From 7a28bb7b4d5fe3cfad5f3371fd92228214cf4fa5 Mon Sep 17 00:00:00 2001 From: Djordje Baljozovic Date: Sat, 31 Jan 2026 20:11:20 +0100 Subject: [PATCH 1/9] v.1.07.5_RC7 --- .../INCHI_API/demos/inchi_main/src/aux2atom.h | 12 +- .../INCHI_API/libinchi/src/inchi_dll_b.c | 6 +- INCHI-1-SRC/INCHI_BASE/src/bcf_s.c | 2 +- INCHI-1-SRC/INCHI_BASE/src/ichi_bns.c | 19 +- INCHI-1-SRC/INCHI_BASE/src/ichi_bns1.c | 12490 ++++++++++++++++ INCHI-1-SRC/INCHI_BASE/src/ichi_io.c | 2 +- INCHI-1-SRC/INCHI_BASE/src/ichicano.c | 2 +- INCHI-1-SRC/INCHI_BASE/src/ichimak2.c | 2 +- INCHI-1-SRC/INCHI_BASE/src/ichimake.c | 8 +- INCHI-1-SRC/INCHI_BASE/src/ichimap2.c | 2 +- INCHI-1-SRC/INCHI_BASE/src/ichimap4.c | 14 +- INCHI-1-SRC/INCHI_BASE/src/ichinorm.c | 7 +- INCHI-1-SRC/INCHI_BASE/src/ichiparm.c | 2 +- INCHI-1-SRC/INCHI_BASE/src/ichiprt1.c | 6 +- INCHI-1-SRC/INCHI_BASE/src/ichiprt2.c | 24 +- INCHI-1-SRC/INCHI_BASE/src/ichiread.c | 30 +- INCHI-1-SRC/INCHI_BASE/src/ichirvr4.c | 6 +- INCHI-1-SRC/INCHI_BASE/src/ichirvr6.c | 2 +- INCHI-1-SRC/INCHI_BASE/src/ichirvr7.c | 6 +- INCHI-1-SRC/INCHI_BASE/src/ichisort.c | 4 +- INCHI-1-SRC/INCHI_BASE/src/ichister.c | 6 +- INCHI-1-SRC/INCHI_BASE/src/ichitaut.c | 2 +- INCHI-1-SRC/INCHI_BASE/src/mol2atom.c | 1 + INCHI-1-SRC/INCHI_BASE/src/mol_fmt1.c | 12 +- INCHI-1-SRC/INCHI_BASE/src/mol_fmt2.c | 2 +- INCHI-1-SRC/INCHI_BASE/src/mol_fmt3.c | 12 +- INCHI-1-SRC/INCHI_BASE/src/mol_fmt4.c | 2 +- INCHI-1-SRC/INCHI_BASE/src/readinch.c | 4 +- INCHI-1-SRC/INCHI_BASE/src/runichi.c | 23 +- INCHI-1-SRC/INCHI_BASE/src/runichi2.c | 6 +- INCHI-1-SRC/INCHI_BASE/src/runichi3.c | 42 +- INCHI-1-SRC/INCHI_BASE/src/runichi4.c | 2 +- INCHI-1-SRC/INCHI_BASE/src/strutil.c | 4 +- 33 files changed, 12642 insertions(+), 122 deletions(-) create mode 100644 INCHI-1-SRC/INCHI_BASE/src/ichi_bns1.c diff --git a/INCHI-1-SRC/INCHI_API/demos/inchi_main/src/aux2atom.h b/INCHI-1-SRC/INCHI_API/demos/inchi_main/src/aux2atom.h index 2534e0d7..da5960d9 100644 --- a/INCHI-1-SRC/INCHI_API/demos/inchi_main/src/aux2atom.h +++ b/INCHI-1-SRC/INCHI_API/demos/inchi_main/src/aux2atom.h @@ -1490,7 +1490,7 @@ int INChITo_Atom( INCHI_IOSTREAM *inp_molfile, MOL_COORD **szCoord, /* cleanup */ if (num_atoms == INCHI_INP_ERROR_RET || num_atoms == INCHI_INP_FATAL_RET) { - if (atom_stereo0D) /* djb-rwth: fixing coverity CID #500395 */ + if (atom_stereo0D) /* djb-rwth: fixing coverity ID #500395 */ { if (stereo0D && *stereo0D == atom_stereo0D) { @@ -1501,13 +1501,13 @@ int INChITo_Atom( INCHI_IOSTREAM *inp_molfile, MOL_COORD **szCoord, } #if ( defined(TARGET_API_LIB) || defined(TARGET_EXE_USING_API) ) - if (atom) /* djb-rwth: fixing coverity CID #499615 */ + if (atom) /* djb-rwth: fixing coverity ID #499615 */ { inchi_free(atom); atom = NULL; } - if (pszCoord) /* djb-rwth: fixing coverity CID #500397 */ + if (pszCoord) /* djb-rwth: fixing coverity ID #500397 */ { inchi_free(pszCoord); pszCoord = NULL; @@ -2730,7 +2730,7 @@ int INChITo_Atom( INCHI_IOSTREAM *inp_molfile, MOL_COORD **szCoord, /* cleanup */ if (num_atoms == INCHI_INP_ERROR_RET || num_atoms == INCHI_INP_FATAL_RET) { - if (atom_stereo0D) /* djb-rwth: fixing coverity CID #500395 */ + if (atom_stereo0D) /* djb-rwth: fixing coverity ID #500395 */ { if (stereo0D && *stereo0D == atom_stereo0D) { @@ -2740,13 +2740,13 @@ int INChITo_Atom( INCHI_IOSTREAM *inp_molfile, MOL_COORD **szCoord, FreeInchi_Stereo0D(&atom_stereo0D); } - if (atom) /* djb-rwth: fixing coverity CID #499615 */ + if (atom) /* djb-rwth: fixing coverity ID #499615 */ { inchi_free(atom); atom = NULL; } - if (pszCoord) /* djb-rwth: fixing coverity CID #500397 */ + if (pszCoord) /* djb-rwth: fixing coverity ID #500397 */ { inchi_free(pszCoord); pszCoord = NULL; diff --git a/INCHI-1-SRC/INCHI_API/libinchi/src/inchi_dll_b.c b/INCHI-1-SRC/INCHI_API/libinchi/src/inchi_dll_b.c index 3a1d2645..9354257a 100644 --- a/INCHI-1-SRC/INCHI_API/libinchi/src/inchi_dll_b.c +++ b/INCHI-1-SRC/INCHI_API/libinchi/src/inchi_dll_b.c @@ -1794,7 +1794,7 @@ int InchiToInchiAtom( INCHI_IOSTREAM *inp_file, /* cleanup */ if (num_atoms == INCHI_INP_ERROR_RET || num_atoms == INCHI_INP_FATAL_RET) { - if (atom_stereo0D) /* djb-rwth: fixing coverity CID #500395 */ + if (atom_stereo0D) /* djb-rwth: fixing coverity ID #500395 */ { if (stereo0D && *stereo0D == atom_stereo0D) { @@ -1804,13 +1804,13 @@ int InchiToInchiAtom( INCHI_IOSTREAM *inp_file, FreeInchi_Stereo0D(&atom_stereo0D); } - if (atom) /* djb-rwth: fixing coverity CID #499615 */ + if (atom) /* djb-rwth: fixing coverity ID #499615 */ { inchi_free(atom); atom = NULL; } - if (pszCoord) /* djb-rwth: fixing coverity CID #500397 */ + if (pszCoord) /* djb-rwth: fixing coverity ID #500397 */ { inchi_free(pszCoord); pszCoord = NULL; diff --git a/INCHI-1-SRC/INCHI_BASE/src/bcf_s.c b/INCHI-1-SRC/INCHI_BASE/src/bcf_s.c index 9c0821bf..d026eac2 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/bcf_s.c +++ b/INCHI-1-SRC/INCHI_BASE/src/bcf_s.c @@ -387,7 +387,7 @@ static int dbl2int_g(double dblinp, int fwidth, int ndecpl, char* str) } } else - { + { /* djb-rwth: addressing coverity ID #499558 -- currently leaving this as it is still a part of GHI #100 */ intpl = (long long int)round(dblinp); ret = sprintf(str, "%*lld", fw_real, intpl); /* djb-rwth: ignoring LLVM warning */ return ret; diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichi_bns.c b/INCHI-1-SRC/INCHI_BASE/src/ichi_bns.c index c620c828..04af6d7a 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichi_bns.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichi_bns.c @@ -47,6 +47,7 @@ Normalization related procedures #include #include +#include #include "mode.h" #include "ichitime.h" @@ -2844,7 +2845,8 @@ void update_some_attype_totals(int nAtTypeTotals[], int mask, int delta, S_CHAR /****************************************************************************/ void update_some_attype_totals(int nAtTypeTotals[], int mask, int delta, S_CHAR at_charge) { - int i, bit; + int i; + int32_t bit; /* djb-rwth: fixing coverity ID #499534 */ if (nAtTypeTotals) { if (mask && !(mask & (ATBIT_Errors))) @@ -2877,7 +2879,8 @@ int GetAtomChargeType( inp_ATOM *atom, inp_ATOM *at = atom + at_no; #if ( FIX_NORM_BUG_ADD_ION_PAIR == 1 ) - int i, neigh, mask, bit, type, num_z, num_m, num_o, delta = bSubtract > 0 ? -1 : 1; /* 0 or -2 => add, 1 or 2 => subtract */ + int i, neigh, mask, type, num_z, num_m, num_o, delta = bSubtract > 0 ? -1 : 1; /* 0 or -2 => add, 1 or 2 => subtract */ + int32_t bit; /* djb-rwth: fixing coverity ID #499579 */ int bNoAdjIon = ( bSubtract == 0 || bSubtract == 1 ); #else int i, neigh, mask, bit, type, num_z, num_m, num_o, delta = bSubtract ? -1 : 1; @@ -4413,6 +4416,7 @@ int HardRemoveAcidicProtons( CANON_GLOBALS *pCG, { /* Remove a proton */ nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; + /* djb-rwth: addressing coverity ID #499503 -- tg_H_Other negative values handled properly */ ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, at, num_atoms, tg_H_Other /*nVertDoubleBond*/, @@ -4615,6 +4619,7 @@ int HardAddAcidicProtons( CANON_GLOBALS *pCG, { /* Add a proton */ nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; + /* djb-rwth: addressing coverity ID #499474 -- cg_Minus_CO negative values handled properly */ ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, at, num_atoms, cg_Minus_Other /*nVertDoubleBond*/, @@ -4877,6 +4882,7 @@ int HardRemoveHplusNP( CANON_GLOBALS *pCG, #if ( FIX_REM_PROTON_COUNT_BUG == 1 ) nPrevRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; #endif + /* djb-rwth: addressing coverity ID #499572 -- tg_H negative values handled properly */ ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, at, num_atoms, tg_H /*nVertDoubleBond*/, cg_Plus /*nVertSingleBond*/, @@ -5211,7 +5217,7 @@ int RemoveNPProtonsAndAcidCharges( CANON_GLOBALS *pCG, goto exit_function; } /*t_group_info->nNumRemovedProtons -= ret;*/ - t_group_info->tni.bNormalizationFlags |= ( ret > 0 ) ? FLAG_PROTON_AC_HARD_ADDED : 0; + t_group_info->tni.bNormalizationFlags |= FLAG_PROTON_AC_HARD_ADDED; /* djb-rwth: fixing coverity ID #499527 */ /* djb-rwth: removing redundant code */ } } @@ -6933,7 +6939,7 @@ int bSetBnsToCheckAltPath( BN_STRUCT *pBNS, if (!bSet_v1) { /* Add st-cap to v1 */ - if (v1t != NO_VERTEX) + if (v1t != NO_VERTEX) /* djb-rwth: addressing coverity ID #499551 -- condition properly written */ { return BNS_BOND_ERR; } @@ -7299,7 +7305,7 @@ int bSetBnsToCheckAltPath( BN_STRUCT *pBNS, if (t1 != NO_VERTEX) { /* Create new edge and vertex, connect to t1 */ - vNew = bAddNewVertex( pBNS, t1, 1/*cap*/, 0/*flow*/, 1/*max_adj_edges*/, nDots ); + vNew = bAddNewVertex( pBNS, t1, 1/*cap*/, 0/*flow*/, 1/*max_adj_edges*/, nDots ); /* djb-rwth: addressing coverity ID #499581 -- condition works as expected for t1 == -2 */ if (IS_BNS_ERROR( vNew )) { return vNew; @@ -7326,7 +7332,7 @@ int bSetBnsToCheckAltPath( BN_STRUCT *pBNS, if (t1 == NO_VERTEX) { /* Add st-cap to v1 */ - n = bAddStCapToAVertex( pBNS, v1, (Vertex) ( t2 == NO_VERTEX ? v2 : t2 ), apc->nOldCapsVert[iapc], nDots, 0 ); + n = bAddStCapToAVertex(pBNS, v1, (Vertex)(t2 == NO_VERTEX ? v2 : t2), apc->nOldCapsVert[iapc], nDots, 0); /* djb-rwth: addressing coverity ID #499501 -- condition works as expected for t2 == -2 */ apc->bSetOldCapsVert[iapc] = n; apc->vOldVert[iapc] = v1; iapc++; @@ -10959,6 +10965,7 @@ int BalancedNetworkSearch( BN_STRUCT* pBNS, BN_DATA *pBD, int bChangeFlow ) /* There is now a valid sv-path via u avoiding b_v (unless v==b_v) => u, v, u', and v' now all become part of the same connected component of M[C] */ + /* djb-rwth: addressing coverity ID #499578 -- negative values of b_u handled properly */ w = MakeBlossom( pBNS, ScanQ, &QSize, Pu, Pv, max_len_Pu_Pv, SwitchEdge, BasePtr, u, v, iuv, b_u, b_v, Tree ); /* this constructed the new blossom and returned its base */ diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichi_bns1.c b/INCHI-1-SRC/INCHI_BASE/src/ichi_bns1.c new file mode 100644 index 00000000..b7244c1f --- /dev/null +++ b/INCHI-1-SRC/INCHI_BASE/src/ichi_bns1.c @@ -0,0 +1,12490 @@ +/* + * International Chemical Identifier (InChI) + * Version 1 + * Software version 1.07 + * April 30, 2024 + * + * MIT License + * + * Copyright (c) 2024 IUPAC and InChI Trust + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +* +* The InChI library and programs are free software developed under the + * auspices of the International Union of Pure and Applied Chemistry (IUPAC). + * Originally developed at NIST. + * Modifications and additions by IUPAC and the InChI Trust. + * Some portions of code were developed/changed by external contributors + * (either contractor or volunteer) which are listed in the file + * 'External-contributors' included in this distribution. + * + * info@inchi-trust.org + * +*/ + + +/* +Balanced Network Search + +Normalization related procedures +*/ + +#include +#include +#include + +#include "mode.h" +#include "ichitime.h" +#include "ichicant.h" +#include "ichierr.h" +#include "ichitaut.h" +#include "ichinorm.h" +#include "util.h" +#include "ichister.h" +#include "ichi_bns.h" + +#include "bcf_s.h" + +#include +#include "logging.h" /*(@nnuk : Nauman Ullah Khan) :: Needed for logging functionality*/ + +#define BNS_MARK_ONLY_BLOCKS 1 /* 1 => find only blocks, do not search for ring systems */ +#define ALLOW_ONLY_SIMPLE_ALT_PATH 0 /* 0 => allow alt. path to contain same bond 2 times (in opposite directions) */ +#define CHECK_TG_ALT_PATH 0 /* 1=> when chacking alt path of a tautomeric atom modify +t-group, not the atom */ +/* 0=> old mode */ + +#define FIX_CPOINT_BOND_CAP 1 /* 1=> fix bug in case of double bond from neutral cpoint */ +#define RESET_EDGE_FORBIDDEN_MASK 1 /* 1: previous; 0: do not apply "edge->forbidden &= pBNS->edge_forbidden_mask" */ +#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) +#define IS_FORBIDDEN(EDGE_FORBIDDEN, PBNS) (EDGE_FORBIDDEN) +#else +#define IS_FORBIDDEN(EDGE_FORBIDDEN, PBNS) (EDGE_FORBIDDEN & PBNS->edge_forbidden_mask) +#endif + + +typedef enum tagAtTypeTotals +{ + /* counts do not include: + charged atom adjacent to another charged atom + atom in an unusual valence state or adjacent to an atom in an unusual valence state + radicals different from singlet + */ + /*ATTOT_NUM_Plus. */ /* number of positive charges, +1, is (ATTOT_NUM_CHARGES + ATTOT_TOT_CHARGE)/2 */ + /*ATTOT_NUM_Minus.*/ /* number of negative charges, -1, is (ATTOT_NUM_CHARGES - ATTOT_TOT_CHARGE)/2 */ + ATTOT_NUM_NP_Plus, /* 0 no H: =N(+)=, #N(+)-, =N(+)<, does not include onium cations >P(+)<, >N(+)< */ + ATTOT_NUM_NP_Proton, /* 1 H(+): -NH3(+), =NH2(+), >NH2(+), =NH(+)-, >NH(+)-, #NH(+), N=N,P */ + ATTOT_NUM_NP_H, /* 2 H: -NH2, =NH, >NH -NH(-) */ + ATTOT_NUM_N_Minus, /* 3 (-): -NH(-), >N(-), =N(-) */ + ATTOT_NUM_NP, /* 4 no H: >N- =N-, #N */ + ATTOT_NUM_ON, /* 5 -N=O: do not allow -N=O => -NH-OH during H(+) add/removal */ + ATTOT_NUM_COH, /* 6 =C-OH, #C-OH; O=O,S,Se,Te */ + ATTOT_NUM_CSH, /* 7 -C-SH, -C-SeH -C-TeH */ + ATTOT_NUM_ZOH, /* 8 =Z-OH, #Z-OH; O=O,S,Se,Te; Z may have charge, Z != C */ + ATTOT_NUM_OOH, /* 9 -O-OH, O=O,S,Se,Te */ + ATTOT_NUM_ZOOH, /* 10 O=Z-OH, O=O,S,Se,Te */ + ATTOT_NUM_NOH, /* 11 =N-OH, -N(-)-OH */ + ATTOT_NUM_N_OH, /* 12 >N-OH, -NH-OH, >NH(+)-OH, -N(-)-OH */ + ATTOT_NUM_CO, /* 13 -C=O, =C=O; O=O,S,Se,Te */ + ATTOT_NUM_ZO, /* 14 -Z=O, =Z=O; O=O,S,Se,Te; Z may have charge */ + ATTOT_NUM_NO, /* 15 -N=O, =N(+)=O */ + ATTOT_NUM_N_O, /* 16 >N(+)=O, =N(+)=O */ + ATTOT_NUM_CO_Minus, /* 17 =C-O(-), #C-O(-); O=O,S,Se,Te */ + ATTOT_NUM_CS_Minus, /* 18 -C-S(-); S = S, Se, Te */ + ATTOT_NUM_ZO_Minus, /* 19 =Z-O(-), #Z-O(-); O = O, S, Se, Te */ + ATTOT_NUM_OO_Minus, /* 20 -O-O(-), O=O,S,Se,Te */ + ATTOT_NUM_ZOO_Minus, /* 21 O=Z-O(-), O=O,S,Se,Te */ + ATTOT_NUM_NO_Minus, /* 22 >N-O(-), -NH-O(-) */ + ATTOT_NUM_N_O_Minus, /* 23 -NH-O(-), >N-O(-); O = O, S, Se, Te */ + ATTOT_NUM_O_Minus, /* 24 -Z-O(-); O=O,S,Se,Te */ + ATTOT_NUM_OH_Plus, /* 25 any OH(+) */ + ATTOT_NUM_O_Plus, /* 26 any O(+) without H */ + ATTOT_NUM_Proton, /* 27 proton */ + ATTOT_NUM_HalAnion, /* 28 Halogen anion */ + ATTOT_NUM_HalAcid, /* 29 Halogen acid */ + ATTOT_NUM_Errors, /* 30 for debugging */ + ATTOT_TOT_CHARGE, /* 31 total of positive and negative single charges, +1 and -1 */ + ATTOT_NUM_CHARGES, /* 32 number of positive and negative single charges, +1 and -1 */ + ATTOT_ARRAY_LEN /* 33 array length */ +} AT_TYPE_TOTALS; + +#define ATBIT_NP_Plus (1 << ATTOT_NUM_NP_Plus) +#define ATBIT_NP_Proton (1 << ATTOT_NUM_NP_Proton) +#define ATBIT_NP_H (1 << ATTOT_NUM_NP_H) +#define ATBIT_N_Minus (1 << ATTOT_NUM_N_Minus) +#define ATBIT_NP (1 << ATTOT_NUM_NP) +#define ATBIT_ON (1 << ATTOT_NUM_ON) +#define ATBIT_COH (1 << ATTOT_NUM_COH) +#define ATBIT_CSH (1 << ATTOT_NUM_CSH) +#define ATBIT_ZOH (1 << ATTOT_NUM_ZOH) +#define ATBIT_OOH (1 << ATTOT_NUM_OOH) +#define ATBIT_ZOOH (1 << ATTOT_NUM_ZOOH) +#define ATBIT_NOH (1 << ATTOT_NUM_NOH) +#define ATBIT_N_OH (1 << ATTOT_NUM_N_OH) +#define ATBIT_CO (1 << ATTOT_NUM_CO) +#define ATBIT_ZO (1 << ATTOT_NUM_ZO) +#define ATBIT_NO (1 << ATTOT_NUM_NO) +#define ATBIT_N_O (1 << ATTOT_NUM_N_O) +#define ATBIT_CO_Minus (1 << ATTOT_NUM_CO_Minus) +#define ATBIT_CS_Minus (1 << ATTOT_NUM_CS_Minus) +#define ATBIT_ZO_Minus (1 << ATTOT_NUM_ZO_Minus) +#define ATBIT_OO_Minus (1 << ATTOT_NUM_OO_Minus) +#define ATBIT_ZOO_Minus (1 << ATTOT_NUM_ZOO_Minus) +#define ATBIT_NO_Minus (1 << ATTOT_NUM_NO_Minus) +#define ATBIT_N_O_Minus (1 << ATTOT_NUM_N_O_Minus) +#define ATBIT_O_Minus (1 << ATTOT_NUM_O_Minus) +#define ATBIT_OH_Plus (1 << ATTOT_NUM_OH_Plus) +#define ATBIT_O_Plus (1 << ATTOT_NUM_O_Plus) +#define ATBIT_Proton (1 << ATTOT_NUM_Proton) +#define ATBIT_HalAnion (1 << ATTOT_NUM_HalAnion) +#define ATBIT_HalAcid (1 << ATTOT_NUM_HalAcid) + + +#define ATBIT_Errors (1 << ATTOT_NUM_Errors) + +typedef struct tagProtonRemovalMaskAndType +{ + int typePos; /* atoms accessible to positive charges */ + int maskPos; + int typeNeg; /* atoms accessible to negative charges */ + int maskNeg; + int typeH; /* atoms accessible to hydrogen atoms */ + int maskH; +} PRMAT; + +#define PR_SIMPLE_MSK (ATBIT_NP_Proton | ATBIT_OH_Plus) +#define PR_SIMPLE_TYP (ATT_ATOM_N | ATT_ATOM_P | ATT_O_PLUS) + +#define ATBIT_MSK_NP (ATBIT_NP_Plus | ATBIT_NP_Proton | ATBIT_NP_H | ATBIT_N_Minus | ATBIT_NP) +#define KNOWN_ACIDIC_TYPE (ATT_ACIDIC_CO | ATT_ACIDIC_S | ATT_OO | ATT_ZOO | ATT_NO) +#define ATBIT_MSK_OS (ATBIT_COH | ATBIT_CSH | ATBIT_ZOH | ATBIT_OOH | ATBIT_ZOOH | ATBIT_NOH | ATBIT_N_OH |\ + ATBIT_CO | ATBIT_ZO | ATBIT_NO | ATBIT_N_O |\ + ATBIT_CO_Minus | ATBIT_CS_Minus | ATBIT_ZO_Minus | ATBIT_OO_Minus |\ + ATBIT_ZOO_Minus | ATBIT_NO_Minus | ATBIT_N_O_Minus /*| ATBIT_O_Minus*/ ) +#define ATBIT_MSK_H (ATBIT_NP_Proton | ATBIT_NP_H | ATBIT_COH | ATBIT_CSH | ATBIT_ZOH | ATBIT_OOH |\ + ATBIT_ZOOH | ATBIT_NOH | ATBIT_N_OH) + +#define ATTYP_OS (ATT_ACIDIC_CO | ATT_ACIDIC_S | ATT_OO | ATT_ZOO | ATT_NO /*| ATT_OTHER_NEG_O*/ | ATT_OTHER_ZO) +#define ATTYP_NP (ATT_ATOM_N | ATT_ATOM_P) +#define ATTYP_N (ATT_ATOM_N) +#define ATTYP_P (ATT_ATOM_P) + +/************* simple proton removal from acids **************************/ +#define AR_ANY_OH 0 /* 1 => create unknown to be acidic anions */ +#define AR_SIMPLE_STEPS 3 +/* acidic groups for proton removal, step 1 */ +#define AR_SIMPLE_MSK1 (ATBIT_COH | ATBIT_CSH | ATBIT_OOH | ATBIT_ZOOH | ATBIT_NOH | ATBIT_HalAcid) +#define AR_SIMPLE_TYP1 (ATT_ACIDIC_CO | ATT_ACIDIC_S | ATT_OO | ATT_ZOO | ATT_NO | ATT_HalAcid) +/* acidic groups for proton removal, step 2 */ +#define AR_SIMPLE_MSK2 (AR_ANY_OH? (ATBIT_N_OH) :0) +#define AR_SIMPLE_TYP2 (AR_ANY_OH? (ATT_N_O) :0) +/* acidic groups for proton removal, step 3 */ +#define AR_SIMPLE_MSK3 (AR_ANY_OH? (ATBIT_ZOH) :0) +#define AR_SIMPLE_TYP3 (AR_ANY_OH? (ATT_OTHER_ZO):0) + +/************* simple proton addition to acids **************************/ +#define AA_ANY_O_Minus 0 /* 1 => neutralize unknown to be acidic anions */ +#define AA_SIMPLE_STEPS 3 +/* acidic groups for proton addition, step 1 */ +#define AA_SIMPLE_MSK1 (ATBIT_CO_Minus | ATBIT_CS_Minus | ATBIT_OO_Minus | ATBIT_ZOO_Minus | ATBIT_NO_Minus | ATBIT_O_Minus | ATBIT_HalAnion) +#define AA_SIMPLE_TYP1 (ATT_ACIDIC_CO | ATT_ACIDIC_S | ATT_OO | ATT_ZOO | ATT_NO | ATT_OH_MINUS | ATT_HalAnion ) +/* acidic groups for proton addition, step 2 */ +#define AA_SIMPLE_MSK2 (AA_ANY_O_Minus? (ATBIT_N_O_Minus) :0) +#define AA_SIMPLE_TYP2 (AA_ANY_O_Minus? (ATT_N_O) :0) +/* acidic groups for proton addition, step 3 */ +#define AA_SIMPLE_MSK3 (AA_ANY_O_Minus? (ATBIT_ZO_Minus | ATBIT_O_Minus):0) +#define AA_SIMPLE_TYP3 (AA_ANY_O_Minus? (ATT_OTHER_ZO) :0) + +#if ( FIX_NP_MINUS_BUG == 1 ) +/* allow to add H(+) to =N(-) which previously was #N */ +#undef AA_SIMPLE_STEPS +#define AA_SIMPLE_STEPS 4 +#define AA_SIMPLE_MSK4 ATBIT_N_Minus +#define AA_SIMPLE_TYP4 ATT_NP_MINUS_V23 +#endif + +/************* hard proton removal from NP **************************/ +/* (+) charge group for proton removal: mask & type */ +#define PR_HARD_MSK_POS ATBIT_MSK_NP +#define PR_HARD_TYP_POS ATTYP_N +#define PR_HARD_TYP_POSP ATTYP_P +/* (-) charge group for proton removal */ +#define PR_HARD_MSK_NEG (ATBIT_MSK_NP | ATBIT_MSK_OS) +#define PR_HARD_TYP_NEG (ATTYP_N | ATTYP_OS) +/* H-group for proton removal */ +#define PR_HARD_MSK_H (ATBIT_MSK_NP | ATBIT_MSK_OS) +#define PR_HARD_TYP_H (ATTYP_N | ATTYP_OS) + +/************* hard proton removal from acids **************************/ +/* (+) charge group for proton removal: mask & type */ +#define AR_HARD_MSK_POS ATBIT_MSK_NP +#define AR_HARD_TYP_POS ATTYP_N +/* (-) charge group for proton removal */ +#define AR_HARD_MSK_NEG (ATBIT_MSK_NP | ATBIT_MSK_OS) +#define AR_HARD_TYP_NEG (ATTYP_N | ATTYP_OS) +/* H-group acid for proton removal */ +#define AR_HARD_MSK_HA (ATBIT_CO | ATBIT_NO ) +#define AR_HARD_TYP_HA (ATT_ACIDIC_CO | ATT_NO) +/* H-group non-acid for proton removal */ +#define AR_HARD_MSK_HN ((ATBIT_MSK_NP | ATBIT_MSK_OS) & ~AR_HARD_MSK_HA) +#define AR_HARD_TYP_HN ((ATTYP_N | ATTYP_OS) /*& ~AR_HARD_TYP_HA*/) + +/************* hard proton addition to acids **************************/ +/* (+) charge group for proton removal: mask & type */ +#define AA_HARD_MSK_POS ATBIT_MSK_NP +#define AA_HARD_TYP_POS ATTYP_N +/* (-) charge group for negative charge removal */ +#define AA_HARD_MSK_NEG ((ATBIT_MSK_NP | ATBIT_MSK_OS) & ~(ATBIT_CO | ATBIT_NO )) +#define AA_HARD_TYP_NEG (ATTYP_N | ATTYP_OS) +/* (-) charge group to accept negative charges */ +#define AA_HARD_MSK_CO (ATBIT_CO | ATBIT_NO ) +#define AA_HARD_TYP_CO (ATT_ACIDIC_CO | ATT_NO) +/* H-group non-acid for proton removal */ +#define AA_HARD_MSK_H (ATBIT_MSK_NP | ATBIT_MSK_OS) +#define AA_HARD_TYP_H (ATTYP_N | ATTYP_OS) + + +/*****************************************************************************/ +#define BNS_MAX_NUM_FLOW_CHANGES (1+2*MAX_BOND_EDGE_CAP) + +/* -- opiginal Pascal values -- +#define NO_VERTEX 0 +#define BLOSSOM_BASE -1 +#define FIRST_INDX 1 +*/ + +#define TREE_NOT_IN_M 0 /* not in T or T' */ +#define TREE_IN_2 1 /* in T' and not s-reachable */ +#define TREE_IN_2BLOSS 2 /* in T' and in a blossom, is s-reachable */ +#define TREE_IN_1 3 /* in T and is s-reachable */ + +#define TREE_IS_S_REACHABLE(X) (Tree[X] >= TREE_IN_2BLOSS) +#define TREE_IS_ON_SCANQ TREE_IS_S_REACHABLE +/* #define TREE_IS_ON_SCANQ(X) (Tree[X] != TREE_NOT_IN_M) */ +#define TREE_MARK(X, MARK) do{ if( Tree[X] < MARK ) Tree[X]=MARK; }while(0) + + +/***************************************************************************** +* store changes done to check whether an alternating path exists +* (see bSetBnsToCheckAltPath, bRestoreBnsAfterCheckAltPath) +******************************************************************************/ +typedef struct tagAltPathChanges +{ + /* caps changed in up to 2 vertices */ + VertexFlow nOldCapsVert[2][MAXVAL + 1]; + Vertex vOldVert[2]; + S_CHAR bSetOldCapsVert[2]; /* number of caps to restore, including st-cap */ + /* save ids of the newly created temporary vertices */ + Vertex vNewVertex[2]; + S_CHAR bSetNew[2]; /* indicators whether to remove vertices */ +} ALT_PATH_CHANGES; + + + +/*****************************************************************************/ + + +/* Local functions */ + +int RestoreRadicalsOnly( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at ); +int bRadChangesAtomType( BN_STRUCT *pBNS, BN_DATA *pBD, Vertex v, Vertex v_1, Vertex v_2 ); +int BnsAdjustFlowBondsRad( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at, int num_atoms ); +int SetAtomRadAndChemValFromVertexCapFlow( BN_STRUCT *pBNS, inp_ATOM *atom, int v1 ); +int bNeedToTestTheFlow( int bond_type, int nTestFlow, int bTestForNonStereoBond ); +int RestoreEdgeFlow( BNS_EDGE *edge, int delta, int bChangeFlow ); +int SetAtomBondType( BNS_EDGE *edge, U_CHAR *bond_type12, U_CHAR *bond_type21, int delta, int bChangeFlow ); +int RestoreBnStructFlow( BN_STRUCT *pBNS, int bChangeFlow ); +int CompTGroupNumber( const void *tg1, const void *tg2, void *p ); +int CompCGroupNumber( const void *cg1, const void *cg2, void *p ); + +/* Rings, Blocks, Non-stereo bonds */ +int ReInitBnStructForAltBns( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, int bUnknAltAsNoStereo ); +int MarkRingSystemsAltBns( BN_STRUCT* pBNS, int bUnknAltAsNoStereo ); +int MarkNonStereoAltBns( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, int bUnknAltAsNoStereo ); + +/* Called from BalancedNetworkSearch */ +int GetVertexDegree( BN_STRUCT* pBNS, Vertex v ); +/* Vertex Get2ndNeighbor1( BN_STRUCT* pBNS, Vertex u, EdgeIndex iedge ); not used */ +Vertex Get2ndEdgeVertex( BN_STRUCT* pBNS, Edge uv ); +Vertex GetVertexNeighbor( BN_STRUCT* pBNS, Vertex v, int neigh, EdgeIndex *iedge ); +int GetEdgePointer( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv, BNS_EDGE **uv, S_CHAR *s_or_t ); +int AugmentEdge( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv, int delta, S_CHAR bReverse, int bChangeFlow ); +int rescap_mark( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv ); +int rescap( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv ); +Vertex FindBase( Vertex u, Vertex *BasePtr ); +int FindPathToVertex_s( Vertex x, Edge *SwitchEdge, Vertex *BasePtr, Vertex *Path, int MaxPathLen ); +Vertex MakeBlossom( BN_STRUCT* pBNS, Vertex *ScanQ, int *pQSize, + Vertex *Pu, Vertex *Pv, int max_len_Pu_Pv, + Edge *SwitchEdge, Vertex *BasePtr, + Vertex u, Vertex v, EdgeIndex iuv, Vertex b_u, Vertex b_v, S_CHAR *Tree ); +int PullFlow( BN_STRUCT *pBNS, Edge *SwitchEdge, Vertex x, Vertex y, int delta, S_CHAR bReverse, int bChangeFlow ); +int FindPathCap( BN_STRUCT* pBNS, Edge *SwitchEdge, Vertex x, Vertex y, int delta ); + +/* +int SetBondType( BNS_EDGE *edge, U_CHAR *bond_type12, U_CHAR *bond_type21, int delta, int bChangeFlow ); +int SetBondsRestoreBnStructFlow( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, int bChangeFlow ); +*/ +int SetBondsFromBnStructFlow( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, int bChangeFlow0 ); +int MarkAtomsAtTautGroups( BN_STRUCT *pBNS, int num_atoms, BN_AATG *pAATG, int nEnd1, int nEnd2 ); + +int nMinFlow2Check( BN_STRUCT *pBNS, int iedge ); +int nMaxFlow2Check( BN_STRUCT *pBNS, int iedge ); +int nCurFlow2Check( BN_STRUCT *pBNS, int iedge ); + +/* Bonds testing */ +/* +int bRestoreFlowToCheckOneBond( BN_STRUCT *pBNS, BNS_FLOW_CHANGES *fcd, int nTestFlow, inp_ATOM *at, int num_atoms, int bChangeFlow ); +*/ +int bSetFlowToCheckOneBond( BN_STRUCT *pBNS, int iedge, int flow, BNS_FLOW_CHANGES *fcd ); +int bRestoreFlowAfterCheckOneBond( BN_STRUCT *pBNS, BNS_FLOW_CHANGES *fcd ); +int bSetBondsAfterCheckOneBond( BN_STRUCT *pBNS, BNS_FLOW_CHANGES *fcd, int nTestFlow, inp_ATOM *at, int num_atoms, int bChangeFlow ); +int BnsTestAndMarkAltBonds( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at, int num_atoms, BNS_FLOW_CHANGES *fcd, int bChangeFlow, int nBondTypeToTest ); +/* +int bIsAltBond(int bond_type); -- djb-rwth: function definition not found +*/ + +/* Fix bonds */ +int fix_special_bonds( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, int edge_forbidden_mask ); +int TempFix_NH_NH_Bonds( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms ); +int CorrectFixing_NH_NH_Bonds( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms ); +int fix_explicitly_indicated_bonds( int nebend, int *ebend, BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms ); + +/* Alt path testing */ +int bSetBnsToCheckAltPath( BN_STRUCT *pBNS, int nVertDoubleBond, int nVertSingleBond, AT_NUMB type, + int path_type, ALT_PATH_CHANGES *apc, BNS_FLOW_CHANGES *fcd, int *nDots ); +int bRestoreBnsAfterCheckAltPath( BN_STRUCT *pBNS, ALT_PATH_CHANGES *apc, int bChangeFlow ); +Vertex GetGroupVertex( BN_STRUCT *pBNS, Vertex v1, AT_NUMB type ); +BNS_IEDGE GetEdgeToGroupVertex( BN_STRUCT *pBNS, Vertex v1, AT_NUMB type ); +int bAddNewVertex( BN_STRUCT *pBNS, int nVertDoubleBond, int nCap, int nFlow, int nMaxAdjEdges, int *nDots ); +int AddNewEdge( BNS_VERTEX *p1, BNS_VERTEX *p2, BN_STRUCT *pBNS, int nEdgeCap, int nEdgeFlow ); +int bAddStCapToAVertex( BN_STRUCT *pBNS, Vertex v1, Vertex v2, VertexFlow *nOldCapVertSingleBond, int *nDots, int bAdjacentDonors ); + +static void remove_alt_bond_marks( inp_ATOM *at, int num_atoms ); +int bIsBnsEndpoint( BN_STRUCT *pBNS, int v ); + +/* Protons removal, charge neutralization */ +/* int is_acidic_CO(inp_ATOM* atom, int at_no); */ /* djb-rwth: function definition not found*/ +int mark_at_type( inp_ATOM *atom, int num_atoms, int nAtTypeTotals[] ); +int GetAtomChargeType( inp_ATOM *atom, int at_no, int nAtTypeTotals[], int *pMask, int bSubtract ); +int AddChangedAtHChargeBNS( inp_ATOM *at, int num_atoms, int nAtTypeTotals[], S_CHAR *mark ); +int EliminatePlusMinusChargeAmbiguity( BN_STRUCT *pBNS, int num_atoms ); +int AddOrRemoveExplOrImplH( int nDelta, inp_ATOM *at, int num_atoms, AT_NUMB at_no, T_GROUP_INFO *t_group_info ); +int SubtractOrChangeAtHChargeBNS( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, + int nAtTypeTotals[], S_CHAR *mark, T_GROUP_INFO *t_group_info, int bSubtract ); +int is_Z_atom( U_CHAR el_number ); +int IsZOX( inp_ATOM *atom, int at_x, int ord ); +int SimpleRemoveHplusNPO( inp_ATOM *at, int num_atoms, int nAtTypeTotals[], T_GROUP_INFO *t_group_info ); +int CreateCGroupInBnStruct( inp_ATOM *at, int num_atoms, + BN_STRUCT *pBNS, int nType, int nMask, int nCharge ); +int CreateTGroupInBnStruct( inp_ATOM *at, int num_atoms, + BN_STRUCT *pBNS, int nType, int nMask ); +int RemoveLastGroupFromBnStruct( inp_ATOM *at, int num_atoms, int tg, BN_STRUCT *pBNS ); +int SetInitCapFlowToCurrent( BN_STRUCT *pBNS ); +int SimpleRemoveAcidicProtons( inp_ATOM *at, int num_atoms, BN_AATG *pAATG, int num2remove ); +int SimpleAddAcidicProtons( inp_ATOM *at, int num_atoms, BN_AATG *pAATG, int num2add ); +int HardRemoveAcidicProtons( struct tagCANON_GLOBALS *pCG, inp_ATOM *at, int num_atoms, BN_AATG *pAATG, int num2remove, + int *nNumCanceledCharges, BN_STRUCT *pBNS, BN_DATA *pBD ); +int HardAddAcidicProtons( struct tagCANON_GLOBALS *pCG, inp_ATOM *at, int num_atoms, BN_AATG *pAATG, int num2add, + int *nNumCanceledCharges, BN_STRUCT *pBNS, BN_DATA *pBD ); +int HardRemoveHplusNP( struct tagCANON_GLOBALS *pCG, inp_ATOM *at, int num_atoms, int bCancelChargesAlways, int *nNumCanceledCharges, + BN_AATG *pAATG, BN_STRUCT *pBNS, BN_DATA *pBD ); +int RemoveNPProtonsAndAcidCharges( struct tagCANON_GLOBALS *pCG, inp_ATOM *at, int num_atoms, BN_AATG *pAATG, BN_STRUCT *pBNS, BN_DATA *pBD ); +Vertex GetPrevVertex( BN_STRUCT* pBNS, Vertex y, Edge *SwitchEdge, EdgeIndex *iuv ); +int bIgnoreVertexNonTACN_atom( BN_STRUCT* pBNS, Vertex u, Vertex v ); +int bIgnoreVertexNonTACN_group( BN_STRUCT* pBNS, Vertex v, Vertex w, Edge *SwitchEdge ); +int bIsRemovedHfromNHaion( BN_STRUCT* pBNS, Vertex u, Vertex v ); +int bIsAggressiveDeprotonation( BN_STRUCT* pBNS, Vertex v, Vertex w, Edge *SwitchEdge ); + +int bIsAtomTypeHard( inp_ATOM *at, int endpoint, int nType, int nMask, int nCharge ); +int bIsHDonorAccAtomType( inp_ATOM *at, int endpoint, int *cSubType ); +int bIsNegAtomType( inp_ATOM *at, int i, int *cSubType ); + +#if ( BNS_RAD_SEARCH == 1 ) +int RegisterRadEndpoint( BN_STRUCT *pBNS, BN_DATA *pBD, Vertex u ); +int cmp_rad_endpoints( const void *a1, const void *a2 ); +int cmp_endpoints_rad( const void *a1, const void *a2 ); +#endif + +int bHasChargedNeighbor( inp_ATOM *at, int iat ); +/*****************************************************************************/ +/**** prim(v) is v' *****/ +#define prim(v) (Vertex)((v)^1) + +/*****************************************************************************/ +#define SwitchEdge_Vert1(u) SwitchEdge[u][0] +#define SwitchEdge_Vert2(u) Get2ndEdgeVertex( pBNS, SwitchEdge[u] ) +#define SwitchEdge_IEdge(u) SwitchEdge[u][1] +/*****************************************************************************/ + + + + + +/**************************************************************************** +Returns value > 0 if a bond has been changed +****************************************************************************/ +int RestoreEdgeFlow( BNS_EDGE *edge, int delta, int bChangeFlow ) +{ + /*flow1 = edge->flow;*/ /* output from BNS */ + switch (bChangeFlow & BNS_EF_CHNG_RSTR) + { + case 0: + /* the flow has not been permitted to change inside the BNS */ + /* nothing to do */ + /*flow1 = edge->flow;*/ /* output from BNS, the original flow value */ + /*flow2 = flow1 + delta;*/ /* the flow would be changed to this value by the BNS if permitted */ + break; + case BNS_EF_CHNG_FLOW: + /* the flow has been changed by the BNS; update flow0 */ + /*flow2 = edge->flow;*/ /* output from BNS, the changed value */ + /*flow1 = flow2 - delta;*/ /* the original flow value before the BNS */ + edge->flow0 = edge->flow; /* SAVE NEW EDGE FLOW AS THE INITIAL FLOW FROM CHEM. BONDS */ + break; + case BNS_EF_CHNG_RSTR: + /* the flow has been changed by the BNS; requested to change it back */ + /*flow2 = edge->flow;*/ /* output from BNS, the changed value */ + /*flow1 = flow2 - delta;*/ /* the original flow value before the BNS */ + edge->flow = edge->flow - delta; /* CHANGE EDGE FLOW BACK (RESTORE) */ + break; + case BNS_EF_RSTR_FLOW: + /* the flow has not been permitted to change inside the BNS */ + /* nothing to do */ + /*flow1 = edge->flow;*/ /* output from BNS, the original flow value */ + /*flow2 = flow1 + delta;*/ /* the flow would be changed to this value by the BNS if permitted */ + break; + } + + return 0; +} + + +/**************************************************************************** +Returns value > 0 if a bond has been changed; do not change flow +****************************************************************************/ +int SetAtomBondType( BNS_EDGE *edge, + U_CHAR *bond_type12, + U_CHAR *bond_type21, + int delta, + int bChangeFlow ) +{ + int flow1, flow2, tmp, ret = 0; + int bond_mark = 0, bond_type, new_bond_type; /* djb-rwth: addressing LLVM warning */ + + if (!edge->pass || !bond_type21) + { + return 0; + } + + switch (bChangeFlow & BNS_EF_CHNG_RSTR) + { + case 0: /* the flow has not been permitted to change inside the BNS: simulated in case of check one bond */ + case BNS_EF_RSTR_FLOW: /* the flow has not been permitted to change inside the BNS: obsolete mode, unexpected bChangeFlow */ + flow1 = edge->flow0; /* output from BNS, the original (old) flow value */ + flow2 = flow1 + delta; /* the flow would be changed to this value by the BNS if permitted */ + break; + case BNS_EF_CHNG_FLOW: /* the flow has been changed by the BNS */ + case BNS_EF_CHNG_RSTR: /* the flow has been changed by the BNS; requested to change it back */ + flow2 = edge->flow; /* output from BNS, the changed (new) value */ + flow1 = edge->flow0; /* the original flow (old) value before the BNS */ + break; + default: + return 0; /* added 2006-03-21 */ + } + + if (( bChangeFlow & BNS_EF_CHNG_BONDS ) && ( bChangeFlow & BNS_EF_ALTR_NS ) != BNS_EF_ALTR_NS) + { + /* Set new bond types according to the new flow values */ + new_bond_type = flow2 + BOND_SINGLE; + if (*bond_type12 != new_bond_type) + { + *bond_type12 = *bond_type21 = new_bond_type; + ret++; + } + } + else + { + if (bChangeFlow & BNS_EF_ALTR_BONDS) + { + if (flow1 == flow2) + { + goto exit_function; + } + /* Update alternating bond information */ + if (flow1 > flow2) + { + /* Make sure flow2 > flow1 */ + tmp = flow1; + flow1 = flow2; + flow2 = tmp; + } + /* djb-rwth: removing redundant code */ + switch (bond_type = ( *bond_type12 & BOND_TYPE_MASK )) + { + case BOND_SINGLE: + case BOND_DOUBLE: + case BOND_TRIPLE: + /* assume that the input bond type fits either flow1 or flow2 */ + if (flow1 == 0 && flow2 == 1) + { + if (bChangeFlow & BNS_EF_SET_NOSTEREO) + { + bond_mark = BOND_MARK_ALT12NS; + bond_type = BOND_ALT12NS; + } + else + { + bond_mark = BOND_MARK_ALT12; + bond_type = BOND_ALTERN; + } + } + else + { + if (flow1 == 0 && flow2 == 2) + { + bond_mark = BOND_MARK_ALT13; + bond_type = BOND_ALT_13; + } + else + { + if (flow1 == 1 && flow2 == 2) + { + bond_mark = BOND_MARK_ALT23; + bond_type = BOND_ALT_23; + } + else + { + return BNS_BOND_ERR; /* error */ + } + } + } + break; + case BOND_TAUTOM: + if (flow1 == 0 && flow2 == 1) + { + bond_mark = BOND_MARK_ALT12NS; + } + else + if (flow1 == 1 && flow2 == 2) { + bond_mark = BOND_MARK_ALT23; + } + else { + return BNS_BOND_ERR; /* error */ + } + break; + default: + new_bond_type = bond_type; + bond_mark = ( *bond_type12 & BOND_MARK_MASK ); + switch (bond_mark) + { + case BOND_MARK_ALT12: + if (( bChangeFlow & BNS_EF_SET_NOSTEREO ) && flow1 == 0 && flow2 == 1) + { + bond_mark = BOND_MARK_ALT12NS; + new_bond_type = BOND_ALT12NS; + break; + } + case BOND_MARK_ALT12NS: + if (flow1 == 2 || flow2 == 2) + { + bond_mark = BOND_MARK_ALT123; + new_bond_type = BOND_ALT_123; + } + break; + case BOND_MARK_ALT13: + if (flow1 == 1 || flow2 == 1) + { + bond_mark = BOND_MARK_ALT123; + new_bond_type = BOND_ALT_123; + } + break; + case BOND_MARK_ALT23: + if (flow1 == 0 || flow2 == 0) + { + bond_mark = BOND_MARK_ALT123; + new_bond_type = BOND_ALT_123; + } + break; + case BOND_MARK_ALT123: + break; + + case 0: /* special case: second alt bond testing */ + if (flow1 == 0 && flow2 == 1) + { + bond_mark = BOND_MARK_ALT12; + } + else + { + if (flow1 == 0 && flow2 == 2) + { + bond_mark = BOND_MARK_ALT13; + } + else + { + if (flow1 == 1 && flow2 == 2) + { + bond_mark = BOND_MARK_ALT23; + } + else + { + return BNS_BOND_ERR; /* error */ + } + } + } + break; + + default: + return BNS_BOND_ERR; /* error */ + } + + switch (bond_type) + { + case BOND_TAUTOM: + break; + case BOND_ALTERN: + case BOND_ALT12NS: + case BOND_ALT_123: + case BOND_ALT_13: + case BOND_ALT_23: + bond_type = new_bond_type; + break; + default: + return BNS_BOND_ERR; /* error */ + } + } + + new_bond_type = bond_type | bond_mark; + if (new_bond_type != *bond_type12) + { + *bond_type12 = *bond_type21 = new_bond_type; + ret++; + } + } + } + +exit_function: + + return ret; +} + + +/**************************************************************************** +Run BalancedNetworkSearch( ... ) until no aug pass is found +****************************************************************************/ +int RunBalancedNetworkSearch( BN_STRUCT *pBNS, BN_DATA *pBD, int bChangeFlow ) +{ + int pass, delta = 0, nSumDelta; + + nSumDelta = 0; + for (pass = 0; pass < pBNS->max_altp; pass++) + { + pBNS->alt_path = pBNS->altp[pass]; + pBNS->bChangeFlow = 0; + delta = BalancedNetworkSearch( pBNS, pBD, bChangeFlow ); + ReInitBnData( pBD ); + if (0 < delta) + { + pBNS->num_altp++; + nSumDelta += abs( delta ); + } + else + { + break; + } + } + + if (IS_BNS_ERROR( delta )) + { + return delta; + } + + if (bInchiTimeIsOver( pBNS->ic, pBNS->ulTimeOutTime )) + { + return BNS_TIMEOUT; + } + + return nSumDelta; /* number of eliminated pairs of "dots" */ +} + + +/****************************************************************************/ +int SetAtomRadAndChemValFromVertexCapFlow( BN_STRUCT *pBNS, + inp_ATOM *atom, + int v1 ) +{ + BNS_VERTEX *vert = pBNS->vert + v1; + inp_ATOM *at = atom + v1; + S_CHAR cValue; + int nChanges = 0; + + /* Set only on the 1st pass */ + if (!vert->st_edge.pass) + { + return 0; + } + + /* Adjust chem_bonds_valence */ + cValue = at->chem_bonds_valence - at->valence; + if (cValue >= 0 && cValue != vert->st_edge.flow) + { + at->chem_bonds_valence = at->valence + vert->st_edge.flow; + nChanges++; + } + + /* Adjist radical */ + switch (vert->st_edge.cap - vert->st_edge.flow) + { + case 0: + cValue = 0; + break; + case 1: + cValue = RADICAL_DOUBLET; + break; + case 2: + cValue = RADICAL_TRIPLET; + break; + default: + return BNS_BOND_ERR; + } + if (cValue != at->radical) + { + at->radical = cValue; + nChanges++; + } + + return nChanges; +} + + +/****************************************************************************/ +int AddChangedAtHChargeBNS( inp_ATOM *at, + int num_atoms, + int nAtTypeTotals[], + S_CHAR *mark ) +{ + int i, mask, num; + for (i = 0, num = 0; i < num_atoms; i++) + { + if (mark[i]) + { + mark[i] = 0; +#if ( FIX_NORM_BUG_ADD_ION_PAIR == 1 ) + /* add ignoring adjacent charges */ + at[i].at_type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, -2 ); +#else + at[i].at_type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); +#endif + num++; + } + } + + return num; +} + + +/**************************************************************************** +Eliminate neutral representation ambiguity: + +replace (+)--N==(-) with (+)==N--(-) + +here (+) is positive charge group, +(-) is negative charge group, N is N or P +This reduces possibility of creating ion pair -OH => -O(+) + H(+) +instead of removing H(+) from N or P + +!Call this function after alt path was found and new flows have been set. +****************************************************************************/ +int EliminatePlusMinusChargeAmbiguity( BN_STRUCT *pBNS, int num_atoms ) +{ + int pass, i, v0, v1, v2, ineigh1, /*ineigh0,*/ /*ineigh2,*/ + vLast, n, delta, ret, err = 0; + int nFound, k; + BNS_EDGE *edge; + + for (pass = pBNS->num_altp - 1, ret = 0; 0 <= pass; pass--) + { + + pBNS->alt_path = pBNS->altp[pass]; + v1 = ALTP_START_ATOM( pBNS->alt_path ); + n = ALTP_PATH_LEN( pBNS->alt_path ); + delta = ALTP_DELTA( pBNS->alt_path ); + vLast = ALTP_END_ATOM( pBNS->alt_path ); + v0 = v2 = NO_VERTEX; /* negative number */ + + for (i = 0; i < n; i++, delta = -delta, v0 = v1, v1 = v2 /*, ineigh0 = ineigh1*/) + { + ineigh1 = ALTP_THIS_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v1->v2 neighbor */ + /*ineigh2 = ALTP_NEXT_ATOM_NEIGHBOR(pBNS->alt_path, i);*/ /* v2->v1 neighbor */ + edge = pBNS->edge + pBNS->vert[v1].iedge[ineigh1]; + /* follow the BN Structure, not the inp_ATOM, to take care of swithching to + t-groups, c-groups or other fictitious edges/vertices + */ + v2 = edge->neighbor12 ^ v1; + if (v1 < num_atoms && + ( (v0 >= num_atoms && ( pBNS->vert[v0].type & BNS_VERT_TYPE_C_GROUP )) || + (v2 >= num_atoms && ( pBNS->vert[v2].type & BNS_VERT_TYPE_C_GROUP ) ))) /* djb-rwth: addressing LLVM warning */ + { + int cgPos = 0, cgNeg = 0; + int neighPos = -1, neighNeg = -1; + BNS_EDGE *edgePos, *edgeNeg; + nFound = 0; + for (k = pBNS->vert[v1].num_adj_edges - 1; k >= 0 && ( neighPos < 0 || neighNeg < 0 ); k--) + { + BNS_EDGE *next_edge = pBNS->edge + pBNS->vert[v1].iedge[k]; + int v = next_edge->neighbor12 ^ v1; + if (pBNS->vert[v].type & BNS_VERT_TYPE_C_GROUP) + { + if (pBNS->vert[v].type & BNS_VERT_TYPE_C_NEGATIVE) + { + cgNeg = v; + neighNeg = k; + nFound++; + } + else + { + cgPos = v; + neighPos = k; + nFound++; + } + } + } + if (2 == nFound && neighPos >= 0 && neighNeg >= 0) + { + /* both c-groups have been found */ + edgePos = pBNS->edge + pBNS->vert[v1].iedge[neighPos]; + edgeNeg = pBNS->edge + pBNS->vert[v1].iedge[neighNeg]; + if (edgePos->flow < edgeNeg->flow) + { + /* ambiguity found; replace (+cg)--N==(-cg) with (+cg)==N--(-cg) */ + int dflow = edgeNeg->flow - edgePos->flow; + + edgePos->flow += dflow; + pBNS->vert[cgPos].st_edge.cap += dflow; + pBNS->vert[cgPos].st_edge.flow += dflow; + + edgeNeg->flow -= dflow; + pBNS->vert[cgNeg].st_edge.cap -= dflow; + pBNS->vert[cgNeg].st_edge.flow -= dflow; + ret++; + } + } + } + } + + if (v2 != vLast) + { + err = BNS_PROGRAM_ERR; + } + } + + return err ? err : ret; +} + + +/**************************************************************************** +Add or remove ixplicit or implicit hydrogens +****************************************************************************/ +int AddOrRemoveExplOrImplH( int nDelta, + inp_ATOM *at, + int num_atoms, + AT_NUMB at_no, + T_GROUP_INFO *t_group_info ) +{ + int i, iso, tot_num_iso_H, + num_H, /* number of H before the removal, including explicit H */ + nNum2Remove, /* number of H to remove */ + nNumRemovedExplicitH; /* djb-rwth: removing redundant variables */ + S_CHAR num_iso_H[NUM_H_ISOTOPES]; + inp_ATOM *at_H; + + if (!nDelta) + { + return 0; + } + /* add */ + if (nDelta > 0) + { + at[at_no].num_H += nDelta; + t_group_info->tni.nNumRemovedProtons--; + return nDelta; + } + /* remove */ + nNum2Remove = -nDelta; + nNumRemovedExplicitH = t_group_info->tni.nNumRemovedExplicitH; /* number of explicit H saved separately in + at[num_atoms+i], i=0..nNumRemovedExplicitH-1 */ + tot_num_iso_H = NUM_ISO_H( at, at_no ); + num_H = at[at_no].num_H; + /* + tot_num_iso_H = NUM_ISO_H(at,at_no); + num_H = at[at_no].num_H; + nNumAtomExplicitH = 0; + nNumRemovedExplicitH = t_group_info->tni.nNumRemovedExplicitH; + tot_num_explicit_iso_H = 0; + */ + + at_H = at + num_atoms; + memcpy(num_iso_H, at[at_no].num_iso_H, sizeof(num_iso_H)); + /* Remove all explicit H, otherwise a false stereo can occur. + Example: remove H(+) from the following substructure: + + H H + A / A / + >X==N(+) produces false stereogenic bond: >X==N + B \ B + H + + To avoid this effect all explicit H atoms must be removed + */ + + /* djb-rwth: removing redundant code */ + for (i = 0; i < nNumRemovedExplicitH; ) + { + if (at_H[i].neighbor[0] == at_no) + { + int m, k, orig_no = at_H[i].orig_at_number; + nNumRemovedExplicitH--; + /* djb-rwth: removing redundant code */ + if (nNumRemovedExplicitH > i) + { + inp_ATOM at_i = at_H[i]; + memmove(at_H + i, at_H + i + 1, sizeof(at_H[0]) * ((long long)nNumRemovedExplicitH - i)); /* djb-rwth: cast operator added */ + at_H[nNumRemovedExplicitH] = at_i; /* save removed H (for debugging purposes?) */ + } + /* Adjust 0D parities */ + if (at[at_no].sb_parity[0]) + { + for (m = 0; m < MAX_NUM_STEREO_BONDS && at[at_no].sb_parity[m]; m++) + { + if (at[at_no].sn_orig_at_num[m] == orig_no) + { + if (at[at_no].valence >= MIN_NUM_STEREO_BOND_NEIGH) + { + at[at_no].sn_ord[m] = k = ( at[at_no].sb_ord[m] == 0 ); + at[at_no].sn_orig_at_num[m] = at[(int) at[at_no].neighbor[k]].orig_at_number; + if (ATOM_PARITY_WELL_DEF( at[at_no].sb_parity[m] )) + { + at[at_no].sb_parity[m] = 3 - at[at_no].sb_parity[m]; + } + } + else + { + at[at_no].sn_ord[m] = -99; /* no sb neighbor exists anymore */ + at[at_no].sn_orig_at_num[m] = 0; + if (ATOM_PARITY_WELL_DEF( at[at_no].sb_parity[m] )) + { + int pnxt_atom, pinxt2cur, pinxt_sb_parity_ord; + if (0 < get_opposite_sb_atom( at, at_no, at[at_no].sb_ord[m], + &pnxt_atom, &pinxt2cur, &pinxt_sb_parity_ord )) + { + at[at_no].sb_parity[m] = + at[pnxt_atom].sb_parity[pinxt_sb_parity_ord] = AB_PARITY_UNDF; + } + } + } + } + } + } + /* do not increment i here: we have shifted next at_H[] element + to the ith position and decremented nNumRemovedExplicitH */ + } + else + { + i++; + } + } + + for (iso = -1; iso < NUM_H_ISOTOPES && 0 < nNum2Remove; iso++) + { + /* Each pass removes up to one H */ + if (iso < 0) + { + /* Try to remove non-isotopic */ + while (tot_num_iso_H < num_H && 0 < nNum2Remove) + { + /* Non-isotopic H exists */ + num_H--; + t_group_info->tni.nNumRemovedProtons++; + nNum2Remove--; + } + } + else + { + /* Remove isotopic */ + while (num_iso_H[iso] && num_H && 0 < nNum2Remove) + { + /* Isotopic H exists */ + num_H--; + num_iso_H[iso] --; + t_group_info->tni.nNumRemovedProtonsIsotopic[iso] ++; + t_group_info->tni.nNumRemovedProtons++; + nNum2Remove--; + } + } + } +#if ( bRELEASE_VERSION != 1 ) + if (nNum2Remove) + { + int stop = 1; /* Program error */ + } +#endif + if (nDelta + nNum2Remove < 0) + { + at[at_no].num_H = num_H; + memcpy(at[at_no].num_iso_H, num_iso_H, sizeof(at[0].num_iso_H)); + t_group_info->tni.nNumRemovedExplicitH = nNumRemovedExplicitH; + } + + return nDelta + nNum2Remove; +} + + +/****************************************************************************/ +int SubtractOrChangeAtHChargeBNS( BN_STRUCT *pBNS, + inp_ATOM *at, + int num_atoms, + int nAtTypeTotals[], + S_CHAR *mark, + T_GROUP_INFO *t_group_info, + int bSubtract ) +{ + int pass, i, v0, v1, v2, ineigh1, /*ineigh2,*/ vLast, n, delta, ret, err = 0; + BNS_EDGE *edge; + int nDeltaH, nDeltaCharge; + int mask, type; /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + + for (pass = pBNS->num_altp - 1, ret = 0; 0 <= pass; pass--) + { + + pBNS->alt_path = pBNS->altp[pass]; + v1 = ALTP_START_ATOM( pBNS->alt_path ); + n = ALTP_PATH_LEN( pBNS->alt_path ); + delta = ALTP_DELTA( pBNS->alt_path ); + vLast = ALTP_END_ATOM( pBNS->alt_path ); + v0 = v2 = NO_VERTEX; + + for (i = 0; i < n; i++, delta = -delta, v0 = v1, v1 = v2) + { + ineigh1 = ALTP_THIS_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v1->v2 neighbor */ + /*ineigh2 = ALTP_NEXT_ATOM_NEIGHBOR(pBNS->alt_path, i);*/ /* v2->v1 neighbor */ + edge = pBNS->edge + pBNS->vert[v1].iedge[ineigh1]; + /* follow the BN Structure, not the inp_ATOM, to take care of swithching to + t-groups, c-groups or other fictitious edges/vertices + */ + v2 = edge->neighbor12 ^ v1; + if (v1 < num_atoms && ( v0 >= num_atoms || v2 >= num_atoms )) + { + nDeltaH = nDeltaCharge = 0; + if (v0 >= num_atoms) + { + /* delta(v0-v1) = -delta(v1-v2) along the alternating path */ + if (pBNS->vert[v0].type & BNS_VERT_TYPE_TGROUP) + { + nDeltaH -= delta; + } + else + { + if (pBNS->vert[v0].type & BNS_VERT_TYPE_C_GROUP) + { + nDeltaCharge += delta; + } + } + } + if (v2 >= num_atoms) + { + if (pBNS->vert[v2].type & BNS_VERT_TYPE_TGROUP) + { + nDeltaH += delta; + } + else + { + if (pBNS->vert[v2].type & BNS_VERT_TYPE_C_GROUP) + { + nDeltaCharge -= delta; + } + } + } + if (nDeltaH || nDeltaCharge) + { + if (bSubtract) + { + if (!mark[v1]) + { + /* first time the atom has been encountered: subtract */ + /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ +#if ( FIX_NORM_BUG_ADD_ION_PAIR == 1 ) + type = GetAtomChargeType(at, v1, nAtTypeTotals, &mask, 2); +#else + type = GetAtomChargeType(at, v1, nAtTypeTotals, &mask, 1); +#endif + ret++; /* number of changed atoms */ + mark[v1] ++; + } + } + else + { + /* Change */ + at[v1].charge += nDeltaCharge; + if (nDeltaH) + { + AddOrRemoveExplOrImplH( nDeltaH, at, num_atoms, (AT_NUMB) v1, t_group_info ); + } + ret++; /* number of changed atoms */ + } + } + } + } + + if (v2 != vLast) + { + err = BNS_PROGRAM_ERR; + } + } + + return err ? err : ret; +} + + +/**************************************************************************** +Set Bonds From BnS Struct Flow +****************************************************************************/ +int SetBondsFromBnStructFlow( BN_STRUCT *pBNS, + inp_ATOM *at, + int num_atoms, + int bChangeFlow0 ) +{ + int pass, i, v0, v1, v2, ineigh1, ineigh2, vLast, n, delta, ret, ret_val, err = 0; + BNS_EDGE *edge; + int bChangeFlowAdd; /* djb-rwth: removing redundant variables */ + int bChangeFlow = ( bChangeFlow0 & ~BNS_EF_SET_NOSTEREO ); + /* + bCheckMovingRad = (bChangeFlow & BNS_EF_ALTR_NS) == BNS_EF_ALTR_NS && + pBNS->tot_st_cap > pBNS->tot_st_flow; + */ + for (pass = pBNS->num_altp - 1, ret = 0; 0 <= pass; pass--) + { + pBNS->alt_path = pBNS->altp[pass]; + v1 = ALTP_START_ATOM( pBNS->alt_path ); + n = ALTP_PATH_LEN( pBNS->alt_path ); + delta = ALTP_DELTA( pBNS->alt_path ); + vLast = ALTP_END_ATOM( pBNS->alt_path ); + if (( bChangeFlow0 & BNS_EF_SET_NOSTEREO ) && + ( pBNS->vert[v1].st_edge.cap0 > pBNS->vert[v1].st_edge.flow0 || + pBNS->vert[vLast].st_edge.cap0 > pBNS->vert[vLast].st_edge.flow0 )) + { + /* djb-rwth: removing redundant code */ + bChangeFlowAdd = BNS_EF_SET_NOSTEREO; + ret |= 2; + } + else + { + bChangeFlowAdd = 0; + } + /* start vertex */ + if (( bChangeFlow & BNS_EF_CHNG_RSTR ) == BNS_EF_CHNG_RSTR) + { + /* Restore s-v1 edge flow to the BNS this pass input value */ + ; /*pBNS->vert[v1].st_edge.flow -= delta;*/ + } + else + { + if (( bChangeFlow & BNS_EF_SAVE_ALL ) == BNS_EF_SAVE_ALL) + { + if (v1 < num_atoms) + { + /* Will produce wrong result if called for v1 next time? */ + ret_val = SetAtomRadAndChemValFromVertexCapFlow( pBNS, at, v1 ); + if (ret_val < 0) + { + err = BNS_PROGRAM_ERR; + } + else + { + ret |= ( ret_val > 0 ); + } + } + /*pBNS->vert[v1].st_edge.flow0 = pBNS->vert[v1].st_edge.flow;*/ + } + } + + pBNS->vert[v1].st_edge.pass = 0; + + v0 = v2 = NO_VERTEX; + for (i = 0; i < n; i++, delta = -delta, v0 = v1, v1 = v2) + { + ineigh1 = ALTP_THIS_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v1->v2 neighbor */ + ineigh2 = ALTP_NEXT_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v2->v1 neighbor */ + edge = pBNS->edge + pBNS->vert[v1].iedge[ineigh1]; + /* follow the BN Structure, not the inp_ATOM, to take care of swithching to + t-groups, c-groups or other fictitious edges/vertices + */ + + v2 = edge->neighbor12 ^ v1; + + /* change at->chem_bonds_valence 2004-03-08 */ + if (( bChangeFlow & BNS_EF_CHNG_BONDS ) && v1 < num_atoms) + { + if (v0 >= num_atoms && v2 < num_atoms) + { + at[v1].chem_bonds_valence += delta; /* change in v1-v2 bond order */ + } + else + { + if (v0 < num_atoms && v2 >= num_atoms && v0 != NO_VERTEX) + { + at[v1].chem_bonds_valence -= delta; /* change in v0-v1 bond order */ + } + } + } + + if (!edge->pass) + { + continue; + } + + if (v1 < num_atoms && ineigh1 < at[v1].valence && + v2 < num_atoms && ineigh2 < at[v2].valence) + { + if (( bChangeFlow0 & BNS_EF_ALTR_NS ) == BNS_EF_ALTR_NS && + ( bChangeFlow0 & BNS_EF_SAVE_ALL ) == BNS_EF_SAVE_ALL) + { + /* 2004-07-02 special mode: save new ring bonds and mark as non-stereo non-ring bonds */ + if (at[v1].nRingSystem != at[v2].nRingSystem) + { + /* Non-ring bond (bridge) */ + bChangeFlowAdd = BNS_EF_ALTR_NS; + } + else + { + /* Ring bond */ + bChangeFlowAdd = 0; + } + } + /* Change bonds on the first pass only: in this case all flow correspond to the BNS output */ + ret_val = SetAtomBondType( edge, &at[v1].bond_type[ineigh1], &at[v2].bond_type[ineigh2], delta, bChangeFlow | bChangeFlowAdd ); + if (ret_val < 0) + { + err = BNS_PROGRAM_ERR; + } + else + { + ret |= ( ret_val > 0 ); + } + } + edge->pass = 0; + } + + if (v2 != vLast) + { + err = BNS_PROGRAM_ERR; + } + else + { + if (( bChangeFlow & BNS_EF_CHNG_RSTR ) == BNS_EF_CHNG_RSTR) + { + /* Restore v2-t edge flow to the BNS this pass input value */ + /* "+=" instead of "-=" explanation: delta must have same sign as at the last edge */ + ; /*pBNS->vert[v2].st_edge.flow += delta; */ + } + else + { + if (( bChangeFlow & BNS_EF_SAVE_ALL ) == BNS_EF_SAVE_ALL) + { + if (v2 < num_atoms) + { + ret_val = SetAtomRadAndChemValFromVertexCapFlow( pBNS, at, v2 ); + if (ret_val < 0) + { + err = BNS_PROGRAM_ERR; + } + else + { + ret |= ( ret_val > 0 ); + } + } + /*pBNS->vert[v2].st_edge.flow0 = pBNS->vert[v2].st_edge.flow;*/ + } + } + } + pBNS->vert[v2].st_edge.pass = 0; + } + + return err ? err : ret; +} + + +/****************************************************************************/ +int MarkAtomsAtTautGroups( BN_STRUCT *pBNS, + int num_atoms, + BN_AATG *pAATG, + int nEnd1, + int nEnd2 ) +{ + int pass, i, j, v1, v2, ineigh1, ineigh2, vLast, vFirst, n, delta, err = 0; /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ + BNS_EDGE *edge; + S_CHAR cDelta[MAX_ALT_AATG_ARRAY_LEN]; + AT_NUMB nVertex[MAX_ALT_AATG_ARRAY_LEN]; + int nLenDelta = 0, last_i, nNumFound; + + for (pass = pBNS->num_altp - 1; 0 <= pass; pass--) + { + pBNS->alt_path = pBNS->altp[pass]; + vFirst = + v1 = ALTP_START_ATOM( pBNS->alt_path ); + n = ALTP_PATH_LEN( pBNS->alt_path ); + delta = ALTP_DELTA( pBNS->alt_path ); + vLast = ALTP_END_ATOM( pBNS->alt_path ); + v2 = NO_VERTEX; + pAATG->nNumFound = 0; /* initialize */ + + if (nEnd1 != vFirst && nEnd1 != vLast) + { + nEnd1 = -1; /* really not the end */ + } + if (nEnd2 != vFirst && nEnd2 != vLast) + { + nEnd2 = -1; /* really not the end */ + } + + for (i = 0; i < n; i++, delta = -delta, v1 = v2) + { + ineigh1 = ALTP_THIS_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v1->v2 neighbor */ + ineigh2 = ALTP_NEXT_ATOM_NEIGHBOR(pBNS->alt_path, i); /* v2->v1 neighbor */ /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ + edge = pBNS->edge + pBNS->vert[v1].iedge[ineigh1]; + /* follow the BN Structure, not the inp_ATOM, to take care of swithching to + t-groups, c-groups or other fictitious edges/vertices + */ + v2 = edge->neighbor12 ^ v1; + /* + if ( v1 < num_atoms && v2 < num_atoms ) { + continue; + } + */ + /* BNS increased edge flow by delta */ + if (v1 >= num_atoms && + ( ( pBNS->vert[v1].type & BNS_VERT_TYPE_TGROUP ) || ( pBNS->vert[v1].type & BNS_VERT_TYPE_TEMP ) ) && + 0 <= v2 && v2 < num_atoms && ( pBNS->vert[v2].type & BNS_VERT_TYPE_ATOM )) + { + /* + if ( !(pAATG->nMarkedAtom[v2] & AATG_MARK_IN_PATH) ) { + pAATG->nMarkedAtom[v2] |= AATG_MARK_IN_PATH; + pAATG->nNumFound ++; + } + */ + + /* BNS increased bond order in v1(t-group)-v2(atom) by delta: added delta attachments */ + if (nLenDelta < MAX_ALT_AATG_ARRAY_LEN) + { + cDelta[nLenDelta] = delta; + nVertex[nLenDelta] = v2; + nLenDelta++; + } + } + else + { + if (v2 >= num_atoms && + ( ( pBNS->vert[v2].type & BNS_VERT_TYPE_TGROUP ) || ( pBNS->vert[v2].type & BNS_VERT_TYPE_TEMP ) ) && + 0 <= v1 && v1 < num_atoms && ( pBNS->vert[v1].type & BNS_VERT_TYPE_ATOM )) + { + /* + if ( !(pAATG->nMarkedAtom[v1] & AATG_MARK_IN_PATH) ) { + pAATG->nMarkedAtom[v1] |= AATG_MARK_IN_PATH; + pAATG->nNumFound ++; + } + */ + + /* BNS increased bond order in v1(atom)-v2(t-group) by delta: added delta attachments */ + if (nLenDelta < MAX_ALT_AATG_ARRAY_LEN) + { + cDelta[nLenDelta] = delta; + nVertex[nLenDelta] = v1; + nLenDelta++; + } + } + else + { + /* Special case when the testing 'dot' was placed on an atom (should be nEnd1 only) */ + if ((0 <= v1 && v1 == nEnd1) || (v1 == nEnd2 && 0 <= v2 && v2 < num_atoms)) /* djb-rwth: addressing LLVM warning */ + { + if (nLenDelta < MAX_ALT_AATG_ARRAY_LEN) + { + cDelta[nLenDelta] = -delta; + nVertex[nLenDelta] = v1; + nLenDelta++; + } + } + else + { + if ((0 <= v2 && v2 == nEnd1) || (v2 == nEnd2 && 0 <= v1 && v1 < num_atoms)) /* djb-rwth: addressing LLVM warning */ + { + if (nLenDelta < MAX_ALT_AATG_ARRAY_LEN) + { + cDelta[nLenDelta] = -delta; + nVertex[nLenDelta] = v2; + nLenDelta++; + } + } + } + } + } + } + + if (v2 != vLast) + { + err = BNS_PROGRAM_ERR; + } + else + { + last_i = -1; + nNumFound = 0; + /* first run */ + for (i = 1, j = 0; i < nLenDelta; j = i++) + { + /* Ignore sequences (-1,+1) and (+1,-1) in cDelta[] because they */ + /* describe ordinary aug. paths of moving a single attachment */ + /* we are looking for aug. paths describing movement of 2 or more */ + if ((cDelta[j] > 0 && cDelta[i] > 0) || + (cDelta[j] < 0 && cDelta[i] < 0)) /* djb-rwth: addressing LLVM warning */ + { + if (j == last_i) + { + /* Three attachments moved */ + return 0; + } + v1 = nVertex[j]; + if (!( pAATG->nMarkedAtom[v1] & AATG_MARK_IN_PATH )) + { + nNumFound++; + } + v2 = nVertex[i]; + if (!( pAATG->nMarkedAtom[v2] & AATG_MARK_IN_PATH )) + { + nNumFound++; + } + last_i = i; + } + } + if (!nNumFound) + { + return 0; + } + if (nNumFound > 4) + { + return 0; + } + if (nNumFound < 4) + { + return 0; + } + + /* Second run */ + for (i = 1, j = 0; i < nLenDelta; j = i++) + { + /* Ignore sequences (-1,+1) and (+1,-1) in cDelta[] because they */ + /* describe ordinary aug. paths of moving a single attachment */ + /* we are looking for aug. paths describing movement of 2 or more */ + if ((cDelta[j] > 0 && cDelta[i] > 0) || + (cDelta[j] < 0 && cDelta[i] < 0)) /* djb-rwth: addressing LLVM warning */ + { + v1 = nVertex[i - 1]; + if (!( pAATG->nMarkedAtom[v1] & AATG_MARK_IN_PATH )) + { + pAATG->nMarkedAtom[v1] |= AATG_MARK_IN_PATH; + pAATG->nNumFound++; + } + v2 = nVertex[i]; + if (!( pAATG->nMarkedAtom[v2] & AATG_MARK_IN_PATH )) + { + pAATG->nMarkedAtom[v2] |= AATG_MARK_IN_PATH; + pAATG->nNumFound++; + } + } + } + } + } + + return err ? err : pAATG->nNumFound; +} + + +/****************************************************************************/ +int RestoreBnStructFlow( BN_STRUCT *pBNS, int bChangeFlow ) +{ + int pass, i, v1, v2, ineigh1, ineigh2, vLast, n, delta, ret, err = 0; /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ + BNS_EDGE *edge; + + for (pass = pBNS->num_altp - 1, ret = 0; 0 <= pass; pass--) + { + pBNS->alt_path = pBNS->altp[pass]; + v1 = ALTP_START_ATOM( pBNS->alt_path ); + n = ALTP_PATH_LEN( pBNS->alt_path ); + delta = ALTP_DELTA( pBNS->alt_path ); + vLast = ALTP_END_ATOM( pBNS->alt_path ); + v2 = NO_VERTEX; + /* starting vertex */ + if (( bChangeFlow & BNS_EF_CHNG_RSTR ) == BNS_EF_CHNG_RSTR) + { + pBNS->vert[v1].st_edge.flow -= delta; /* restore s-v1 edge flow to the BNS input value */ + } + else + { + if (( bChangeFlow & BNS_EF_SAVE_ALL ) == BNS_EF_SAVE_ALL) + { + pBNS->vert[v1].st_edge.flow0 = pBNS->vert[v1].st_edge.flow; + } + } + + /* Augmenting path edges */ + for (i = 0; i < n; i++, delta = -delta, v1 = v2) + { + ineigh1 = ALTP_THIS_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v1->v2 neighbor */ + ineigh2 = ALTP_NEXT_ATOM_NEIGHBOR(pBNS->alt_path, i); /* v2->v1 neighbor */ /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ + edge = pBNS->edge + pBNS->vert[v1].iedge[ineigh1]; + v2 = edge->neighbor12 ^ v1; + RestoreEdgeFlow( edge, delta, bChangeFlow ); + edge->pass = 0; + } + + /* Ending vertex */ + if (v2 != vLast) + { + err = BNS_PROGRAM_ERR; + } + else + { + if (( bChangeFlow & BNS_EF_CHNG_RSTR ) == BNS_EF_CHNG_RSTR) + { + /* Restore v2-t edge flow to the original value */ + /* "+=" instead of "-=" explanation: delta must have same sign as at the last edge */ + pBNS->vert[v2].st_edge.flow += delta; + } + else + { + if (( bChangeFlow & BNS_EF_SAVE_ALL ) == BNS_EF_SAVE_ALL) + { + pBNS->vert[v2].st_edge.flow0 = pBNS->vert[v2].st_edge.flow; + } + } + } + } + + return err ? err : ret; +} + + +/****************************************************************************/ +int bNeedToTestTheFlow( int bond_type, + int nTestFlow, + int bTestForNonStereoBond ) +{ + int nBondType = ( BOND_TYPE_MASK & bond_type ); + int nBondAttrib = ( BOND_MARK_MASK & bond_type ); + + if (bTestForNonStereoBond) + { + if (nBondAttrib || nBondType == BOND_ALTERN || nBondType == BOND_ALT12NS) + { + switch (nTestFlow) + { + case 0: /* single: can be 1 (single)? */ + if (nBondAttrib == BOND_MARK_ALT12NS || + nBondAttrib == BOND_MARK_ALT123 || + nBondAttrib == BOND_MARK_ALT13) + { + return 0; /* yes, already checked */ + } + break; + + case 1: /* double: can be 2 (double)? */ + if (nBondAttrib == BOND_MARK_ALT12NS || + nBondAttrib == BOND_MARK_ALT123 || + nBondAttrib == BOND_MARK_ALT23) + { + return 0; /* yes, already checked */ + } + break; + case 2: /* triple: can be 3 (triple)? */ + if (nBondAttrib == BOND_MARK_ALT13 || + nBondAttrib == BOND_MARK_ALT123 || + nBondAttrib == BOND_MARK_ALT23) + { + return 0; /* yes, already checked */ + } + break; + } + } + } + else + { + if (nBondAttrib || nBondType == BOND_ALTERN || nBondType == BOND_ALT12NS) + { + switch (nTestFlow) + { + case 0: /* single: can be 1 (single)? */ + if (nBondAttrib == BOND_MARK_ALT12 || + nBondAttrib == BOND_MARK_ALT12NS || + nBondAttrib == BOND_MARK_ALT123 || + nBondAttrib == BOND_MARK_ALT13) + { + return 0; + } + break; + + case 1: /* double: can be 2 (double)? */ + if (nBondAttrib == BOND_MARK_ALT12 || + nBondAttrib == BOND_MARK_ALT12NS || + nBondAttrib == BOND_MARK_ALT123 || + nBondAttrib == BOND_MARK_ALT23) + { + return 0; /* yes */ + } + break; + case 2: /* triple: can be 3 (triple)? */ + if (nBondAttrib == BOND_MARK_ALT13 || + nBondAttrib == BOND_MARK_ALT123 || + nBondAttrib == BOND_MARK_ALT23) + { + return 0; + } + break; + } + } + } + + return 1; +} + + +/****************************************************************************/ +int nBondsValenceInpAt( const inp_ATOM *at, + int *nNumAltBonds, + int *nNumWrongBonds ) +{ + int j, bond_type, nBondsValence = 0, nAltBonds = 0, nNumWrong = 0; + for (j = 0; j < at->valence; j++) + { + bond_type = at->bond_type[j] & BOND_TYPE_MASK; + switch (bond_type) + { + case 0: /* for structure from InChI reconstruction */ + case BOND_SINGLE: + case BOND_DOUBLE: + case BOND_TRIPLE: + nBondsValence += bond_type; + break; + case BOND_ALTERN: + nAltBonds++; + break; + default: + nNumWrong++; + } + } + switch (nAltBonds) + { + case 0: + break; + case 1: + nBondsValence += 1; /* 1 or greater than 3 is wrong */ + nNumWrong++; + break; + default: + nBondsValence += nAltBonds + 1; + break; + } + if (nNumAltBonds) + { + *nNumAltBonds = nAltBonds; + } + if (nNumWrongBonds) + { + *nNumWrongBonds = nNumWrong; + } + + return nBondsValence; +} + + +/**************************************************************************** +If radical or has aromatic bonds, +then augment to the lowest "multiplicity" +****************************************************************************/ +int BnsAdjustFlowBondsRad( BN_STRUCT *pBNS, + BN_DATA *pBD, + inp_ATOM *at, + int num_atoms ) +{ + int bError = 0, nOrigDelta = 0, ret, num_removed; + +#if( CHECK_AROMBOND2ALT == 1 ) + int *pcValMinusBondsVal = NULL; + int i, nValMinusBondsVal, nAltBonds, bIgnore, valen, is_rad, excess; + + /* Find valence excess (it may only be due to aromatic bonds) */ + for (i = 0; i < num_atoms; i++) + { + valen = nBondsValenceInpAt( at + i, &nAltBonds, &bIgnore ); + nValMinusBondsVal = (int) at[i].chem_bonds_valence - valen; + bIgnore += ( nAltBonds > 3 ); + if (!bIgnore && nValMinusBondsVal > 0) + { + if (!pcValMinusBondsVal && + !( pcValMinusBondsVal = (int *) inchi_calloc( num_atoms, sizeof( pcValMinusBondsVal[0] ) ) )) + { + bError = BNS_OUT_OF_RAM; + goto exit_function; + } + /* Mark atoms that have extra unsatisfied valence due to aromatic bonds */ + is_rad = ( at[i].radical == RADICAL_DOUBLET ); + excess = nValMinusBondsVal + is_rad; + pcValMinusBondsVal[i] = excess; + } + } +#endif /* CHECK_AROMBOND2ALT */ + + /* Match bonds to valences */ + do + { + num_removed = 0; + ret = RunBalancedNetworkSearch( pBNS, pBD, BNS_EF_CHNG_FLOW ); + if (IS_BNS_ERROR( ret )) + { + bError = ret; + } + else + { + nOrigDelta += ret; + num_removed = pBNS->num_altp; /* number of augmenting paths */ + if (ret > 0) + { + /* save new bonds in at[] and flows in pBNS and at[] */ + ret = SetBondsFromBnStructFlow( pBNS, at, num_atoms, BNS_EF_SAVE_ALL ); /* must include 1: 5=(4|1) */ + if (IS_BNS_ERROR( ret )) + { + bError = ret; + } + ret = RestoreBnStructFlow( pBNS, BNS_EF_SAVE_ALL ); /* must include 1: 5=(4|1) */ + if (IS_BNS_ERROR( ret )) + { + bError = ret; + } + } + ReInitBnStructAltPaths( pBNS ); + } + } while (num_removed && num_removed == pBNS->max_altp && !bError); + +#if( CHECK_AROMBOND2ALT == 1 ) + /* Check whether aromatic bonds have been replaced with alternating bonds */ + if (!bError && pcValMinusBondsVal) + { + for (i = 0; i < num_atoms; i++) + { + if (!pcValMinusBondsVal[i]) + { + continue; + } + valen = nBondsValenceInpAt( at + i, &nAltBonds, &bIgnore ); + nValMinusBondsVal = (int) at[i].chem_bonds_valence - valen; + is_rad = ( at[i].radical == RADICAL_DOUBLET ); + excess = nValMinusBondsVal + is_rad; + if (bIgnore || + ( pcValMinusBondsVal[i] - excess ) != 1) + { + /* radical excess has not been reduced */ + bError = BNS_ALTBOND_ERR; + break; + } + } + } + +exit_function: + if (pcValMinusBondsVal) + { + inchi_free( pcValMinusBondsVal ); + } +#endif /* CHECK_AROMBOND2ALT */ + + return bError ? bError : nOrigDelta; +} + + +/****************************************************************************/ +int BnsTestAndMarkAltBonds( BN_STRUCT *pBNS, + BN_DATA *pBD, + inp_ATOM *at, + int num_atoms, + BNS_FLOW_CHANGES *fcd, + int bChangeFlow, + int nBondTypeToTest ) +{ + int ret, iat, ineigh, neigh; + int nMinFlow, nMaxFlow, nTestFlow, nCurFlow; + int iedge, bError, nDots, nChanges, bTestForNonStereoBond; /* djb-rwth: removing redundant variables */ + + /* Normalize bonds and find tautomeric groups */ + bError = 0; + nChanges = 0; + bTestForNonStereoBond = pBNS->tot_st_cap > pBNS->tot_st_flow; + + for (iat = 0; iat < num_atoms && !bError; iat++) + { + for (ineigh = 0; ineigh < at[iat].valence && !bError; ineigh++) + { + neigh = at[iat].neighbor[ineigh]; + if (neigh < iat) + { + continue; /* we have already tested the bond */ + } + iedge = pBNS->vert[iat].iedge[ineigh]; + if (IS_FORBIDDEN( pBNS->edge[iedge].forbidden, pBNS )) + { + continue; + } + if (nBondTypeToTest && ( at[iat].bond_type[ineigh] & BOND_TYPE_MASK ) != nBondTypeToTest) + { + continue; + } + nMinFlow = nMinFlow2Check( pBNS, iedge ); + nMaxFlow = nMaxFlow2Check( pBNS, iedge ); + nCurFlow = nCurFlow2Check( pBNS, iedge ); + if (nMinFlow == nMaxFlow) + { + if (nMaxFlow && bTestForNonStereoBond) + { + nTestFlow = nMaxFlow - (int) ( pBNS->tot_st_cap - pBNS->tot_st_flow ); /* temporary use of nTestFlow */ + nMinFlow = inchi_max( 0, nTestFlow ); + } + else + { + continue; + } + } + for (nTestFlow = nMinFlow; nTestFlow <= nMaxFlow && !bError; nTestFlow++) + { + if (nTestFlow == nCurFlow) + { + continue; + } + if (!bNeedToTestTheFlow( at[iat].bond_type[ineigh], nTestFlow, bTestForNonStereoBond )) + { + continue; + } + /* djb-rwth: removing redundant code */ + nDots = bSetFlowToCheckOneBond( pBNS, iedge, nTestFlow, fcd ); + + if (IS_BNS_ERROR( nDots )) + { + if (nDots == BNS_CANT_SET_BOND) + { + ret = bRestoreFlowAfterCheckOneBond( pBNS, fcd ); + if (!IS_BNS_ERROR( ret )) + { + continue; + } + } + bError = nDots; + } + else + { + if (nDots > 0) + { + ret = RunBalancedNetworkSearch( pBNS, pBD, bChangeFlow ); + if (IS_BNS_ERROR( ret )) + { + bError = ret; + } + else + { + if (ret > 0) + { + if (2 * ret == nDots) + { + ret = bSetBondsAfterCheckOneBond( pBNS, fcd, nTestFlow, at, num_atoms, bChangeFlow ); + if (IS_BNS_ERROR( ret )) + { + bError = ret; + } + else + { + nChanges += ( ret & 1 ); + ret = SetBondsFromBnStructFlow( pBNS, at, num_atoms, bChangeFlow ); + if (IS_BNS_ERROR( ret )) + { + bError = ret; + } + else + { + if (ret >= 0) + { + nChanges += ( ret & 1 ); + /* djb-rwth: removing redundant code */ + } + else + { + bError = ret; + } + } + } + } + /* typically 2*ret < nDots; 2*ret > nDots should not happen. Check later */ + ret = RestoreBnStructFlow( pBNS, bChangeFlow & BNS_EF_CHNG_RSTR ); + if (IS_BNS_ERROR( ret )) + { + bError = ret; + } + } + } + /* --- Reinitialize to repeat the calculations --- */ + ReInitBnStructAltPaths( pBNS ); + } + + else + { + if (nDots == 0) + { + ret = bSetBondsAfterCheckOneBond( pBNS, fcd, nTestFlow, at, num_atoms, bChangeFlow ); + if (IS_BNS_ERROR( ret )) + { + bError = ret; + } + else + { + nChanges += ( ret & 1 ); + } + } + } + } + + ret = bRestoreFlowAfterCheckOneBond( pBNS, fcd ); + + if (IS_BNS_ERROR( ret )) + { + bError = ret; + } + + } /* for (nTestFlow = */ + } /* for (ineigh = */ + } /* for (iat = */ + + return bError ? bError : nChanges; +} + + +/****************************************************************************/ +static void remove_alt_bond_marks( inp_ATOM *at, int num_atoms ) +{ + int i, j, val; + for (i = 0; i < num_atoms; i++) + { + for (val = at[i].valence, j = 0; j < val; j++) + { + at[i].bond_type[j] &= BOND_TYPE_MASK; + } + } + +} + + +/****************************************************************************/ +int SetForbiddenEdges( BN_STRUCT *pBNS, + inp_ATOM *at, + int num_atoms, + int forbidden_mask, + int nebend, + int *ebend ) +{ + + + int i, j, neigh, num_found; + BNS_IEDGE iedge; + /*S_CHAR edge_forbidden_mask = BNS_EDGE_FORBIDDEN_MASK;*/ + S_CHAR edge_forbidden_mask = forbidden_mask; + + pBNS->edge_forbidden_mask |= forbidden_mask; + + num_found = 0; + + for (i = 0; i < num_atoms; i++) + { + /* acetyl */ + if (at[i].el_number == EL_NUMBER_C && 3 == at[i].valence && + 4 == at[i].chem_bonds_valence) + { + int num_O = 0; + int bond_to_O_val = 0; + int forbidden_bond_pos = -1; + int forbidden_bond_val = -1; + for (j = 0; j < at[i].valence; j++) + { + neigh = at[i].neighbor[j]; + if (at[neigh].el_number == EL_NUMBER_O && + at[neigh].valence == 1) + { + num_O++; + bond_to_O_val += ( at[i].bond_type[j] & BOND_TYPE_MASK ); + } + else + { + forbidden_bond_pos = j; + forbidden_bond_val = ( at[i].bond_type[j] & BOND_TYPE_MASK ); + } + } + if (2 == num_O && 3 == bond_to_O_val && 1 == forbidden_bond_val) + { + iedge = pBNS->vert[i].iedge[forbidden_bond_pos]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; + num_found++; + } + } + else + { + /* nitro */ + if (at[i].el_number == EL_NUMBER_N && 3 == at[i].valence && + ( 4 == at[i].chem_bonds_valence || 5 == at[i].chem_bonds_valence )) + { + int num_O = 0; + int bond_to_O_val = 0; + int forbidden_bond_pos = -1; + int forbidden_bond_val = -1; + for (j = 0; j < at[i].valence; j++) + { + neigh = at[i].neighbor[j]; + if (at[neigh].el_number == EL_NUMBER_O && + at[neigh].valence == 1) + { + num_O++; + bond_to_O_val += ( at[i].bond_type[j] & BOND_TYPE_MASK ); + } + else + { + forbidden_bond_pos = j; + forbidden_bond_val = ( at[i].bond_type[j] & BOND_TYPE_MASK ); + } + } + if (2 == num_O && ( 3 == bond_to_O_val || 4 == bond_to_O_val ) && 1 == forbidden_bond_val) + { + iedge = pBNS->vert[i].iedge[forbidden_bond_pos]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; + num_found++; + } + } + } + } + +#ifdef FIX_SRU_CYCLIZING_PS_BONDS_IN_BNS + if (nebend > 1) + num_found += fix_explicitly_indicated_bonds( nebend, ebend, pBNS, at, num_atoms ); +#endif + +#if ( REMOVE_ION_PAIRS_FIX_BONDS == 1 ) + num_found += fix_special_bonds( pBNS, at, num_atoms, edge_forbidden_mask ); +#endif +#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) + num_found += TempFix_NH_NH_Bonds( pBNS, at, num_atoms ); +#endif + + return num_found; +} + + + +#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) + + +/****************************************************************************/ +int TempFix_NH_NH_Bonds( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms ) +{ + int i, j, neigh, num_found; + BNS_IEDGE iedge; + S_CHAR edge_forbidden_mask = BNS_EDGE_FORBIDDEN_TEMP; + for (i = 0, num_found = 0; i < num_atoms; i++) + { + /* -NH-NH- or -NH-NH3 */ + if (at[i].el_number == EL_NUMBER_N && at[i].valence < 3 && at[i].num_H && + 3 == at[i].chem_bonds_valence + at[i].num_H && + at[i].chem_bonds_valence == at[i].valence && + !at[i].charge && !at[i].radical) + { + for (j = 0; j < at[i].valence; j++) + { + neigh = at[i].neighbor[j]; + if (neigh < i && + at[neigh].el_number == EL_NUMBER_N && at[neigh].valence < 3 && at[neigh].num_H && + 3 == at[neigh].chem_bonds_valence + at[neigh].num_H && + at[neigh].chem_bonds_valence == at[neigh].valence && + !at[neigh].charge && !at[neigh].radical) + { + iedge = pBNS->vert[i].iedge[j]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; + num_found++; + } + } + } + } + + return num_found; +} + + +/****************************************************************************/ +int CorrectFixing_NH_NH_Bonds( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms ) +{ + int i, j, neigh, num_found; + BNS_IEDGE iedge; + S_CHAR edge_forbidden_mask = BNS_EDGE_FORBIDDEN_TEMP; + + for (i = 0, num_found = 0; i < num_atoms; i++) + { + /* -NH-NH- or -NH-NH3 */ + if (at[i].el_number == EL_NUMBER_N && at[i].valence < 3) + { + for (j = 0; j < at[i].valence; j++) + { + neigh = at[i].neighbor[j]; + if (neigh < i && + at[neigh].el_number == EL_NUMBER_N && at[neigh].valence < 3) + { + if (BOND_TYPE_SINGLE != ( at[i].bond_type[j] & BOND_TYPE_MASK )) + { + iedge = pBNS->vert[i].iedge[j]; + if (pBNS->edge[iedge].forbidden & edge_forbidden_mask) + { + pBNS->edge[iedge].forbidden &= ~edge_forbidden_mask; + num_found++; + } + } + } + } + } + } + + return num_found; +} +#endif + +/**************************************************************************** +Fixes bonds which were set by remove_ion_pairs( ... ) +****************************************************************************/ +int fix_special_bonds( BN_STRUCT *pBNS, + inp_ATOM *at, + int num_atoms, + int forbidden_mask ) +{ + int num_changes = 0; + +#define MAX_NEIGH 6 + + int i, k, n1, n2, n3, i1, i2, i3, i4, bond_type; /* djb-rwth: removing redundant variables */ + inp_ATOM *a; + int j[3], m[3], num_O, k_O, num_N, num_OH, num_OM, num_X, num_other, k_N; + + BNS_IEDGE iedge; + /*S_CHAR edge_forbidden_mask = BNS_EDGE_FORBIDDEN_MASK;*/ + S_CHAR edge_forbidden_mask = forbidden_mask; + + pBNS->edge_forbidden_mask |= edge_forbidden_mask; + + for (i = 0, a = at; i < num_atoms; i++, a++) + { + + if (!a->charge && !a->radical && + 2 <= a->chem_bonds_valence + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && + 0 == num_of_H( at, i ) && + 2 == nNoMetalBondsValence( at, i ) + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && + ion_el_group( at[i].el_number ) == EL_NUMBER_N ) + { + /* Found N(V), no H */ + if (2 == nNoMetalNumBonds( at, i )) + { + /* #N= */ + /* fix bonds: double and triple: =N# so that bonds cannot be changed by the normalization */ +#if ( FIX_N_V_METAL_BONDS_GPF == 1 ) + if (0 > ( i1 = nNoMetalNeighIndex( at, i ) ) || + 0 > ( i2 = nNoMetalOtherNeighIndex( at, i, n1 = a->neighbor[i1]/* non-metal neighbor #1 */ ) )) + { + /*num_err ++; */ /* do not count would-be original InChI v.1 buffer overflow GPF */ + continue; /* v1 bug: 2 bonds to metal yield i1 < 0 and/or i2 < 0 => bounds violation */ + } +#else + i1 = nNoMetalNeighIndex( at, i ); + n1 = a->neighbor[i1]; /* non-metal neighbor #1 */ + i2 = nNoMetalOtherNeighIndex( at, i, n1 ); +#endif + n2 = a->neighbor[i2]; /* non-metal neighbor #2 */ + /* forbid all edges to non-metals */ + iedge = pBNS->vert[i].iedge[i1]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; /* fix bond to neighbor #1 */ + iedge = pBNS->vert[i].iedge[i2]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; /* fix bond to neighbor #1 */ + num_changes++; /* added 11-15-2005 */ + /* i n3 */ + /* forbid single bond edge beyond the neighboring =N- as in #N=N- */ + /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + if (( at[i].bond_type[i1] & BOND_TYPE_MASK ) == BOND_TYPE_DOUBLE) + { + i3 = i1; /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + n3 = n1; + } + else + { + i3 = i2; /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + n3 = n2; + } + if (0 == NUMH( at, n3 ) && 2 == nNoMetalNumBonds( at, n3 ) && + 3 == nNoMetalBondsValence( at, n3 ) && + ion_el_group( at[n3].el_number ) == EL_NUMBER_N && + 0 <= ( k = nNoMetalOtherNeighIndex( at, n3, i ) )) + { + /* found =N- ; forbid the edge*/ + iedge = pBNS->vert[n3].iedge[k]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; + num_changes++; + } + } + else if (3 == nNoMetalNumBonds( at, i ) && + /* | */ + /* found =N= */ + /* locate all non-metal neighbors */ + 0 <= ( j[0] = nNoMetalNeighIndex( at, i ) ) && + 0 <= ( j[1] = nNoMetalOtherNeighIndex( at, i, m[0] = a->neighbor[j[0]] ) ) && + 0 <= ( j[2] = nNoMetalOtherNeighIndex2( at, i, m[0], m[1] = a->neighbor[j[1]] ) )) + { + /* Count specific neighbors: N(V)=N, N(V)-N N(V)=O, and N(V)-N */ + + /* if there is a single neighbor connected by a double bond, namely + N(V)=N and/or N(V)=O, then fix the bond(s). + If N(V)=O was fixed then do not fix another bond */ + m[2] = a->neighbor[j[2]]; + num_O = num_N = 0; + for (k = 0; k < 3; k++) + { + n1 = m[k]; + i1 = j[k]; /* djb-rwth: ignoring LLVM warning: variable used */ + if (ion_el_group( at[n1].el_number ) == EL_NUMBER_N) + { + k_N = k; + num_N++; + } + else if (ion_el_group( at[n1].el_number ) == EL_NUMBER_O && + 1 == nNoMetalNumBonds( at, n1 )) + { + k_O = k; + num_O++; + } + } + num_other = 0; + if (1 == num_O && + 0 == at[n1 = m[k_O]].charge && + 0 == at[n1].radical && + BOND_TYPE_DOUBLE == ( at[i].bond_type[i1 = j[k_O]] & BOND_TYPE_MASK ) + ) + { + /* Fix bond to neighbor =O */ + iedge = pBNS->vert[i].iedge[i1]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; + num_changes++; + num_other++; /* indicator: double to a terminal O has been fixed */ + } + if (!num_other && + num_O <= 1 && + 1 == num_N && + 0 == at[n1 = m[k_N]].charge && + 0 == at[n1].radical && + BOND_TYPE_DOUBLE == ( at[i].bond_type[i1 = j[k_N]] & BOND_TYPE_MASK )) + { + /* Fix bond to neighbor =N */ + iedge = pBNS->vert[i].iedge[i1]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; + num_changes++; + } + } + else if (4 == nNoMetalNumBonds( at, i )) + { + /* | */ + /* found -N=N- */ + /* | */ + /* locate non-metal neighbor connected by a double bond; + * if it is =N- then fix the double bond and the single bond beyond the neighbor + */ + num_N = 0; + num_other = 0; /* djb-rwth: ignoring LLVM warning: variable used */ + for (i1 = 0; i1 < at[i].valence; i1++) + { + if (BOND_TYPE_DOUBLE == ( at[i].bond_type[i1] & BOND_TYPE_MASK ) && + !is_el_a_metal( at[n1 = (int) at[i].neighbor[i1]].el_number ) && + ion_el_group( at[n1].el_number ) == EL_NUMBER_N) + { + num_N++; + n2 = n1; + i2 = i1; + } + } + if (1 == num_N && 0 == NUMH( at, n2 ) && + 2 == nNoMetalNumBonds( at, n2 ) && + 3 == nNoMetalBondsValence( at, n2 ) && + 0 <= ( i3 = nNoMetalOtherNeighIndex( at, n2, i ) ) && + BOND_TYPE_SINGLE == ( at[n2].bond_type[i3] & BOND_TYPE_MASK )) + { + /* fix the single bond beyond the N(V) neighbor N(V)=N- */ + iedge = pBNS->vert[n2].iedge[i3]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; + num_changes++; + /* fix the double bond */ + iedge = pBNS->vert[i].iedge[i2]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; + num_changes++; + } + } + } + + else if (!a->charge && !a->radical && + 2 <= a->chem_bonds_valence + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && + 0 == num_of_H( at, i ) && + 2 == nNoMetalBondsValence( at, i ) + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && + a->el_number != EL_NUMBER_O && ion_el_group( a->el_number ) == EL_NUMBER_O && + 3 == nNoMetalNumBonds( at, i )) + { + /* Found S(IV), no H, one double bond, total 3 bonds */ + /* OH + / + in O=S (X != O) fix single bond O-X (type 1) + \ + X + + X + / + in Z=S (X, Y != OH) fix double bond Z=S (type 2) + \ + Y + */ + num_N = 0; /* number of non-metal neighbors connected by a double bond */ + num_OH = 0; /* number of neighbors OH connected by a single bond */ + num_OM = 0; /* number of charged neighbors O connected by a single bond */ + num_O = 0; /* number of neighbors =O connected by a double bond */ + num_other = 0; + + for (i1 = 0; i1 < a->valence; i1++) + { + n1 = (int) a->neighbor[i1]; + if (is_el_a_metal( at[n1].el_number )) + { + continue; + } + + bond_type = ( a->bond_type[i1] & BOND_TYPE_MASK ); + + if (BOND_TYPE_DOUBLE == bond_type) + { + num_N++; + n2 = n1; + i2 = i1; + if (ion_el_group( at[n1].el_number ) == EL_NUMBER_O) + { + num_O++; + } + } + else if (BOND_TYPE_SINGLE == bond_type && + 1 == nNoMetalNumBonds( at, n1 ) && + 1 == nNoMetalBondsValence( at, n1 ) && + ion_el_group( at[n1].el_number ) == EL_NUMBER_O) + { + if (0 == at[n1].charge) + { + num_OH++; + n3 = n1; + i3 = i1; /* djb-rwth: ignoring LLVM warning: variable used */ + } + else + { + num_OM++; + } + } + else + { + num_other++; + /* djb-rwth: removing redundant code */ + i4 = i1; + } + } /* for (i1 = */ + + if (1 == num_N && 1 == num_O && 1 == num_OH + num_OM) + { + if (1 == num_other) + { + /* type 1: fix the single bond S-X */ + iedge = pBNS->vert[i].iedge[i4]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; + num_changes++; + } + } + else if (1 == num_N && !num_OH && !num_OM) + { + int bFound = 0; /* flag */ + int bDoNotFixAnyBond = 0; /* flag */ + /* Avoid case N=S-NH or N=S-N(-); N = N, P, As, Sb */ + if (ion_el_group( at[n2].el_number ) == EL_NUMBER_N) + { + U_CHAR el_number = at[n2].el_number; + for (i1 = 0; i1 < a->valence; i1++) + { + n1 = (int) a->neighbor[i1]; + bond_type = ( a->bond_type[i1] & BOND_TYPE_MASK ); + if (BOND_TYPE_SINGLE == bond_type && + ( NUMH( at, n1 ) || -1 == at[n1].charge ) && + el_number == at[n1].el_number) + { + i3 = i1; /* djb-rwth: ignoring LLVM warning: variable used */ + n3 = n1; + bFound++; + } + } + } + /* Exception: check if Z==X and they belong to the same ring system */ + for (i1 = 0; i1 < a->valence; i1++) + { + if (i1 != i2) + { + n1 = (int) a->neighbor[i1]; + if (at[n2].el_number == at[n1].el_number && + at[n2].nRingSystem == at[n1].nRingSystem) + { + bDoNotFixAnyBond++; + } + } + } + if (bDoNotFixAnyBond) + { + ; /* do nothing */ + } + else if (bFound) + { + if (1 == bFound && + 0 <= ( i4 = nNoMetalOtherNeighIndex2( at, i, n2, n3 ) )) + { + /* fix bond i4 */ + iedge = pBNS->vert[i].iedge[i4]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; + num_changes++; + } + } + else + { + /* fix the double bond >S=X */ + iedge = pBNS->vert[i].iedge[i2]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; + num_changes++; + /* -- test later -- + if ( 2 == nNoMetalNumBonds( at, n2 ) && + 0 <= ( i3 = nNoMetalOtherNeighIndex( at, n2, i ) ) ) { + iedge = pBNS->vert[n2].iedge[i3]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; + num_changes ++; + } + -------------------*/ + } + } + } + + else if (!a->charge && !a->radical && + 4 <= a->chem_bonds_valence + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && + 0 == num_of_H( at, i ) && + 4 == nNoMetalBondsValence( at, i ) + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && + a->el_number != EL_NUMBER_O && ion_el_group( a->el_number ) == EL_NUMBER_O && + 4 == nNoMetalNumBonds( at, i )) + { + /* Found S(VI), no H, two double bonds or one triple bond */ + /* O + || + in O=S--Y- (X, Y -- non-terminal) fix single bonds S-X, S-Y (type 1) + \ + X-- + + O + || + in O=S--O(-) (X -- non-terminal) fix single bond S-X (type 2) + \ + X-- + + O + || + in O=S--OH (X -- non-terminal) fix single bond S-X (type 3) + \ + X-- + + */ + int iN[4]; /* indexes of non-terminal neighbors connected by a single bond */ + num_N = 0; /* number of non-metal neighbors connected by a double bond */ + num_OH = 0; /* number of neighbors OH connected by a single bond */ + num_OM = 0; /* number of non-terminal neighbors connected by a single bond */ + num_O = 0; /* number of neighbors =O connected by a double bond */ + num_X = 0; /* number of terminal atom X != O connected by a single bond */ + num_other = 0; + for (i1 = 0; i1 < a->valence; i1++) + { + n1 = (int) a->neighbor[i1]; + if (is_el_a_metal( at[n1].el_number )) + { + continue; + } + bond_type = ( a->bond_type[i1] & BOND_TYPE_MASK ); + if (BOND_TYPE_DOUBLE == bond_type) + { + num_N++; + if (( 0 == at[n1].charge +#if ( S_VI_O_PLUS_METAL_FIX_BOND == 1 ) + || (1 == at[n1].charge && 2 == at[n1].valence) /* djb-rwth: addressing LLVM warning */ +#endif + ) && + 0 == at[n1].radical && + 0 == num_of_H( at, n1 ) && + ion_el_group( at[n1].el_number ) == EL_NUMBER_O && + 1 == nNoMetalNumBonds( at, n1 )) + { + num_O++; + } + } + else if (BOND_TYPE_SINGLE == bond_type && + 1 == nNoMetalNumBonds( at, n1 ) && + ion_el_group( at[n1].el_number ) == EL_NUMBER_O && + 1 >= num_of_H( at, n1 ) && + 1 == ( ( 0 == at[n1].charge ) && 1 == num_of_H( at, n1 ) ) + + ( ( -1 == at[n1].charge ) && 0 == num_of_H( at, n1 ) )) + { + num_OH++; /* -OH or -O(-) */ + } + else if (BOND_TYPE_SINGLE == bond_type && + 1 < nNoMetalNumBonds( at, n1 )) + { + iN[num_OM++] = i1; /* non-terminal neighbor connected by a single bond */ + } + else if (BOND_TYPE_SINGLE == bond_type && + 1 == nNoMetalNumBonds( at, n1 )) + { + num_X++; /* other terminal neighbor connected by a single bond */ + } + else + { + num_other++; + } + } + if (num_N == num_O && 2 == num_O && 2 == num_OH + num_OM + num_X && 0 == num_other) + { + for (i2 = 0; i2 < num_OM; i2++) + { + i1 = iN[i2]; + /* fix bond i1 */ + iedge = pBNS->vert[i].iedge[i1]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; + num_changes++; + } + } + } + + else if (!a->charge && !a->radical && + 6 <= a->chem_bonds_valence + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && + 0 == num_of_H( at, i ) && + 6 == nNoMetalBondsValence( at, i ) + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && + a->el_number != EL_NUMBER_O && ion_el_group( a->el_number ) == EL_NUMBER_O && + 5 == nNoMetalNumBonds( at, i )) + { + /* Found S(VIII), no H, three double bonds or two triple bond */ + /* + + O + || + in O=S--Y-- (X, Y -- non-terminal) fix single bond S-X, S-Y (type 4) + //\ + O X-- + + note: this structure is a mistakenly drawn structure + + O O + || || + O=S--O--Y-- or O=S--Y-- + \ \ + X-- O--X-- + + + */ + int iN[5]; /* indexes of non-terminal neighbors connected by a single bond */ + num_N = 0; /* number of non-metal neighbors connected by a double bond */ + num_OH = 0; /* number of neighbors OH connected by a single bond */ + num_OM = 0; /* number of non-terminal neighbors connected by a single bond */ + num_O = 0; /* number of neighbors =O connected by a double bond */ + num_X = 0; /* number of terminal atom X != O connected by a single bond */ + num_other = 0; + for (i1 = 0; i1 < a->valence; i1++) + { + n1 = (int) a->neighbor[i1]; + if (is_el_a_metal( at[n1].el_number )) + { + continue; + } + bond_type = ( a->bond_type[i1] & BOND_TYPE_MASK ); + if (BOND_TYPE_DOUBLE == bond_type) + { + num_N++; + if (( 0 == at[n1].charge +#if ( S_VI_O_PLUS_METAL_FIX_BOND == 1 ) + || (1 == at[n1].charge && 2 == at[n1].valence) /* djb-rwth: addressing LLVM warning */ +#endif + ) + && 0 == at[n1].radical && + 0 == num_of_H( at, n1 ) && + ion_el_group( at[n1].el_number ) == EL_NUMBER_O && + 1 == nNoMetalNumBonds( at, n1 )) + { + num_O++; + } + } + else if (BOND_TYPE_SINGLE == bond_type && + 1 == nNoMetalNumBonds( at, n1 ) && + ion_el_group( at[n1].el_number ) == EL_NUMBER_O && + 1 >= num_of_H( at, n1 ) && + 1 == ( ( 0 == at[n1].charge ) && 1 == num_of_H( at, n1 ) ) + + ( ( -1 == at[n1].charge ) && 0 == num_of_H( at, n1 ) )) + { + num_OH++; /* -OH or -O(-) */ + } + else + { + if (BOND_TYPE_SINGLE == bond_type && + 1 < nNoMetalNumBonds( at, n1 )) + { + + iN[num_OM++] = i1; /* non-terminal neighbor connected by a single bond */ + } + else + { + if (BOND_TYPE_SINGLE == bond_type && 1 == nNoMetalNumBonds( at, n1 )) + { + + num_X++; /* other terminal neighbor connected by a single bond */ + } + else + { + num_other++; + } + } + } + } + if (num_N == num_O && 3 == num_O && 2 == num_OH + num_OM + num_X && 0 == num_other) + { + for (i2 = 0; i2 < num_OM; i2++) + { + i1 = iN[i2]; + /* fix bond i1 */ + iedge = pBNS->vert[i].iedge[i1]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; + num_changes++; + } + } + } + + } /* for (i = */ + + return num_changes; +} + + +/****************************************************************************/ +int fix_explicitly_indicated_bonds( int nebend, + int *ebend, + BN_STRUCT *pBNS, + inp_ATOM *at, + int num_atoms ) +{ + int i, num_changes = 0; + inp_ATOM *a; + int j, ia1, ia2, i1 = -1, i2 = -1, index = -1, neigh; + BNS_IEDGE iedge; + S_CHAR edge_forbidden_mask = BNS_EDGE_FORBIDDEN_MASK; + pBNS->edge_forbidden_mask |= edge_forbidden_mask; + + if (nebend < 1 || !ebend) + { + return 0; + } + + for (j = 0; j < nebend; j += 2) + { + + ia1 = ebend[2 * j]; + ia2 = ebend[2 * j + 1]; + + for (i = 0; i < num_atoms; i++) + { + if (at[i].orig_at_number == ia1) + { + i1 = i; + } + else if (at[i].orig_at_number == ia2) + { + i2 = i; + } + if (i1 > 0 && i2 > 0) + { + break; + } + } + + if (i1 < 0 || i2 < 0) + { + return 0; + } + + if (i2 < i1) + { + int tmp = i1; i1 = i2; i2 = tmp; + } + + a = at + i1; + for (i = 0; i < a->valence; i++) + { + neigh = (int) a->neighbor[i]; + if (neigh == i2) + { + index = i; break; + } + } + if (index > -1) + { + iedge = pBNS->vert[i].iedge[index]; + pBNS->edge[iedge].forbidden |= edge_forbidden_mask; + num_changes++; + } + } + + return num_changes; +} + + + + +#define ALL_NONMETAL_Z 0 + + +/****************************************************************************/ +int is_Z_atom( U_CHAR el_number ) +{ + switch ( el_number ) + { + case EL_NUMBER_C: /* fallthrough */ + case EL_NUMBER_N: + case EL_NUMBER_P: + case EL_NUMBER_AS: + case EL_NUMBER_SB: + case EL_NUMBER_S: + case EL_NUMBER_SE: + case EL_NUMBER_TE: + case EL_NUMBER_CL: + case EL_NUMBER_BR: + case EL_NUMBER_I: +#if ( ALL_NONMETAL_Z == 1 ) + case EL_NUMBER_B: + case EL_NUMBER_O: + case EL_NUMBER_SI: + case EL_NUMBER_GE: + case EL_NUMBER_F: + case EL_NUMBER_AT: +#endif + return 1; + default: + return 0; + } +} + + +/**************************************************************************** +Detect O==Z--X, O=O,S,Se,Te +****************************************************************************/ +int IsZOX( inp_ATOM *atom, int at_x, int ord ) +{ + inp_ATOM *at_Z = atom + atom[at_x].neighbor[ord]; + + int i, neigh, num_O; + + for (i = 0, num_O = 0; i < at_Z->valence; i++) + { + neigh = at_Z->neighbor[i]; + if (neigh == at_x) + { + continue; + } + if (atom[neigh].valence == 1 && + atom[neigh].chem_bonds_valence == 2 && + atom[neigh].charge == 0 && + atom[neigh].radical == 0 && + ( atom[neigh].el_number == EL_NUMBER_O || + atom[neigh].el_number == EL_NUMBER_S || + atom[neigh].el_number == EL_NUMBER_SE || + atom[neigh].el_number == EL_NUMBER_TE )) + { + num_O++; + } + } + + return num_O; +} + +#if ( FIX_RENUM_BUG_FOR_CASE_OF_ACIDIC_OH_AT_P_PLUS == 1 ) +void update_some_attype_totals(int nAtTypeTotals[], int mask, int delta, S_CHAR at_charge); +/****************************************************************************/ +void update_some_attype_totals(int nAtTypeTotals[], int mask, int delta, S_CHAR at_charge) +{ + int i; + int32_t bit; /* djb-rwth: fixing coverity CID #499534 */ + if (nAtTypeTotals) + { + if (mask && !(mask & (ATBIT_Errors))) + { + for (i = 0, bit = 1; i < ATTOT_ARRAY_LEN; i++, bit <<= 1) + { + if (bit & mask) + { + nAtTypeTotals[i] += delta; + } + } + } + /* Count charges */ + if (at_charge) + { + nAtTypeTotals[ATTOT_TOT_CHARGE] += delta * at_charge; + nAtTypeTotals[ATTOT_NUM_CHARGES] += delta; + } + } + return; +} +#endif +/****************************************************************************/ +int GetAtomChargeType( inp_ATOM *atom, + int at_no, + int nAtTypeTotals[], + int *pMask, + int bSubtract ) +{ + + inp_ATOM *at = atom + at_no; +#if ( FIX_NORM_BUG_ADD_ION_PAIR == 1 ) + int i, neigh, mask, type, num_z, num_m, num_o, delta = bSubtract > 0 ? -1 : 1; /* 0 or -2 => add, 1 or 2 => subtract */ + int32_t bit; /* djb-rwth: fixing coverity CID #499579 */ + int bNoAdjIon = ( bSubtract == 0 || bSubtract == 1 ); +#else + int i, neigh, mask, bit, type, num_z, num_m, num_o, delta = bSubtract ? -1 : 1; +#endif + int bUnsatNHasTerminalO = 0; + + type = ATT_NONE; + mask = 0; + + if (at->radical && at->radical != RADICAL_SINGLET) + { + goto exit_function; + } + + if (is_el_a_metal( at->el_number )) + { + goto exit_function; + } + if (at->charge < -1 || at->charge > 1) + { + goto exit_function; + } + + if (!at->valence && at->charge == 1 && !at->num_H && !at->radical && at->el_number == EL_NUMBER_H) + { + /* a proton H+ (#1) */ + type = ATT_PROTON; + mask = ATBIT_Proton; + goto count_mask_bits; + } + + if ( !at->valence && at->charge == -1 && + !at->num_H && !at->radical && + ( at->el_number == EL_NUMBER_F || at->el_number == EL_NUMBER_CL || + at->el_number == EL_NUMBER_BR || at->el_number == EL_NUMBER_I ) + ) + { + /* a halogen anion Hal- (#2) */ + type = ATT_HalAnion; + mask = ATBIT_HalAnion; + goto count_mask_bits; + } +#if ( HAL_ACID_H_XCHG == 1 ) + /* halogen/chalcogen acid */ + if ((!at->valence && at->charge == 0 && 1 == at->num_H && !at->radical && + ( at->el_number == EL_NUMBER_F || + at->el_number == EL_NUMBER_CL || + at->el_number == EL_NUMBER_BR || + at->el_number == EL_NUMBER_I )) || + (!at->valence && at->charge == 0 && 2 == at->num_H && !at->radical && + ( at->el_number == EL_NUMBER_O || + at->el_number == EL_NUMBER_S || + at->el_number == EL_NUMBER_SE || + at->el_number == EL_NUMBER_TE )) /* djb-rwth: addressing LLVM warning */ + ) + { + /* a halogen/chalcogen acid (#3) */ + type = ATT_HalAcid; + mask = ATBIT_HalAcid; + goto count_mask_bits; + } +#endif + + if (detect_unusual_el_valence( at->el_number, at->charge, at->radical, + at->chem_bonds_valence, at->num_H, at->valence )) + { + goto exit_function; /* unusual valence state */ + } + + /* Check neighbors */ + for (i = 0, num_z = 0, num_m = 0, num_o = 0; i < at->valence; i++) + { + neigh = at->neighbor[i]; +#if ( FIX_NORM_BUG_ADD_ION_PAIR == 1 ) + if (atom[neigh].charge < -1 || atom[neigh].charge > 1) + { + goto exit_function; /* neighboring charge */ + } + if (atom[neigh].charge && at->charge) + { + if (bNoAdjIon) + { +#if ( FIX_RENUM_BUG_FOR_CASE_OF_ACIDIC_OH_AT_P_PLUS == 1 ) + goto count_mask_bits; + /*update_some_attype_totals(nAtTypeTotals, mask, delta, at->charge);*/ +#endif + goto exit_function; /* neighboring charge */ + } + type = ATT_NONE; + mask = 0; + goto count_mask_bits; + } +#else + if (atom[neigh].charge < -1 || atom[neigh].charge > 1 || atom[neigh].charge && at->charge) + { + goto exit_function; /* neighboring charge */ + } +#endif + if (detect_unusual_el_valence( atom[neigh].el_number, atom[neigh].charge, atom[neigh].radical, + atom[neigh].chem_bonds_valence, atom[neigh].num_H, + atom[neigh].valence )) + { + /* neighbor in unusual valence state */ + goto exit_function; + } + if (is_Z_atom( atom[neigh].el_number )) + { + num_z++; + } + if (is_el_a_metal( atom[neigh].el_number )) + { + num_m++; + } + num_o += ( atom[neigh].el_number == EL_NUMBER_O ); + if (at->el_number == EL_NUMBER_N && at->valence == 2 && !at->charge && + /*at->valence < at->chem_bonds_valence &&*/ + atom[neigh].valence == 1 && atom[neigh].chem_bonds_valence == 2 && + ( atom[neigh].el_number == EL_NUMBER_O || + atom[neigh].el_number == EL_NUMBER_S || + atom[neigh].el_number == EL_NUMBER_SE || + atom[neigh].el_number == EL_NUMBER_TE )) + { + bUnsatNHasTerminalO++; + } + } /* eof check neighbors */ + + /* O, S, Se, Te */ + if ( at->el_number == EL_NUMBER_O || + at->el_number == EL_NUMBER_S || + at->el_number == EL_NUMBER_SE || + at->el_number == EL_NUMBER_TE ) + { + if (at->charge == 1) + { + if (at->num_H) + { + /* #4 */ + type = ATT_O_PLUS; + mask |= ATBIT_OH_Plus; + } + else + { + /* #5 */ + type = ATT_O_PLUS; + mask |= ATBIT_O_Plus; + } + } + else + { + /* at->charge != 1 */ + if (at->valence > 1) + { + goto exit_function; /* not a terminal atom #C1 */ + } + else + { + if (at->valence && !( num_z || num_o )) + { + if (num_m == at->valence) + { + goto exit_function; /* #C2 */ + } + goto count_mask_bits; /* #C3 count charges, no donor or acceptor found */ + } + else + { + /* Here at->neigh[0] is one of: O, or Z={C, N, P, As, Sb, S, Se, Te, Cl, Br, I} */ + if (at->valence) + { + neigh = at->neighbor[0]; /* Z or O only */ + if (!atom[neigh].charge && atom[neigh].el_number == EL_NUMBER_C && + atom[neigh].chem_bonds_valence > atom[neigh].valence) + { + /* =C-OH, #C-OH, =C-O(-), #C-O(-), -C=O, =C=O; O = O, S, Se, Te */ + type = ATT_ACIDIC_CO; + if (at->num_H == 1) + { + mask |= ( ATBIT_COH ); /* #6: =C-OH, #C-OH; O=O,S,Se,Te */ + /*nAtTypeTotals[ATTOT_NUM_COH] ++;*/ + } + else + { + if (at->charge == -1) + { + mask |= ( ATBIT_CO_Minus ); /* #7: =C-O(-), #C-O(-); O=O,S,Se,Te */ + /*nAtTypeTotals[ATTOT_NUM_CO_Minus] ++;*/ + } + else + { + if (!at->num_H && !at->charge) + { + mask |= ( ATBIT_CO ); /* #8 -C=O, =C=O; O=O,S,Se,Te */ + /*nAtTypeTotals[ATTOT_NUM_CO] ++;*/ + } + else + { + mask |= ( ATBIT_Errors ); + /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ + } + } + } + } + else + { + if (!atom[neigh].charge && + ( atom[neigh].el_number == EL_NUMBER_O || + atom[neigh].el_number == EL_NUMBER_S || + atom[neigh].el_number == EL_NUMBER_SE || + atom[neigh].el_number == EL_NUMBER_TE ) && + atom[neigh].chem_bonds_valence == atom[neigh].valence) + { + /* -O-OH, -O-O(-); O = O, S, Se, Te */ + type = ATT_OO; + if (at->num_H == 1) + { + mask |= ( ATBIT_OOH ); /* #9 -O-OH */ + /*nAtTypeTotals[ATTOT_NUM_OOH] ++;*/ + } + else + { + if (at->charge == -1) + { + mask |= ( ATBIT_OO_Minus ); /* #10 -O-O(-) */ + /*nAtTypeTotals[ATTOT_NUM_OO_Minus] ++;*/ + } + else + { + mask |= ( ATBIT_Errors ); + /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ + } + } + } + else + { + if (!atom[neigh].charge && + atom[neigh].chem_bonds_valence == atom[neigh].valence && + atom[neigh].el_number == EL_NUMBER_C && + at->el_number != EL_NUMBER_O) + { + /* >C-S(-), >C-SH; S = S, Se, Te */ + type = ATT_ACIDIC_S; + if (at->num_H == 1) + { + mask |= ( ATBIT_CSH ); /* #11: >C-SH, >CH-SH, -CH2-SH; S = S, Se, Te */ + /*nAtTypeTotals[ATTOT_NUM_CSH] ++;*/ + } + else + { + if (at->charge == -1) + { + mask |= ( ATBIT_CS_Minus ); /* #12: >C-S(-), >CH-S(-), -CH2-S(-); S = S, Se, Te */ + /*nAtTypeTotals[ATTOT_NUM_CS_Minus] ++;*/ + } + else + { + mask |= ( ATBIT_Errors ); + /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ + } + } + } + else + { + if (atom[neigh].el_number == EL_NUMBER_N && + atom[neigh].valence == 2 && + ( !atom[neigh].num_H || (atom[neigh].num_H == 1 && atom[neigh].charge == 1) )) /* djb-rwth: addressing LLVM warning */ + { + /* N or N(-) or NH(+) neighbor */ + type = ATT_NO; /* single bond only */ + if (at->num_H == 1) + { + mask |= ( ATBIT_NOH ); /* #13: =N-OH, =NH(+)-OH, #N(+)-OH, -N(-)-OH; O = O, S, Se, Te */ + /*nAtTypeTotals[ATTOT_NUM_NOH] ++;*/ + } + else + { + if (at->charge == -1) + { + mask |= ( ATBIT_NO_Minus ); /* #14: =N-O(-); O = O, S, Se, Te */ + /*nAtTypeTotals[ATTOT_NUM_NO_Minus] ++;*/ + } + else + { + if (atom[neigh].charge == 1 || atom[neigh].charge == 0) + { + mask |= ( ATBIT_NO ); /* #15: =N(+)=O, -NH(+)=O -N=O */ + /*nAtTypeTotals[ATTOT_NUM_NO] ++;*/ + } + else + { + mask |= ( ATBIT_Errors ); + /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ + } + } + } + } + else + { + if (atom[neigh].el_number == EL_NUMBER_N) + { + type = ATT_N_O; /* #16: single bond only */ + if (at->num_H == 1) + { + mask |= ( ATBIT_N_OH ); /* #16: -NH-OH, >N-OH or >N(+)charge == -1) + { + mask |= ( ATBIT_N_O_Minus ); /* #17: -NH-O(-), >N-O(-); O = O, S, Se, Te */ + /*nAtTypeTotals[ATTOT_NUM_NO_Minus] ++;*/ + } + else + { + if (atom[neigh].charge == 1) + { + mask |= ( ATBIT_N_O ); /* #18: >N(+)=O */ + /*nAtTypeTotals[ATTOT_NUM_NO] ++;*/ + } + else + { + mask |= ( ATBIT_Errors ); + /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ + } + } + } + } + else + { + if ( atom[neigh].el_number != EL_NUMBER_C && + atom[neigh].el_number != EL_NUMBER_O && + !is_el_a_metal( atom[neigh].el_number ) && + atom[neigh].chem_bonds_valence > atom[neigh].valence) + { + /* =Z-OH, #Z-OH, =Z-O(-), #Z-O(-), -Z=O, =Z=O; + =Z(+)-OH, #Z(+)-OH, =Z-O(-), #Z-O(-), -Z(+)=O, =Z(+)=O; O = O, S, Se, Te */ + /* neigh = Z\{N,C} = P, As, Sb, S, Se, Te, Cl, Br, I */ + if (at->chem_bonds_valence == 1 && IsZOX( atom, at_no, 0 )) + { + type = ATT_ZOO; + if (at->num_H == 1) + { + mask |= ( ATBIT_ZOOH ); /* 18: O=Z-OH; O=O,S,Se,Te; Z may have charge */ + /*nAtTypeTotals[ATTOT_NUM_ZOOH] ++;*/ + } + else + { + if (at->charge == -1) + { + mask |= ( ATBIT_ZOO_Minus ); /* 19: O=Z-O(-); O = O, S, Se, Te */ + /*nAtTypeTotals[ATTOT_NUM_ZOO_Minus] ++;*/ + } + else + { + mask |= ( ATBIT_Errors ); + /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ + } + } + } + else + { + type = ATT_OTHER_ZO; + if (at->num_H == 1) + { + mask |= ( ATBIT_ZOH ); /* 20: =Z-OH, #Z-OH; O=O,S,Se,Te; Z may have charge */ + /*nAtTypeTotals[ATTOT_NUM_ZOH] ++;*/ + } + else + { + if (at->charge == -1) + { + mask |= ( ATBIT_ZO_Minus ); /* 21: =Z-O(-), #Z-O(-); O = O, S, Se, Te */ + /*nAtTypeTotals[ATTOT_NUM_ZO_Minus] ++;*/ + } + else + { + if (at->num_H == 0) + { + mask |= ( ATBIT_ZO ); /* 22: -Z=O, =Z=O; O=O,S,Se,Te; Z may have charge */ + /*nAtTypeTotals[ATTOT_NUM_ZO] ++;*/ + } + else + { + mask |= ( ATBIT_Errors ); + /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ + } + } + } + } + } + else + { + if (at->charge == -1 && !is_el_a_metal( atom[neigh].el_number )) + { + /* >Z-O(-); O=O,S,Se,Te */ + type = ATT_OTHER_NEG_O; + mask |= ( ATBIT_O_Minus ); /* 23: -Z-O(-); O=O,S,Se,Te */ + /*nAtTypeTotals[ATTOT_NUM_ZO_Minus] ++;*/ + } + } + } + } + } + } + } + } + + else + { + if (at->charge == -1 && at->num_H == 1) + { + type = ATT_OH_MINUS; + mask |= ( ATBIT_O_Minus ); /* 25: HO(-); O=O,S,Se,Te */ + } + } + } + } + } + } + + else + { + /* P, N, neutral valence = 3 (not 5) */ + if (( at->el_number == EL_NUMBER_N || + at->el_number == EL_NUMBER_P ) && + 0 <= at->valence && at->valence <= 3 && + at->chem_bonds_valence + at->num_H == 3 + at->charge) + { + if (at->valence && !( num_z /*|| num_o == at->valence*/ )) + { + if (num_m == at->valence) + { + goto exit_function; + } + goto count_mask_bits; /* N(III), N(-)(II), N(+)(IV) and same P that have only oxygen neighbors are ignored here */ + } + type = ( at->el_number == EL_NUMBER_N ) ? ATT_ATOM_N : ATT_ATOM_P; + switch (at->charge) + { + case -1: + if (at->el_number == EL_NUMBER_N) + { + mask |= ( ATBIT_N_Minus ); /* 26: -NH(-), =N(-), >N(-) */ + if (at->num_H) + { + mask |= ( ATBIT_NP_H ); /* 27: -NH(-) */ + } +#if ( FIX_NP_MINUS_BUG == 1 ) + else + { + if (at->valence == 1 && at->chem_bonds_valence >= 2 && ( at->bond_type[0] & BOND_MARK_ALL )) + { + type |= ATT_NP_MINUS_V23; /* =N(-) created by normalization 2010-03-11 DT */ + } + } +#endif + } + /*nAtTypeTotals[ATTOT_NUM_N_Minus] += (at->el_number == EL_NUMBER_N);*/ + break; + case 0: + if (at->num_H) + { + mask |= ( ATBIT_NP_H ); /* 28: -NH2, =NH, >NH */ + /*nAtTypeTotals[ATTOT_NUM_NP_H] ++;*/ + } + else + { + if (bUnsatNHasTerminalO == 1) + { + mask |= ( ATBIT_ON ); /* 29: -N=O,-N=OH(+) only, not =N-OH */ + } + else + { + mask |= ( ATBIT_NP ); /* 30: -P=O,-P=OH(+), >N- =N- (incl. =N-OH) , #N */ + /*nAtTypeTotals[ATTOT_NUM_NP] ++;*/ + } + } + break; /* ignore neutral N or P */ + case 1: + if (at->num_H) + { + mask |= ( ATBIT_NP_Proton ); /* 31: NH4(+), -NH3(+), =NH2(+), >NH2(+), =NH(+)-, >NH(+)-, #NH(+) */ + /*nAtTypeTotals[ATTOT_NUM_NP_Proton] ++;*/ + } + else + { + if (at->chem_bonds_valence > at->valence) + { + mask |= ( ATBIT_NP_Plus ); /* =N(+)=, #N(+)-, =N(+)< */ + /*nAtTypeTotals[ATTOT_NUM_NP_Plus] ++;*/ + } + else + { + type = 0; /* 32: ignore onium cations >N(+)< */ + } + } + break; + default: + mask |= ( 1 << ATTOT_NUM_Errors ); + /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ + break; + } + } + } + +count_mask_bits: + if (nAtTypeTotals) + { + if (mask && !( mask & ( ATBIT_Errors ) )) + { + for (i = 0, bit = 1; i < ATTOT_ARRAY_LEN; i++, bit <<= 1) + { + if (bit & mask) + { + nAtTypeTotals[i] += delta; + } + } + } + + /* Count charges */ + if (at->charge) + { + nAtTypeTotals[ATTOT_TOT_CHARGE] += delta * at->charge; + nAtTypeTotals[ATTOT_NUM_CHARGES] += delta; + } + } + + if (pMask) + { + *pMask = mask; + } + +exit_function: + if (mask & ( ATBIT_Errors )) + { + type = 0; + if (nAtTypeTotals) + { + nAtTypeTotals[ATTOT_NUM_Errors] += 1; + } + } + + + return type; +} + + +/****************************************************************************/ +int SimpleRemoveHplusNPO( inp_ATOM *at, + int num_atoms, + int nAtTypeTotals[], + T_GROUP_INFO *t_group_info ) +{ + int i, mask, type, num_removed; + for (i = 0, num_removed = 0; i < num_atoms; i++) + { + /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + if (( PR_SIMPLE_TYP & ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) ) ) && + ( PR_SIMPLE_MSK & mask )) + { +#if ( bRELEASE_VERSION == 0 ) + if (at[i].charge != 1 || at[i].num_H == 0) + { + return -1; /* program error */ + } +#endif + type = GetAtomChargeType(at, i, nAtTypeTotals, &mask, 1); /* subtract at[i] */ /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + at[i].charge = 0; + AddOrRemoveExplOrImplH( -1, at, num_atoms, (AT_NUMB) i, t_group_info ); + /*at[i].num_H --;*/ + num_removed++; +#if ( FIX_NORM_BUG_ADD_ION_PAIR == 1 ) + type = GetAtomChargeType(at, i, nAtTypeTotals, &mask, 0); /* add changed at[i] */ /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ +#else + type = GetAtomChargeType(at, i, nAtTypeTotals, &mask, 1); /* bug: subtract instead of add */ /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ +#endif + /* + if ( nAtTypeTotals ) { + nAtTypeTotals[ATTOT_NUM_NP_Proton] --; + if ( at[i].num_H ) { + nAtTypeTotals[ATTOT_NUM_NP_H] ++; + } else { + nAtTypeTotals[ATTOT_NUM_NP] ++; + } + nAtTypeTotals[ATTOT_TOT_CHARGE] --; + nAtTypeTotals[ATTOT_NUM_CHARGES] --; + } + */ + } + } + + return num_removed; +} + + +/****************************************************************************/ +int bIsAtomTypeHard( inp_ATOM *at, + int endpoint, + int nType, + int nMask, + int nCharge ) +{ + int mask; + if (( nType & GetAtomChargeType( at, endpoint, NULL, &mask, 0 ) ) && ( mask & nMask ) +#if ( OPPOSITE_CHARGE_IN_CGROUP == 0 ) + && ( at[endpoint].charge == nCharge || !at[endpoint].charge ) +#endif + ) + { + return 1; + } + + return 0; +} + + +/****************************************************************************/ +int bIsHDonorAccAtomType( inp_ATOM *at, int endpoint, int *cSubType ) +{ + if (bIsAtomTypeHard( at, endpoint, PR_HARD_TYP_H, PR_HARD_MSK_H, 0 )) + { + /* Obtain donor/acceptor info */ + int neutral_valence = at[endpoint].chem_bonds_valence + at[endpoint].num_H - at[endpoint].charge; + if (neutral_valence != 2 /* O, S, Se, Te */ && + neutral_valence != 3 /* N, P */) + { + return -1; /* wrong endpoint neutral valence */ + } + else + { + int edge_flow = at[endpoint].num_H; + int num_bonds = at[endpoint].valence; + int edge_cap = neutral_valence - num_bonds; /* does not allow to reduce -NH3(+) to #N or -OH(+)- to -O- */ + edge_flow = inchi_min( edge_flow, edge_cap ); + /* what this means: */ + if (edge_cap) + { + if (edge_cap > edge_flow) + { + *cSubType |= SALT_ACCEPTOR; + } + if (edge_flow) + { + *cSubType |= SALT_DONOR_H; + } + return 4; + } + } + } + + return -1; +} + + +/****************************************************************************/ +int bIsNegAtomType( inp_ATOM *at, int endpoint, int *cSubType ) +{ + int sub_type = 0; + if (bIsAtomTypeHard( at, endpoint, PR_HARD_TYP_NEG, PR_HARD_MSK_NEG, -1 )) + { + /* Obtain donor/acceptor info */ + int neutral_valence = at[endpoint].chem_bonds_valence + at[endpoint].num_H - at[endpoint].charge; + if (neutral_valence != 2 /* O, S, Se, Te */ && + neutral_valence != 3 /* N, P */) + { + return -1; /* wrong endpoint neutral valence */ + } + else + { + int edge_flow = ( at[endpoint].charge == -1 ); + int num_bonds = at[endpoint].valence; + int edge_cap = neutral_valence - num_bonds - at[endpoint].num_H; /* does not allow to reduce -NH3(+) to #N or -OH(+)- to -O- */ + edge_flow = inchi_min( edge_flow, edge_cap ); + /* what this means: */ + if (edge_cap) + { + if (edge_cap > edge_flow) + { + sub_type |= SALT_ACCEPTOR; + } + if (edge_flow) + { + sub_type |= SALT_DONOR_Neg; + } + if (sub_type) + { + *cSubType |= sub_type; + return 4; + } + } + } + } + + return -1; +} + + +/****************************************************************************/ +int bIsHardRemHCandidate( inp_ATOM *at, int i, int *cSubType ) +{ + int ret1, ret2, ret; + int sub_type = 0; + ret1 = bIsHDonorAccAtomType( at, i, &sub_type ); + ret2 = bIsNegAtomType( at, i, &sub_type ); + ret = inchi_max( ret1, ret2 ); + if (ret > 0 && sub_type) + { + *cSubType |= sub_type; + return ret; + } + return -1; +} + + +/****************************************************************************/ +int CreateCGroupInBnStruct( inp_ATOM *at, + int num_atoms, + BN_STRUCT *pBNS, + int nType, + int nMask, + int nCharge ) +{ + int k, c_point, cg, centerpoint, fictpoint, type, ret = 0; + int num_cg = 1; + int num_edges = pBNS->num_edges; + int num_vertices = pBNS->num_vertices; /* new c-group bns-ID */ + BNS_VERTEX *vert_ficpoint, *ver_ficpont_prev; /* fictitious vertex describing charge c-group */ + BNS_VERTEX *vertex_cpoint; + BNS_EDGE *edge; /* edge between that vertex and the tautomeric c_point */ + int mask, num_CPoints; + + /* Debug: check overflow */ + if (num_vertices + num_cg >= pBNS->max_vertices) + { + return BNS_VERT_EDGE_OVFL; + } + + /* Count new c-group edges */ + for (c_point = 0, num_CPoints = 0; c_point < num_atoms; c_point++) + { + if (( nType & GetAtomChargeType( at, c_point, NULL, &mask, 0 ) ) && ( mask & nMask ) +#if ( OPPOSITE_CHARGE_IN_CGROUP == 0 ) + && ( at[c_point].charge == nCharge || !at[c_point].charge ) +#endif + ) + { + num_CPoints++; + } + } + + if (!num_CPoints) + { + return 0; + } + + /* Clear the new vertex */ + memset( pBNS->vert + num_vertices, 0, 1 * sizeof( pBNS->vert[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + + /* *old* Make sure the last t-group has the largest t-group ID: + this is necessary to correctly add new edges and vertices for testing augmenting paths + */ + + /**************************************/ + /* initialize new fictitious vertex */ + /* representing c-point group */ + /**************************************/ + + ver_ficpont_prev = pBNS->vert + num_vertices - 1; + + for (cg = 0; cg < num_cg; cg++, ver_ficpont_prev = vert_ficpoint) + { + /* + vert_ficpoint-1 is the last vertex; + vert_ficpoint is the being added vertex + Note: nGroupNumber are not contiguous + */ + vert_ficpoint = pBNS->vert + num_vertices + cg; + vert_ficpoint->iedge = ver_ficpont_prev->iedge + ver_ficpont_prev->max_adj_edges; + vert_ficpoint->max_adj_edges = num_CPoints + BNS_ADD_EDGES; + vert_ficpoint->num_adj_edges = 0; + vert_ficpoint->st_edge.flow = vert_ficpoint->st_edge.flow0 = 0; + vert_ficpoint->st_edge.cap = vert_ficpoint->st_edge.cap0 = 0; + vert_ficpoint->type = BNS_VERT_TYPE_C_GROUP | ( ( nCharge < 0 ) ? BNS_VERT_TYPE_C_NEGATIVE : 0 ); + } + + /************************************************/ + /* Connect c-points to the fictitious vertices */ + /* representing c-point groups; set caps, flows */ + /************************************************/ + cg = 1; + for (c_point = 0; c_point < num_atoms; c_point++) + { + if (( nType & ( type = GetAtomChargeType( at, c_point, NULL, &mask, 0 ) ) ) && ( mask & nMask ) +#if ( OPPOSITE_CHARGE_IN_CGROUP == 0 ) + && ( at[c_point].charge == nCharge || !at[c_point].charge ) +#endif + ) + { + ; + } + else + { + continue; + } + + fictpoint = cg + num_vertices - 1; /* c-group vertex index */ + vert_ficpoint = pBNS->vert + fictpoint; /* c-group vertex */ + vertex_cpoint = pBNS->vert + c_point; /* c_point vertex */ + + /* Debug: check overflow */ + if (fictpoint >= pBNS->max_vertices || + num_edges >= pBNS->max_edges || + vert_ficpoint->num_adj_edges >= vert_ficpoint->max_adj_edges || + vertex_cpoint->num_adj_edges >= vertex_cpoint->max_adj_edges) + { + /* djb-rwth: removing redundant code */ + break; + } + vertex_cpoint->type |= BNS_VERT_TYPE_C_POINT; + if (( KNOWN_ACIDIC_TYPE & type ) && nCharge < 0) + { + vertex_cpoint->type |= pBNS->type_TACN; + } + +#if ( FIX_CPOINT_BOND_CAP != 1 ) /* { */ + /* Set capacity = 1 to the edges from the c_point to the centerpoint(s) */ + /* if their current capacity is zero */ + /* the centerpoint is any adjacent atom that is adjacent to a multiple bond */ + for (k = 0; k < vertex_cpoint->num_adj_edges; k++) + { + int iedge = vertex_cpoint->iedge[k]; + if (!pBNS->edge[iedge].cap) + { + /* single bond, possibly between c_point and centerpoint */ + centerpoint = ( pBNS->edge[iedge].neighbor12 ^ c_point ); + if (centerpoint < pBNS->num_atoms && + pBNS->vert[centerpoint].st_edge.cap >= 1) + { + int bond_type = ( at[c_point].bond_type[k] & BOND_TYPE_MASK ); + if (bond_type == BOND_TAUTOM || + bond_type == BOND_ALTERN || + bond_type == BOND_SINGLE) + { + pBNS->edge[iedge].cap = 1; + } + } + } + } +#endif /* } FIX_CPOINT_BOND_CAP */ + + /* Create a new edge connecting c_point to the new fictitious c-group vertex vert_ficpoint */ + edge = pBNS->edge + num_edges; + edge->cap = 1; + edge->flow = 0; + edge->pass = 0; +#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) + edge->forbidden &= pBNS->edge_forbidden_mask; /* remove previous temporary ban */ +#endif + + /* nCharge = +1: mark edge to c-point having no (+)-moveable charge with flow=1 */ + /* nCharge = -1: mark edge to c-point having -1 moveable charge with flow=1 */ + + if ((nCharge == 1 && at[c_point].charge != 1) || (nCharge == -1 && at[c_point].charge == -1)) /* djb-rwth: addressing LLVM warning */ + /*if ( !CHARGED_CPOINT(at,c_point) )*/ + { + /* Increment new edge flow, update st_edges of the adjacent vertices */ + edge->flow++; + /* Increment c-group vertex st-flow & cap */ + vert_ficpoint->st_edge.flow++; + vert_ficpoint->st_edge.cap++; + /* Increment c-point vertex st-flow & cap */ + vertex_cpoint->st_edge.flow++; + vertex_cpoint->st_edge.cap++; + } + +#if ( FIX_CPOINT_BOND_CAP == 1 ) /* { */ + /* Set capacity = 1 to the edges from the c_point to the centerpoint(s) */ + /* if their current capacity is zero */ + /* the centerpoint is any adjacent atom that is adjacent to a multiple bond */ + for (k = 0; k < vertex_cpoint->num_adj_edges; k++) + { + int iedge = vertex_cpoint->iedge[k]; + VertexFlow nNewCap = vertex_cpoint->st_edge.cap; + centerpoint = ( pBNS->edge[iedge].neighbor12 ^ c_point ); + if (!pBNS->edge[iedge].cap) + { + /* Single bond, possibly between c_point and centerpoint */ + if (centerpoint < pBNS->num_atoms && + pBNS->vert[centerpoint].st_edge.cap >= 1) + { + nNewCap = inchi_min( pBNS->vert[centerpoint].st_edge.cap, nNewCap ); + nNewCap = inchi_min( nNewCap, MAX_BOND_EDGE_CAP ); + pBNS->edge[iedge].cap = nNewCap; + } + } +#if ( FIX_CPOINT_BOND_CAP2 == 1 ) /* multiple bond */ + else + { + if (centerpoint < pBNS->num_atoms && + edge->flow && pBNS->edge[iedge].cap < MAX_BOND_EDGE_CAP) + { + pBNS->edge[iedge].cap++; + } + } +#endif + } +#endif /* } FIX_CPOINT_BOND_CAP */ + + /* Connect edge to c_point and fictpoint and increment the counters of neighbors and edges */ + edge->neighbor1 = c_point; /* the smallest out of v1=endopoint and v2=num_vertices */ + edge->neighbor12 = c_point ^ fictpoint; /* v1 ^ v2 */ + vertex_cpoint->iedge[vertex_cpoint->num_adj_edges] = num_edges; + vert_ficpoint->iedge[vert_ficpoint->num_adj_edges] = num_edges++; + edge->neigh_ord[0] = vertex_cpoint->num_adj_edges++; + edge->neigh_ord[1] = vert_ficpoint->num_adj_edges++; + edge->cap0 = edge->cap; + edge->flow0 = edge->flow; + } + + ret = pBNS->num_vertices; /* new c-group atom number */ + pBNS->num_edges = num_edges; + pBNS->num_vertices += num_cg; + pBNS->num_c_groups += num_cg; + + return ret; +} + + +/****************************************************************************/ +int CreateTGroupInBnStruct( inp_ATOM *at, + int num_atoms, + BN_STRUCT *pBNS, + int nType, + int nMask ) +{ + int ret = 0; + /* ret = ReInitBnStruct( pBNS ); */ + int k, endpoint, tg, centerpoint, fictpoint; + int num_tg = 1; + int num_edges = pBNS->num_edges; + int num_vertices = pBNS->num_vertices; + BNS_VERTEX *vert_ficpoint, *ver_ficpont_prev; /* fictitious vertex describing t-group */ + BNS_VERTEX *vert_endpoint; + BNS_EDGE *edge; /* edge between that vertex and the tautomeric endpoint */ + int mask, num_endpoints, neutral_valence, edge_flow, edge_cap, num_bonds; + + /* Debug: check overflow */ + if (num_vertices + num_tg >= pBNS->max_vertices) + { + return BNS_VERT_EDGE_OVFL; + } + + /* Count new t-group edges */ + for (endpoint = 0, num_endpoints = 0; endpoint < num_atoms; endpoint++) + { + if (( nType & GetAtomChargeType( at, endpoint, NULL, &mask, 0 ) ) && ( mask & nMask ) + ) + { + num_endpoints++; + } + } + + if (!num_endpoints) + { + return 0; + } + + /* Since t-group IDs may be not contiguous, clear all vertices that will be added. + all-zeroes-vertex will be ignored by the BNS + */ + memset( pBNS->vert + num_vertices, 0, num_tg * sizeof( pBNS->vert[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + + /* *old* Make sure the last t-group has the largest t-group ID: + this is necessary to correctly add new edges and vertices for testing augmenting paths + */ + + /**************************************/ + /* Initialize new fictitious vertex */ + /* representing t-point group */ + /**************************************/ + ver_ficpont_prev = pBNS->vert + num_vertices - 1; + + for (tg = 0; tg < num_tg; tg++, ver_ficpont_prev = vert_ficpoint) + { + /* + vert_ficpoint-1 is the last vertex; + vert_ficpoint is the vertex that is being added + Note: nGroupNumber are not contiguous + */ + vert_ficpoint = pBNS->vert + num_vertices + tg; + vert_ficpoint->iedge = ver_ficpont_prev->iedge + ver_ficpont_prev->max_adj_edges; + vert_ficpoint->max_adj_edges = num_endpoints + BNS_ADD_EDGES + BNS_ADD_SUPER_TGROUP; + vert_ficpoint->num_adj_edges = 0; + vert_ficpoint->st_edge.flow = vert_ficpoint->st_edge.flow0 = 0; + vert_ficpoint->st_edge.cap = vert_ficpoint->st_edge.cap0 = 0; + vert_ficpoint->type |= BNS_VERT_TYPE_TGROUP; + } + + tg = 1; + for (endpoint = 0; endpoint < num_atoms; endpoint++) + { + if (( nType & GetAtomChargeType( at, endpoint, NULL, &mask, 0 ) ) && ( mask & nMask )) + { + ; + } + else + { + continue; + } + fictpoint = tg + num_vertices - 1; + vert_ficpoint = pBNS->vert + fictpoint; + vert_endpoint = pBNS->vert + endpoint; + /* Debug: check overflow */ + if (fictpoint >= pBNS->max_vertices || + num_edges >= pBNS->max_edges || + vert_ficpoint->num_adj_edges >= vert_ficpoint->max_adj_edges || + vert_endpoint->num_adj_edges >= vert_endpoint->max_adj_edges) + { + /* djb-rwth: removing redundant code */ + break; + } + + /* Obtain donor/acceptor info */ + neutral_valence = at[endpoint].chem_bonds_valence + at[endpoint].num_H - at[endpoint].charge; + if (neutral_valence != 2 /* O, S, Se, Te */ && + neutral_valence != 3 /* N, P */) + { + /* djb-rwth: removing redundant code */ + break; + } + edge_flow = at[endpoint].num_H; + num_bonds = at[endpoint].valence; + edge_cap = neutral_valence - num_bonds; /* does not allow to reduce -NH3(+) to #N or -OH(+)- to -O- */ + + if (3 == neutral_valence /* N or P */ && 1 < num_bonds) + { + edge_cap++; /* allow -NH2(+)- => -N=, >NH(+)- => >N- */ + } + edge_flow = inchi_min( edge_flow, edge_cap ); + /* + if ( !nGetEndpointInfo( at, endpoint, &eif ) ) { + ret = BNS_BOND_ERR; + break; + } + */ + vert_endpoint->type |= BNS_VERT_TYPE_ENDPOINT; + + /* Create a new edge connecting endpoint to the new fictitious t-group vertex vert_ficpoint */ + edge = pBNS->edge + num_edges; + edge->cap = edge_cap; + edge->flow = edge_flow; + edge->pass = 0; +#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) + edge->forbidden &= pBNS->edge_forbidden_mask; +#endif + + /* Adjust st_flow and st_cap of the adjacent vertices */ + /* Adjust t-group vertex st-flow & cap */ + vert_ficpoint->st_edge.flow += edge->flow; + vert_ficpoint->st_edge.cap += edge->flow; + /* adjust endpoint vertex st-flow & cap */ + vert_endpoint->st_edge.flow += edge->flow; + vert_endpoint->st_edge.cap += edge->flow; + + /* Adjust edge cap & flow according to the number of H and number of bonds */ + for (k = 0; k < vert_endpoint->num_adj_edges; k++) + { + int iedge = vert_endpoint->iedge[k]; + VertexFlow nNewCap = vert_endpoint->st_edge.cap; + if (!pBNS->edge[iedge].cap) + { + /* single bond, possibly between endpoint and centerpoint */ + centerpoint = ( pBNS->edge[iedge].neighbor12 ^ endpoint ); + if (centerpoint < pBNS->num_atoms && + pBNS->vert[centerpoint].st_edge.cap >= 1) + { + nNewCap = inchi_min( pBNS->vert[centerpoint].st_edge.cap, nNewCap ); + nNewCap = inchi_min( nNewCap, MAX_BOND_EDGE_CAP ); + pBNS->edge[iedge].cap = nNewCap; + } + } + } + + /* Connect edge to endpoint and fictpoint and increment the counters of neighbors and edges */ + edge->neighbor1 = endpoint; /* the smallest out of v1=endopoint and v2=num_vertices */ + edge->neighbor12 = endpoint ^ fictpoint; /* v1 ^ v2 */ + vert_endpoint->iedge[vert_endpoint->num_adj_edges] = num_edges; + vert_ficpoint->iedge[vert_ficpoint->num_adj_edges] = num_edges++; + edge->neigh_ord[0] = vert_endpoint->num_adj_edges++; + edge->neigh_ord[1] = vert_ficpoint->num_adj_edges++; + edge->cap0 = edge->cap; + edge->flow0 = edge->flow; + } + + ret = pBNS->num_vertices; /* new t-group atom number */ + pBNS->num_edges = num_edges; + pBNS->num_vertices += num_tg; + pBNS->num_t_groups += num_tg; + + return ret; +} + + +/****************************************************************************/ +int RemoveLastGroupFromBnStruct( inp_ATOM *at, + int num_atoms, + int tg, + BN_STRUCT *pBNS ) +{ + int ret = 0; + /* ret = ReInitBnStruct( pBNS ); */ + int k, endpoint, /*centerpoint, fictpoint,*/ iedge; + int num_edges = pBNS->num_edges; + int num_vertices = pBNS->num_vertices; + BNS_VERTEX *vert_ficpoint /*, *ver_ficpont_prev*/; /* fictitious vertex describing t-group */ + BNS_VERTEX *vert_endpoint; + BNS_EDGE *edge; /* edge between that vertex and the tautomeric endpoint */ + /*int mask, num_endpoints, neutral_valence, edge_flow, edge_cap, num_bonds;*/ + int is_t_group = 0, is_c_group = 0; + + /* Debug: check overflow */ + if (pBNS->num_added_atoms + pBNS->num_c_groups + pBNS->num_t_groups + num_atoms >= pBNS->max_vertices) + { + return BNS_VERT_EDGE_OVFL; + } + + if (tg + 1 != num_vertices) + { + return BNS_VERT_EDGE_OVFL; + } + + vert_ficpoint = pBNS->vert + tg; + + if (vert_ficpoint->type & BNS_VERT_TYPE_TGROUP) + { + is_t_group = 1; + } + if (vert_ficpoint->type & BNS_VERT_TYPE_C_GROUP) + { + is_c_group = 1; + if (vert_ficpoint->type & BNS_VERT_TYPE_C_NEGATIVE) + { + is_c_group = 2; + } + } + + for (k = vert_ficpoint->num_adj_edges - 1; 0 <= k; k--) + { + iedge = vert_ficpoint->iedge[k]; + if (iedge + 1 != num_edges) + { + return BNS_VERT_EDGE_OVFL; + } + edge = pBNS->edge + iedge; + endpoint = edge->neighbor12 ^ tg; + vert_endpoint = pBNS->vert + endpoint; + /* adjust st_flow, st_cap */ + vert_endpoint->st_edge.cap0 = + vert_endpoint->st_edge.cap -= edge->flow; + vert_endpoint->st_edge.flow0 = + vert_endpoint->st_edge.flow -= edge->flow; + if (pBNS->type_TACN && ( vert_endpoint->type & pBNS->type_TACN ) == pBNS->type_TACN) + { + vert_endpoint->type ^= pBNS->type_TACN; + } + if (is_t_group) + { + vert_endpoint->type ^= ( vert_ficpoint->type & BNS_VERT_TYPE_ENDPOINT ); + } + if (is_c_group) + { + vert_endpoint->type ^= ( vert_ficpoint->type & BNS_VERT_TYPE_C_POINT ); + } + /* Remove edge */ + if (edge->neigh_ord[0] + 1 != vert_endpoint->num_adj_edges) + { + return BNS_VERT_EDGE_OVFL; + } + vert_endpoint->num_adj_edges--; + memset( edge, 0, sizeof( *edge ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + num_edges--; + if (1 == is_t_group && endpoint < num_atoms) + { + at->endpoint = 0; + } + if (1 == is_c_group && endpoint < num_atoms) + { + at->c_point = 0; + } + } + memset( vert_ficpoint, 0, sizeof( *vert_ficpoint ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + num_vertices--; + + pBNS->num_edges = num_edges; + pBNS->num_vertices = num_vertices; + if (is_t_group) + { + pBNS->num_t_groups--; + } + if (is_c_group) + { + pBNS->num_c_groups--; + } + + return ret; +} + + + +/****************************************************************************/ +int SetInitCapFlowToCurrent( BN_STRUCT *pBNS ) +{ + int i, j; + BNS_EDGE *pEdge = NULL; + for (i = 0; i < pBNS->num_vertices; i++) + { + pBNS->vert[i].st_edge.flow0 = pBNS->vert[i].st_edge.flow; + pBNS->vert[i].st_edge.cap0 = pBNS->vert[i].st_edge.cap; + for (j = 0; j < pBNS->vert[i].num_adj_edges; j++) + { + pEdge = pBNS->edge + pBNS->vert[i].iedge[j]; + pEdge->cap0 = pEdge->cap; + pEdge->flow0 = pEdge->flow; + } + } + + return 0; +} + + +int ArTypMask[] = +{ + AR_SIMPLE_TYP1, + AR_SIMPLE_MSK1, + AR_SIMPLE_TYP2, + AR_SIMPLE_MSK2, + AR_SIMPLE_TYP3, + AR_SIMPLE_MSK3, + 0, + 0 +}; + + + +/****************************************************************************/ +int SimpleRemoveAcidicProtons( inp_ATOM *at, + int num_atoms, + BN_AATG *pAATG, + int num2remove ) +{ + int i, j, max_j = -1, mask, type, num_removed; + int num[AR_SIMPLE_STEPS + 1], num_tot; + + for (j = 0; ArTypMask[2 * j]; j++) + { + num[max_j = j] = 0; + } + + for (i = 0; i < num_atoms; i++) + { + if (!at[i].charge && at[i].num_H && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) + { + for (j = 0; j <= max_j; j++) + { + if (( type & ArTypMask[2 * j] ) && ( mask && ArTypMask[2 * j + 1] )) + { + num[j] ++; + break; + } + } + } + } + for (j = 0, num_tot = 0; j <= max_j; j++) + { + if (( num_tot += num[j] ) >= num2remove) + { + max_j = j; + break; + } + } + if (!num_tot) + { + return 0; + } + for (i = 0, num_removed = 0; i < num_atoms && num_removed < num2remove; i++) + { + if (!at[i].charge && at[i].num_H && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) + { + for (j = 0; j <= max_j; j++) + { + if (num[j] && ( type & ArTypMask[2 * j] ) && ( mask && ArTypMask[2 * j + 1] )) + { + /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + type = GetAtomChargeType(at, i, pAATG->nAtTypeTotals, &mask, 1); /* subtract at[i] */ + num[j] --; + at[i].charge--; + AddOrRemoveExplOrImplH( -1, at, num_atoms, (AT_NUMB) i, pAATG->t_group_info ); + /*at[i].num_H --;*/ + num_removed++; + type = GetAtomChargeType(at, i, pAATG->nAtTypeTotals, &mask, 0); /* add changed at[i] */ /* ! THIS CHANGES pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] */ + break; + } + } + } + } + + /* + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] -= num_removed; + pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] += num_removed; + */ + + return num_removed; +} + + +/****************************************************************************/ +int bHasAcidicHydrogen( inp_ATOM *at, int i ) +{ + int bFound = 0, j, type, mask; + if (!at[i].charge && at[i].num_H && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) + { + for (j = 0; ArTypMask[2 * j]; j++) + { + if (( type & ArTypMask[2 * j] ) && ( mask & ArTypMask[2 * j + 1] )) + { + bFound++; + break; + } + } + } + + return bFound; +} + + +/****************************************************************************/ +int bHasOtherExchangableH( inp_ATOM *at, int i ) +{ + int bFound = 0, type, mask; + if (at[i].num_H && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) + { + if (( type & ATT_ATOM_N ) && ( mask & ATBIT_NP_H )) + { + bFound++; + } + } + + return bFound; +} + + +int AaTypMask[] = +{ + AA_SIMPLE_TYP1, + AA_SIMPLE_MSK1, +#if ( FIX_NP_MINUS_BUG == 1 ) + AA_SIMPLE_TYP4, + AA_SIMPLE_MSK4, /* should not follow 0,0 pair */ +#endif + AA_SIMPLE_TYP2, + AA_SIMPLE_MSK2, + AA_SIMPLE_TYP3, + AA_SIMPLE_MSK3, + 0, + 0 +}; + + +/****************************************************************************/ +int SimpleAddAcidicProtons( inp_ATOM *at, + int num_atoms, + BN_AATG *pAATG, + int num2add ) +{ + int i, j, max_j = -1, mask, type, num_added; + int num[AR_SIMPLE_STEPS + 1], num_tot; + + for (j = 0; AaTypMask[2 * j]; j++) + { + num[max_j = j] = 0; + } + + for (i = 0; i < num_atoms; i++) + { + if (at[i].charge == -1 && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) + { + for (j = 0; j <= max_j; j++) + { + if (( type & AaTypMask[2 * j] ) && ( mask && AaTypMask[2 * j + 1] )) + { + num[j] ++; + break; + } + } + } + } + for (j = 0, num_tot = 0; j <= max_j; j++) + { + if (( num_tot += num[j] ) >= num2add) + { + max_j = j; + break; + } + } + if (!num_tot) + { + return 0; + } + for (i = 0, num_added = 0; i < num_atoms && num_added < num2add; i++) + { + if (at[i].charge == -1 && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) + { + for (j = 0; j <= max_j; j++) + { + if (num[j] && ( type & AaTypMask[2 * j] ) && ( mask && AaTypMask[2 * j + 1] )) + { + /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + type = GetAtomChargeType(at, i, pAATG->nAtTypeTotals, &mask, 1); /* subtract at[i] */ + num[j] --; + at[i].charge++; + AddOrRemoveExplOrImplH( 1, at, num_atoms, (AT_NUMB) i, pAATG->t_group_info ); + /*at[i].num_H ++;*/ + num_added++; + type = GetAtomChargeType(at, i, pAATG->nAtTypeTotals, &mask, 0); /* add changed at[i] */ + break; + } + } + } + } + + /* + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] += num_added; + pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] -= num_added; + */ + + return num_added; +} + + +/****************************************************************************/ +int bHasAcidicMinus( inp_ATOM *at, int i ) +{ + int bFound = 0, j, type, mask; + if (at[i].charge == -1 && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) + { + for (j = 0; AaTypMask[2 * j]; j++) + { + if (( type & AaTypMask[2 * j] ) && ( mask & AaTypMask[2 * j + 1] )) + { + bFound++; + break; + } + } + } + + return bFound; +} + + +/**************************************************************************** +HardRemoveAcidicProtons( ... ) + +Create 2 tautomeric groups: +(1) for O on -C=O, +(2) for the rest of the atoms. +Pull H from (2) to (1); remove later +****************************************************************************/ +int HardRemoveAcidicProtons( CANON_GLOBALS *pCG, + inp_ATOM *at, + int num_atoms, + BN_AATG *pAATG, + int num2remove, + int *nNumCanceledCharges, + BN_STRUCT *pBNS, + BN_DATA *pBD ) +{ + int cg_Plus = 0; + int cg_Minus = 0; + int tg_H_Other = 0; + int tg_H_Acid = 0; + + int ret = 0, ret2; + int nDelta, nNumMoved2AcidH = 0, nNumNeutralized = 0, nPrevNumCharges; /* djb-rwth: removing redundant variables */ + + int nPosCharges, nPosCharges2; + int nNegCharges, nNegCharges2; + /* + int nNumNP_H, nNumNP_H2; + int nNumOS_H, nNumOS_H2; + */ + + nPosCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; + nNegCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; + /* + nNumNP_H = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + + pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; + nNumOS_H = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + + pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + + pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; + */ + + /* Prevent free exchange H <-> (-) */ + pBNS->type_CN = ( BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_C_NEGATIVE ); + pBNS->type_T = BNS_VERT_TYPE_TGROUP; + pBNS->type_TACN = BNS_VERT_TYPE_ACID; + + /* Create (+) charge group */ + cg_Plus = CreateCGroupInBnStruct( at, num_atoms, pBNS, AR_HARD_TYP_POS, AR_HARD_MSK_POS, 1 ); + + /* create (-) charge group */ + /* + if ( nAtTypeTotals[ATTOT_NUM_CO_Minus] + + nAtTypeTotals[ATTOT_NUM_CS_Minus] + + nAtTypeTotals[ATTOT_NUM_ZO_Minus] + + nAtTypeTotals[ATTOT_NUM_N_Minus] ) + */ + + cg_Minus = CreateCGroupInBnStruct( at, num_atoms, pBNS, AR_HARD_TYP_NEG, AR_HARD_MSK_NEG, -1 ); + + pBNS->type_CN = ( BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_C_NEGATIVE ); + pBNS->type_T = BNS_VERT_TYPE_TGROUP; + pBNS->type_TACN = BNS_VERT_TYPE_ACID; + + /* Create tautomeric group for non-acidic or negatively charged acidic O */ + tg_H_Other = CreateTGroupInBnStruct( at, num_atoms, pBNS, AR_HARD_TYP_HN, AR_HARD_MSK_HN ); + if (tg_H_Other) /* djb-rwth: fixing coverity CID #499503 */ + { + return BNS_PROGRAM_ERR; + } + + /* Create tautomeric group for possibly acidic O */ + tg_H_Acid = CreateTGroupInBnStruct( at, num_atoms, pBNS, AR_HARD_TYP_HA, AR_HARD_MSK_HA ); + if (tg_H_Other >= num_atoms && tg_H_Acid >= num_atoms) + { + /* Find alt path to remove one proton */ + do + { + /* Remove a proton */ + nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; + ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, + at, num_atoms, + tg_H_Other /*nVertDoubleBond*/, + tg_H_Acid /*nVertSingleBond*/, + ALT_PATH_MODE_REM_PROTON ); + if (IS_BNS_ERROR( ret )) + { + return ret; + } + if (ret & 1) + { + nDelta = ( ret & ~3 ) >> 2; + /* djb-rwth: removing redundant code */ + if (nDelta) + { + /* Radical pair has disappeared */ + ; /* goto quick_exit;*/ + } + nNumMoved2AcidH++; + if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + 1) + { + nNumNeutralized += ( nPrevNumCharges - ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - 1 ) ) / 2; + } + } + } while (( ret & 1 ) && nNumMoved2AcidH < num2remove); + + /* Neutralize: remove ion pairs like >N(+)=-O(-) => >N-=O */ + if (( nNumMoved2AcidH /*|| bCancelChargesAlways*/ ) && cg_Minus >= num_atoms && cg_Plus >= num_atoms && + pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] > abs( pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] )) + { + do + { + nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; + ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, + at, num_atoms, + cg_Minus /*nVertDoubleBond*/, + cg_Plus /*nVertSingleBond*/, + ALT_PATH_MODE_REM_PROTON ); + if (IS_BNS_ERROR( ret )) + { + return ret; + } + if (ret & 1) + { + nDelta = ( ret & ~3 ) >> 2; + /* djb-rwth: removing redundant code */ + if (nDelta) + { + /* Radical pair has disappeared */ + ; /* goto quick_exit;*/ + } + if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]) + { + nNumNeutralized += ( nPrevNumCharges - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] ) / 2; + } + } + } while (ret & 1); + } + } + + ret = 0; + if (tg_H_Acid >= num_atoms) + { + ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, tg_H_Acid, pBNS ); + if (!ret && ret2) + { + ret = ret2; + } + } + if (tg_H_Other >= num_atoms) + { + ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, tg_H_Other, pBNS ); + if (!ret && ret2) + { + ret = ret2; + } + } + if (cg_Minus >= num_atoms) + { + ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Minus, pBNS ); + if (!ret && ret2) + { + ret = ret2; + } + } + if (cg_Plus >= num_atoms) + { + ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Plus, pBNS ); + if (!ret && ret2) + { + ret = ret2; + } + } + + pBNS->type_CN = 0; + pBNS->type_T = 0; + pBNS->type_TACN = 0; + + if (ret) + { + return ret; + } + + if (pAATG->nAtTypeTotals[ATTOT_NUM_CO_Minus] + pAATG->nAtTypeTotals[ATTOT_NUM_ZO_Minus] && + pAATG->nAtTypeTotals[ATTOT_NUM_N_Minus]) + { + } + + nPosCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; + nNegCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; + /* + nNumNP_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + + pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; + nNumOS_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + + pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + + pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; + */ + if (( nPosCharges - nNegCharges ) - ( nPosCharges2 - nNegCharges2 ) != 0) + { + return BNS_PROGRAM_ERR; + } + + if (nNumCanceledCharges) + { +#if ( FIX_CANCEL_CHARGE_COUNT_BUG == 1 ) + *nNumCanceledCharges += 2 * nNumNeutralized; +#else + *nNumCanceledCharges = 2 * nNumNeutralized; +#endif + } + + return nNumMoved2AcidH; +} + + +/****************************************************************************/ +int HardAddAcidicProtons( CANON_GLOBALS *pCG, + inp_ATOM *at, + int num_atoms, + BN_AATG *pAATG, + int num2add, + int *nNumCanceledCharges, + BN_STRUCT *pBNS, + BN_DATA *pBD ) +{ + int cg_Plus = 0; + int cg_Minus_CO = 0; + int cg_Minus_Other = 0; + int tg_H = 0; + + int ret = 0, ret2; + int nDelta, nNumChanges = 0, nNumMoved2AcidMinus = 0, nNumNeutralized = 0, nPrevNumCharges; /* djb-rwth: removing redundant variables */ + + int nPosCharges, nPosCharges2; + int nNegCharges, nNegCharges2; + /* + int nNumNP_H, nNumNP_H2; + int nNumOS_H, nNumOS_H2; + */ + nPosCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; + nNegCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; + /* + nNumNP_H = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + + pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; + nNumOS_H = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + + pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + + pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; + */ + + /* Prevent free exchange H <-> (-) */ + pBNS->type_CN = ( BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_C_NEGATIVE ); + pBNS->type_T = BNS_VERT_TYPE_TGROUP; + pBNS->type_TACN = BNS_VERT_TYPE_ACID; + + /* Create (+) charge group */ + cg_Plus = CreateCGroupInBnStruct( at, num_atoms, pBNS, AA_HARD_TYP_POS, AA_HARD_MSK_POS, 1 ); + + /* Create (-) charge group */ + /* + if ( nAtTypeTotals[ATTOT_NUM_CO_Minus] + + nAtTypeTotals[ATTOT_NUM_CS_Minus] + + nAtTypeTotals[ATTOT_NUM_ZO_Minus] + + nAtTypeTotals[ATTOT_NUM_N_Minus] ) + */ + cg_Minus_CO = CreateCGroupInBnStruct( at, num_atoms, pBNS, AA_HARD_TYP_CO, AA_HARD_MSK_CO, -1 ); + if (cg_Minus_CO < 0) /* djb-rwth: fixing coverity CID #499474 */ + { + return BNS_PROGRAM_ERR; + } + + cg_Minus_Other = CreateCGroupInBnStruct( at, num_atoms, pBNS, AA_HARD_TYP_NEG, AA_HARD_MSK_NEG, -1 ); + + pBNS->type_CN = ( BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_C_NEGATIVE ); + pBNS->type_T = BNS_VERT_TYPE_TGROUP; + pBNS->type_TACN = BNS_VERT_TYPE_ACID; + + /* Create tautomeric group for all H */ + tg_H = CreateTGroupInBnStruct( at, num_atoms, pBNS, AA_HARD_TYP_H, AA_HARD_MSK_H ); + + if (cg_Minus_Other >= num_atoms && cg_Minus_CO >= num_atoms) + { + /* Find alt path to remove one proton */ + do + { + /* Add a proton */ + nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; + ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, + at, num_atoms, + cg_Minus_Other /*nVertDoubleBond*/, + cg_Minus_CO /*nVertSingleBond*/, + ALT_PATH_MODE_REM_PROTON ); + if (IS_BNS_ERROR( ret )) + { + return ret; + } + if (ret & 1) + { + nDelta = ( ret & ~3 ) >> 2; + nNumChanges += (0 != (ret & 2)); /* djb-rwth: ignoring LLVM warning: variable used */ + if (nDelta) + { + /* Radical pair has disappeared */ + ; /* goto quick_exit;*/ + } + nNumMoved2AcidMinus++; + if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + 1) + { + nNumNeutralized += ( nPrevNumCharges - ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - 1 ) ) / 2; + } + } + } while (( ret & 1 ) && nNumMoved2AcidMinus < num2add); + + /* Neutralize: remove ion pairs like >N(+)=-O(-) => >N-=O */ + if (( nNumMoved2AcidMinus /*|| bCancelChargesAlways*/ ) && + cg_Minus_Other >= num_atoms && cg_Plus >= num_atoms && + pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] > abs( pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] )) + { + do + { + nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; + ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, + at, num_atoms, + cg_Minus_Other /*nVertDoubleBond*/, + cg_Plus /*nVertSingleBond*/, + ALT_PATH_MODE_REM_PROTON ); + if (IS_BNS_ERROR( ret )) + { + return ret; + } + if (ret & 1) + { + nDelta = ( ret & ~3 ) >> 2; + nNumChanges += (0 != (ret & 2)); /* djb-rwth: ignoring LLVM warning: variable used */ + if (nDelta) + { + /* Radical pair has disappeared */ + ; /* goto quick_exit;*/ + } + if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]) + { + nNumNeutralized += ( nPrevNumCharges - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] ) / 2; + } + } + } while (ret & 1); + } + } + + ret = 0; + if (tg_H >= num_atoms) + { + ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, tg_H, pBNS ); + if (!ret && ret2) + { + ret = ret2; + } + } + if (cg_Minus_Other >= num_atoms) + { + ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Minus_Other, pBNS ); + if (!ret && ret2) + { + ret = ret2; + } + } + if (cg_Minus_CO >= num_atoms) + { + ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Minus_CO, pBNS ); + if (!ret && ret2) + { + ret = ret2; + } + } + if (cg_Plus >= num_atoms) + { + ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Plus, pBNS ); + if (!ret && ret2) + { + ret = ret2; + } + } + + pBNS->type_CN = 0; + pBNS->type_T = 0; + pBNS->type_TACN = 0; + + if (ret) + { + return ret; + } + + if (pAATG->nAtTypeTotals[ATTOT_NUM_CO_Minus] + pAATG->nAtTypeTotals[ATTOT_NUM_ZO_Minus] && + pAATG->nAtTypeTotals[ATTOT_NUM_N_Minus]) + { + } + + nPosCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; + nNegCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; + /* + nNumNP_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + + pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; + nNumOS_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + + pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + + pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; + */ + + if (( nPosCharges - nNegCharges ) - ( nPosCharges2 - nNegCharges2 ) != 0) + { + return BNS_PROGRAM_ERR; + } + + if (nNumCanceledCharges) + { +#if ( FIX_CANCEL_CHARGE_COUNT_BUG == 1 ) + *nNumCanceledCharges += 2 * nNumNeutralized; +#else + *nNumCanceledCharges = 2 * nNumNeutralized; +#endif + } + + return nNumMoved2AcidMinus; +} + + +/**************************************************************************** +HardRemoveHplusNP( ... ) + +Examples include removal of H from tautomeric O +that belongs to the same t-group as N: + +>N(+)=-N=-OH =(taut.) => +>N(+)=-NH-=O =(+charge move) => +>N-=NH(+)-=O => >N-=N-=O + H(+) +****************************************************************************/ +int HardRemoveHplusNP( CANON_GLOBALS *pCG, + inp_ATOM *at, + int num_atoms, + int bCancelChargesAlways, + int *nNumCanceledCharges, + BN_AATG *pAATG, + BN_STRUCT *pBNS, + BN_DATA *pBD ) +{ + + int cg_Plus = 0; + int cg_Minus = 0; + int tg_H = 0; +#if ( MOVE_PPLUS_TO_REMOVE_PROTONS == 1 ) + int cg_PlusP = 0; +#endif +#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) + int nPrevRemovedProtons, nCurrRemovedProtons; +#endif + int ret = 0, ret2; + int nDelta, nNumChanges = 0, nNumRemovedProtons = 0, nNumNeutralized = 0, nPrevNumCharges; /* djb-rwth: ignoring LLVM warning: variable used */ + + int nPosCharges, nPosCharges2; + int nNegCharges, nNegCharges2; + /* + int nNumNP_H, nNumNP_H2; + int nNumOS_H, nNumOS_H2; + */ + + nPosCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; + nNegCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; + /* + nNumNP_H = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + + pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; + nNumOS_H = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + + pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + + pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; + */ + + /* Prevent free exchange H <-> (-) */ + pBNS->type_CN = ( BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_C_NEGATIVE ); + pBNS->type_T = BNS_VERT_TYPE_TGROUP; + pBNS->type_TACN = BNS_VERT_TYPE_ACID; + + /* Create (+) charge group */ + cg_Plus = CreateCGroupInBnStruct( at, num_atoms, pBNS, PR_HARD_TYP_POS, PR_HARD_MSK_POS, 1 ); + + /* Create (-) charge group */ + /* + if ( nAtTypeTotals[ATTOT_NUM_CO_Minus] + + nAtTypeTotals[ATTOT_NUM_CS_Minus] + + nAtTypeTotals[ATTOT_NUM_ZO_Minus] + + nAtTypeTotals[ATTOT_NUM_N_Minus] ) + */ +#if ( MOVE_PPLUS_TO_REMOVE_PROTONS == 1 ) + cg_PlusP = CreateCGroupInBnStruct( at, num_atoms, pBNS, PR_HARD_TYP_POSP, PR_HARD_MSK_POS, 1 ); +#endif + cg_Minus = CreateCGroupInBnStruct( at, num_atoms, pBNS, PR_HARD_TYP_NEG, PR_HARD_MSK_NEG, -1 ); + + /* Create single tautomeric group */ + tg_H = CreateTGroupInBnStruct( at, num_atoms, pBNS, PR_HARD_TYP_H, PR_HARD_MSK_H ); + if (tg_H < 0) /* djb-rwth: fixing coverity CID #499572 */ + { + return BNS_PROGRAM_ERR; + } + + if (tg_H >= num_atoms && cg_Plus >= num_atoms) + { + +#if ( FIX_N_MINUS_NORN_BUG == 1 ) + /* neutralize: remove ion pairs like >N(+)=-O(-) => >N-=O; >N(+)=-NH(-) => >N-=NH */ + if (( nNumRemovedProtons || bCancelChargesAlways ) && cg_Minus >= num_atoms && cg_Plus >= num_atoms && + pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] > abs( pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] )) + { + do + { + nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; +#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) + nPrevRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; +#endif + ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, at, num_atoms, + cg_Minus /*nVertDoubleBond*/, cg_Plus /*nVertSingleBond*/, ALT_PATH_MODE_REM_PROTON ); + if (IS_BNS_ERROR( ret )) + { + return ret; + } +#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) + nCurrRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; + if (nCurrRemovedProtons != nPrevRemovedProtons) + { + return BNS_RADICAL_ERR; + } +#endif + if (ret & 1) + { + nDelta = ( ret & ~3 ) >> 2; + nNumChanges += ( 0 != ( ret & 2 ) ); + if (nDelta) + { + /* radical pair has disappeared */ + ; /* goto quick_exit;*/ + } + if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]) + { + nNumNeutralized += ( nPrevNumCharges - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] ) / 2; + } + } + } while (ret & 1); + } +#endif + + /* Find alt path to remove one proton */ + do + { + /* Remove a proton */ + nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; +#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) + nPrevRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; +#endif + ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, at, num_atoms, + tg_H /*nVertDoubleBond*/, + cg_Plus /*nVertSingleBond*/, + ALT_PATH_MODE_REM_PROTON ); + if (IS_BNS_ERROR( ret )) + { + return ret; + } +#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) + nCurrRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; + if (nCurrRemovedProtons != nPrevRemovedProtons + ( ret & 1 )) + { + return BNS_RADICAL_ERR; + } +#endif + if (ret & 1) + { + nDelta = ( ret & ~3 ) >> 2; + nNumChanges += (0 != (ret & 2)); /* djb-rwth: ignoring LLVM warning: variable used */ + if (nDelta) + { + /* radical pair has disappeared */ + ; /* goto quick_exit;*/ + } + nNumRemovedProtons++; + if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + 1) + { + nNumNeutralized += ( nPrevNumCharges - ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - 1 ) ) / 2; + } + } + } while (ret & 1); + + /* Neutralize: remove ion pairs like >N(+)=-O(-) => >N-=O */ + if (( nNumRemovedProtons || bCancelChargesAlways ) && cg_Minus >= num_atoms && cg_Plus >= num_atoms && + pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] > abs( pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] )) + { + do + { + nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; +#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) + nPrevRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; +#endif + ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, at, num_atoms, + cg_Minus /*nVertDoubleBond*/, + cg_Plus /*nVertSingleBond*/, + ALT_PATH_MODE_REM_PROTON ); + if (IS_BNS_ERROR( ret )) + { + return ret; + } +#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) + nCurrRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; + if (nCurrRemovedProtons != nPrevRemovedProtons) + { + return BNS_RADICAL_ERR; + } +#endif + if (ret & 1) + { + nDelta = ( ret & ~3 ) >> 2; + nNumChanges += (0 != (ret & 2)); /* djb-rwth: ignoring LLVM warning: variable used */ + if (nDelta) + { + /* Radical pair has disappeared */ + ; /* goto quick_exit;*/ + } + if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]) + { + nNumNeutralized += ( nPrevNumCharges - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] ) / 2; + } + } + } while (ret & 1); + } + } + + ret = 0; + if (tg_H >= num_atoms) + { + ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, tg_H, pBNS ); + if (!ret && ret2) + { + ret = ret2; + } + } + if (cg_Minus >= num_atoms) + { + ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Minus, pBNS ); + if (!ret && ret2) + { + ret = ret2; + } + } +#if ( MOVE_PPLUS_TO_REMOVE_PROTONS == 1 ) + if (cg_PlusP >= num_atoms) + { + ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_PlusP, pBNS ); + if (!ret && ret2) + { + ret = ret2; + } + } +#endif + if (cg_Plus >= num_atoms) + { + ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Plus, pBNS ); + if (!ret && ret2) + { + ret = ret2; + } + } + + pBNS->type_CN = 0; + pBNS->type_T = 0; + pBNS->type_TACN = 0; + + if (ret) + { + return ret; + } + + if (pAATG->nAtTypeTotals[ATTOT_NUM_CO_Minus] + pAATG->nAtTypeTotals[ATTOT_NUM_ZO_Minus] && + pAATG->nAtTypeTotals[ATTOT_NUM_N_Minus]) + { + } + + nPosCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; + nNegCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; + /* + nNumNP_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + + pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; + nNumOS_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + + pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + + pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; + */ + + if (( nPosCharges - nNegCharges ) - ( nPosCharges2 - nNegCharges2 ) != nNumRemovedProtons) + { + return BNS_PROGRAM_ERR; + } + + if (nNumCanceledCharges) + { +#if ( FIX_CANCEL_CHARGE_COUNT_BUG == 1 ) + *nNumCanceledCharges += 2 * nNumNeutralized; +#else + *nNumCanceledCharges = 2 * nNumNeutralized; +#endif + } + + return nNumRemovedProtons; +} + + +/****************************************************************************/ +int mark_at_type( inp_ATOM *atom, int num_atoms, int nAtTypeTotals[] ) +{ + int i, max_num_ions, mask, type; + /*int max_protons, max_O_Minus, num_H = 0, num_CO=0;*/ + + if (nAtTypeTotals) + { + memset( nAtTypeTotals, 0, ATTOT_ARRAY_LEN * sizeof( nAtTypeTotals[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + } + + for (i = 0; i < num_atoms; i++) + { + type = GetAtomChargeType( atom, i, nAtTypeTotals, &mask, 0 ); + atom[i].at_type = type; + /* + num_H += ((type & PR_HARD_TYP_H) && (mask & ATBIT_MSK_H)); + num_CO += ((type & AR_HARD_TYP_HA) && (mask & AR_HARD_MSK_HA)); + */ + } + + if (nAtTypeTotals) + { + /* + max_protons = nAtTypeTotals[ATTOT_NUM_NP_Proton] + + inchi_min(num_H, nAtTypeTotals[ATTOT_NUM_NP_Plus]); + max_O_Minus = nAtTypeTotals[ATTOT_NUM_CO_Minus] + nAtTypeTotals[ATTOT_NUM_CS_Minus] + + nAtTypeTotals[ATTOT_NUM_ZO_Minus] + nAtTypeTotals[ATTOT_NUM_OO_Minus] + + nAtTypeTotals[ATTOT_NUM_ZOO_Minus] + nAtTypeTotals[ATTOT_NUM_NO_Minus] + + nAtTypeTotals[ATTOT_NUM_O_Minus] +nAtTypeTotals[ATTOT_NUM_N_Minus]; + ; + max_num_ions = max_protons + max_O_Minus + nAtTypeTotals[ATTOT_NUM_CHARGES]; + */ + max_num_ions = nAtTypeTotals[ATTOT_NUM_CHARGES]; + } + else + { + max_num_ions = 0; + } + + return max_num_ions; +} + + +/****************************************************************************/ +int RemoveNPProtonsAndAcidCharges( CANON_GLOBALS *pCG, + inp_ATOM *at, + int num_atoms, + BN_AATG *pAATG, + BN_STRUCT *pBNS, + BN_DATA *pBD ) +{ + + /* Prepare data structure */ + int num; + int nNumCanceledCharges = 0; + /* djb-rwth: removing redundant variables */ + T_GROUP_INFO *t_group_info = pAATG->t_group_info; + int ret = 0, bError = 0; + + int bAllowHardRemove = ( t_group_info->bTautFlags & TG_FLAG_TEST_TAUT__SALTS ) && + ( t_group_info->bTautFlags & TG_FLAG_TEST_TAUT2_SALTS ) && + ( t_group_info->bTautFlags & TG_FLAG_MOVE_POS_CHARGES ) && + ( t_group_info->bTautFlags & TG_FLAG_HARD_ADD_REM_PROTONS ); + + if (pAATG->nMarkedAtom && num_atoms < pAATG->nAllocLen) + { + inchi_free( pAATG->nMarkedAtom ); + qzfree( pAATG->nEndPoint ); + memset( pAATG, 0, sizeof( *pAATG ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + } + + if (!pAATG->nMarkedAtom && ( pAATG->nMarkedAtom = (S_CHAR *) inchi_malloc( num_atoms * sizeof( pAATG->nMarkedAtom[0] ) ) )) + { + pAATG->nAllocLen = num_atoms; + pAATG->nNumFound = 0; + } + + /* o TECHMAN-5.1. Remove protons from charged heteroatoms */ + + /* (TECHMAN-5.1a) Simple remove of protons from N, P, and O,S,Se,Te */ + if ((num = pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton] + pAATG->nAtTypeTotals[ATTOT_NUM_OH_Plus])) /* djb-rwth: addressing LLVM warning */ + { + ret = SimpleRemoveHplusNPO( at, num_atoms, pAATG->nAtTypeTotals, t_group_info ); + if (ret != num) + { + bError = BNS_PROGRAM_ERR; + goto exit_function; + } + /*t_group_info->nNumRemovedProtons += ret;*/ + t_group_info->tni.bNormalizationFlags |= ( ret > 0 ) ? FLAG_PROTON_NPO_SIMPLE_REMOVED : 0; + } + + if (( num = pAATG->nAtTypeTotals[ATTOT_NUM_NP_Plus] ) && bAllowHardRemove) /* djb-rwth: ignoring LLVM warning: variable used */ + { + /* [TECHMAN-5.1b] Hard removing more protons from cationic N; charges may be canceled */ + ret = HardRemoveHplusNP( pCG, at, num_atoms, 1, &nNumCanceledCharges, pAATG, pBNS, pBD ); + if (IS_BNS_ERROR( ret )) + { + bError = ret; + goto exit_function; + } + /* djb-rwth: removing redundant code */ + /*t_group_info->nNumRemovedProtons += ret;*/ + t_group_info->tni.bNormalizationFlags |= ( ret > 0 ) ? FLAG_PROTON_NP_HARD_REMOVED : 0; + } + + if (pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] > 0) + { + /* o TECHMAN-5.2. Remove protons from neutral heteroatoms */ + + /* (TECHMAN-5.2a) Simple removal */ + ret = SimpleRemoveAcidicProtons( at, num_atoms, pAATG, pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ); + if (IS_BNS_ERROR( ret )) + { + bError = ret; + goto exit_function; + } + + /*t_group_info->nNumRemovedProtons += ret;*/ + t_group_info->tni.bNormalizationFlags |= ( ret > 0 ) ? FLAG_PROTON_AC_SIMPLE_REMOVED : 0; + + + if (pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] > 0 && bAllowHardRemove) + { + /* (TECHMAN-5.2b) Hard removal */ + ret = HardRemoveAcidicProtons(pCG, at, num_atoms, pAATG, pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE], &nNumCanceledCharges, pBNS, pBD); + if (IS_BNS_ERROR(ret)) + { + bError = ret; + goto exit_function; + } + if (ret > 0) + { + int ret2 = SimpleRemoveAcidicProtons(at, num_atoms, pAATG, ret); + if (ret2 != ret) + { + bError = BNS_PROGRAM_ERR; + goto exit_function; + } + /*t_group_info->nNumRemovedProtons += ret;*/ + t_group_info->tni.bNormalizationFlags |= (ret > 0) ? FLAG_PROTON_AC_HARD_REMOVED : 0; + /* djb-rwth: removing redundant code */ + } + } + + + } + else + { + if (pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] < 0) + { + ret = SimpleAddAcidicProtons( at, num_atoms, pAATG, -pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ); + if (IS_BNS_ERROR( ret )) + { + bError = ret; + goto exit_function; + } + /*t_group_info->nNumRemovedProtons -= ret;*/ + /* + CHECK_TACN == 1 prohibits replacing (-) on N with H unless H can be moved to N + along an alternating path from another heteroatom (t-group will be detected). + */ + t_group_info->tni.bNormalizationFlags |= ( ret > 0 ) ? FLAG_PROTON_AC_SIMPLE_ADDED : 0; + if (pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] < 0 && bAllowHardRemove) + { + ret = HardAddAcidicProtons( pCG, at, num_atoms, pAATG, -pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE], &nNumCanceledCharges, pBNS, pBD ); + if (IS_BNS_ERROR( ret )) + { + bError = ret; + goto exit_function; + } + if (ret > 0) + { + int ret2 = SimpleAddAcidicProtons( at, num_atoms, pAATG, ret ); + if (ret2 != ret) + { + bError = BNS_PROGRAM_ERR; + goto exit_function; + } + /*t_group_info->nNumRemovedProtons -= ret;*/ + t_group_info->tni.bNormalizationFlags |= FLAG_PROTON_AC_HARD_ADDED; /* djb-rwth: fixing coverity CID #499527 */ + /* djb-rwth: removing redundant code */ + } + } + } + } + + t_group_info->tni.bNormalizationFlags |= nNumCanceledCharges ? FLAG_PROTON_CHARGE_CANCEL : 0; + +exit_function: + if (bError) + { + ret = IS_BNS_ERROR( bError ) ? bError : BNS_PROGRAM_ERR; + } + + return ret; +} + + +/**************************************************************************** +Main normalization procedure +****************************************************************************/ +int mark_alt_bonds_and_taut_groups( struct tagINCHI_CLOCK *ic, + struct tagCANON_GLOBALS *pCG, + inp_ATOM *at, + inp_ATOM *at_fixed_bonds_out, + int num_atoms, + struct tagInchiTime *ulTimeOutTime, + T_GROUP_INFO *t_group_info, + INCHI_MODE *inpbTautFlags, + INCHI_MODE *inpbTautFlagsDone, + int nebend, + int *ebend ) + + +{ + BN_STRUCT *pBNS = NULL; + BN_DATA *pBD = NULL; + int bError, nChanges, taut_found, salt_found, salt_pass, salt_step, ret, ret2, num, num_changed_bonds; /* djb-rwth: removing redundant variables */ + int max_altp = BN_MAX_ALTP; + int bChangeFlow = ( BNS_EF_CHNG_RSTR | BNS_EF_ALTR_BONDS ); + BNS_FLOW_CHANGES fcd[BNS_MAX_NUM_FLOW_CHANGES + 1]; + C_GROUP_INFO CGroupInfo; + C_GROUP_INFO *c_group_info = &CGroupInfo; + S_GROUP_INFO SGroupInfo; + S_GROUP_INFO *s_group_info = &SGroupInfo; + INCHI_MODE *pbTautFlags = t_group_info ? &t_group_info->bTautFlags : inpbTautFlags; + INCHI_MODE *pbTautFlagsDone = t_group_info ? &t_group_info->bTautFlagsDone : inpbTautFlagsDone; + + int nAtTypeTotals[ATTOT_ARRAY_LEN]; + int nNumOrigTotAtoms; + + BN_AATG aatg; + BN_AATG *pAATG = &aatg; + +#ifdef FIX_AROM_RADICAL /* Added 2011-05-09 IPl */ + int i, n_arom_radicals = 0, *stored_radicals = NULL; +#endif + int at_prot; /* moved from below 2024-09-01 DT */ + + nChanges = 0; + bError = 0; + + memset( c_group_info, 0, sizeof( *c_group_info ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + memset( s_group_info, 0, sizeof( *s_group_info ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + memset( pAATG, 0, sizeof( *pAATG ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + + /*(@nnuk : Nauman Ullah Khan) :: Variable for checking (De)protonation status */ + LOG_NO_ARGS("\n############# Initial state before (De)Protonation (L5373:ichi_bns.c) ###############\n"); + for (at_prot = 0; at_prot < num_atoms; at_prot++) + { + LOG_MULT_ARGS("Atom %d: Element: %s, Num_H: %d, Charge: %hhd, Radical: %d\n", at_prot, at[at_prot].elname, at[at_prot].num_H, at[at_prot].charge, at[at_prot].radical); + } + LOG_NO_ARGS("\n#####################################################################################\n"); + + +#ifdef FIX_AROM_RADICAL /* Added 2011-05-09 IPl */ + for (i = 0; i < num_atoms; i++) + { + if (( at[i].radical == RADICAL_DOUBLET ) && ( at[i].valence == 2 ) && + ( at[i].bond_type[0] == BOND_ALTERN ) && ( at[i].bond_type[1] == BOND_ALTERN )) + { + n_arom_radicals++; + if (!stored_radicals) + { + stored_radicals = (int *) inchi_calloc( num_atoms, sizeof( int ) ); + /* 2011-08-05 explicit cast added due to Evan Bolton */ + if (!stored_radicals) + { + bError = BNS_OUT_OF_RAM; + goto exit_function; + } + stored_radicals[i] = RADICAL_DOUBLET; + at[i].radical = 0; + at[i].num_H++; + } + } + } + +#endif + + if (( *pbTautFlags & TG_FLAG_MOVE_POS_CHARGES ) && num_atoms > 1) + { + /* Charge groups memory allocation */ + c_group_info->c_group = (C_GROUP *) inchi_calloc( num_atoms / 2, sizeof( c_group_info->c_group[0] ) ); + c_group_info->c_candidate = (C_CANDIDATE*) inchi_calloc( num_atoms, sizeof( c_group_info->c_candidate[0] ) ); + if (c_group_info->c_group && c_group_info->c_candidate) + { + c_group_info->max_num_c_groups = num_atoms / 2; + c_group_info->max_num_candidates = num_atoms; + } + else + { + bError = BNS_OUT_OF_RAM; /* error: out of RAM */ + /*printf("BNS_OUT_OF_RAM-1: num_at=%d, c_gr=%lx c_can=%lx\n", num_atoms, c_group_info->c_group, c_group_info->c_candidate);*/ + goto exit_function; + } + } + + if (*pbTautFlags & TG_FLAG_TEST_TAUT__SALTS) + { + if (t_group_info) + { + /* Salt groups memory allocation */ + s_group_info->s_candidate = + (S_CANDIDATE*) inchi_calloc( num_atoms, + sizeof( s_group_info->s_candidate[0] ) ); + if (s_group_info->s_candidate) + { + s_group_info->max_num_candidates = num_atoms; + } + else + { + bError = BNS_OUT_OF_RAM; /* error: out of RAM */ + /*printf("BNS_OUT_OF_RAM-2\n");*/ + goto exit_function; + } + } + } + + if (t_group_info) + { + if (t_group_info->tGroupNumber) + { + inchi_free( t_group_info->tGroupNumber ); + } + t_group_info->tGroupNumber = (AT_NUMB *) inchi_calloc( 2 * (long long)num_atoms + 1, sizeof( t_group_info->tGroupNumber[0] ) ); /* djb-rwth: cast operator added */ + if (!t_group_info->tGroupNumber) + { + /*printf("BNS_OUT_OF_RAM-9\n");*/ + bError = BNS_OUT_OF_RAM; /* error: out of RAM */ + goto exit_function; + } + num = t_group_info->tni.nNumRemovedExplicitH; + memset( &t_group_info->tni, 0, sizeof( t_group_info->tni ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + t_group_info->tni.nNumRemovedExplicitH = num; + } + + /* + again: + */ + + /* Allocate Balanced Network Data Strucures; replace Alternating bonds with Single */ + if (( pBNS = AllocateAndInitBnStruct( at, num_atoms, + BNS_ADD_ATOMS, BNS_ADD_EDGES, + max_altp, &num_changed_bonds ) ) + && + ( pBD = AllocateAndInitBnData( pBNS->max_vertices ) )) + { + + + pBNS->pbTautFlags = pbTautFlags; /* carry through all functions */ + pBNS->pbTautFlagsDone = pbTautFlagsDone; /* carry through all functions */ + + pBNS->ulTimeOutTime = ulTimeOutTime; /* v. 1.05 */ + pBNS->ic = ic; /* v. 1.05 */ + +#if ( BNS_PROTECT_FROM_TAUT == 1 ) + /* Protect bonds to acetyl and nitro */ + SetForbiddenEdges( pBNS, at, num_atoms, BNS_EDGE_FORBIDDEN_MASK, nebend, ebend ); +#endif + + /* Set bonds in case of input "aromatic" bonds or multiple radicals */ +#ifdef FIX_AROM_RADICAL /* Added 2011-05-09 IPl */ + if (n_arom_radicals) + { + ret = BnsAdjustFlowBondsRad( pBNS, pBD, at, num_atoms ); + if (stored_radicals) + { + for (i = 0; i < num_atoms; i++) + { + if (stored_radicals[i]) + { + at[i].radical = stored_radicals[i]; + at[i].num_H--; + } + } + } + if (IS_BNS_ERROR( ret )) + { + bError = ret; + goto exit_function; + } + } +#endif + + ret = BnsAdjustFlowBondsRad( pBNS, pBD, at, num_atoms ); + + /* (here pair(s) of radicals could have disappeared from the atoms) */ + if (IS_BNS_ERROR( ret )) + { + bError = ret; + goto exit_function; + } + pBNS->tot_st_flow += 2 * ret; + + /*return 0;*/ /* debug */ + /* djb-rwth: removing redundant code */ + + if (pBNS->tot_st_cap > pBNS->tot_st_flow) + { + /* has radical */ + bChangeFlow |= BNS_EF_SET_NOSTEREO; + } + + /******************************************************************** + * Remove protons from NH(+), but not PH(+) + * Add protons to COO(-) etc. + * or remove protons from COOH etc to make the organic part neutral + * Note: for now (-) from N(-) can be only canceled or moved to -C=O + ********************************************************************/ + if (( *pbTautFlags & TG_FLAG_VARIABLE_PROTONS ) && + t_group_info && + mark_at_type( at, num_atoms, nAtTypeTotals ) && + nAtTypeTotals[ATTOT_NUM_CHARGES]) + { + /* + the structure is simple to neutralize if it yields exactly + num[H(+)] = num[N,P H(+)] + num[N,S,O(-)] = num[=C-O(-)] + num[C-S(-)] + num[N(-)] + num[other O(-), S(-)] + + and n(p) = num[H(+)] - num[N,S,O(-)] (no protons, no negative N,O,S condition) + + Additional check is needed if: + min{num[N,PH], num[N,P(+), not onium]} > 0 + => possibility to yield more H(+) + + min_charge = orig_charge(P,N,O,S) - n(p) - n(OH,SH) + max_charge = orig_charge(P,N,O,S) - n(p) + n(O,S,N(-)) + */ + + nNumOrigTotAtoms = t_group_info->tni.nNumRemovedExplicitH + num_atoms; + pAATG->nAtTypeTotals = nAtTypeTotals; + pAATG->t_group_info = t_group_info; +#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) + pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; +#endif + + /***********************************************************/ + /* */ + /* ( D E ) P R O T O N A T I O N */ + /* */ + /***********************************************************/ + + ret = RemoveNPProtonsAndAcidCharges( pCG, at, num_atoms, pAATG, pBNS, pBD ); + +#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) + pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; +#endif + if (IS_BNS_ERROR( ret )) + { + bError = ret; + goto exit_function; + } + + if (t_group_info->tni.bNormalizationFlags) + { + SetInitCapFlowToCurrent( pBNS ); + if (at_fixed_bonds_out) + { + /* Copy modified initial tautomeric structure for displaying + Warning: implicit H counts in at_fixed_bonds_out include explicit Hs */ + + memcpy(at_fixed_bonds_out, at, nNumOrigTotAtoms * sizeof(at_fixed_bonds_out[0])); + + /* -- will be done in FillOutInputInfAtom() -- + RemoveExcessiveImplicitH( num_atoms, t_group_info->tni.nNumRemovedExplicitH, at_fixed_bonds_out ); + */ + } + } + } + + /****************** Initial bonds normalization ***************/ + + if (*pbTautFlags & TG_FLAG_MOVE_POS_CHARGES) + { + /******************* Find moveable positive charges **********************/ + do + { + /* Cycling while ret>0 added 2004-06-04 */ +#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) + pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; + CorrectFixing_NH_NH_Bonds( pBNS, at, num_atoms ); +#endif + ret = MarkChargeGroups( pCG, at, num_atoms, + c_group_info, t_group_info, + pBNS, pBD ); + +#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) + pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; +#endif + if (IS_BNS_ERROR( ret )) + { + bError = ret; + goto exit_function; + } + if (ret) + { + nChanges += ret; + ret2 = AddCGroups2BnStruct( pCG, pBNS, at, num_atoms, c_group_info ); + if (IS_BNS_ERROR( ret2 )) + { + bError = ret2; + goto exit_function; + } + *pbTautFlagsDone |= TG_FLAG_MOVE_POS_CHARGES_DONE; + } + } while (ret > 0); + + +#if ( BNS_RAD_SEARCH == 1 ) +#else + /* moveable charges may allow to cancel radicals -- check it */ + if (pBNS->tot_st_cap > pBNS->tot_st_flow) + { + ret = BnsAdjustFlowBondsRad( pBNS, pBD, at, num_atoms ); + if (IS_BNS_ERROR( ret )) + { + bError = ret; + goto exit_function; + } + if (ret > 0) + { + /* + pBNS->tot_st_flow += 2*ret; + ret = ReInitBnStruct( pBNS, at, num_atoms, 1 ); + if ( IS_BNS_ERROR( ret ) ) { + bError = ret; + goto exit_function; + } + */ + bError = BNS_RADICAL_ERR; + goto exit_function; + } + } +#endif + } + + /************************************************************************/ + /******** Test bonds for bond tautomerism **************/ + /******** replace moveable bonds with "alternating" bonds **************/ + /************************************************************************/ + ret = BnsTestAndMarkAltBonds( pBNS, pBD, at, num_atoms, fcd, bChangeFlow, 0 ); + + if (IS_BNS_ERROR( ret )) + { + bError = ret; + goto exit_function; + } + /* djb-rwth: removing redundant code */ + + /*********************** End of initial bonds normalization *************/ + + /* djb-rwth: removing redundant code */ + + /* Check for tautomerism */ + /* find new tautomer groups */ + salt_pass = 0; + salt_step = 0; + salt_found = 0; + + /*************************************************************/ + /* */ + /* M A I N C Y C L E B E G I N */ + /* */ + /*************************************************************/ + + do + { + /* djb-rwth: removing redundant code */ + nChanges = 0; + /* djb-rwth: removing redundant code */ + + /**************** Regular bond/H/(-)/positive charges tautomerism cycle begin **************/ + do + { + /* djb-rwth: removing redundant code */ + for (taut_found = 0; + 0 < ( ret = MarkTautomerGroups( pCG, at, num_atoms, + t_group_info, c_group_info, + pBNS, pBD ) ); + taut_found++) + { + ; + } + if (ret < 0) + { + bError = ret; + } + if (taut_found && !salt_pass) + { + *pbTautFlagsDone |= TG_FLAG_TEST_TAUT__ATOMS_DONE; + } + + if (taut_found || salt_found) + { + /****************** repeat bonds normalization ***************/ + ret = ReInitBnStructAddGroups( pCG, pBNS, at, num_atoms, + t_group_info, c_group_info ); + if (IS_BNS_ERROR( ret )) + { + bError = ret; + goto exit_function; + } +#if ( BNS_RAD_SEARCH == 1 ) +#else + /* discovered moveable charges and H-atoms may allow to cancel radicals */ + if (pBNS->tot_st_cap > pBNS->tot_st_flow) + { + ret = BnsAdjustFlowBondsRad( pBNS, pBD, at, num_atoms ); + if (IS_BNS_ERROR( ret )) + { + bError = ret; + goto exit_function; + } + if (ret > 0) + { + /* + pBNS->tot_st_flow += 2*ret; + ret = ReInitBnStruct( pBNS, at, num_atoms, 1 ); + if ( IS_BNS_ERROR( ret ) ) { + bError = ret; + goto exit_function; + } + */ + bError = BNS_RADICAL_ERR; + goto exit_function; + } + } +#endif + /****************** Update bonds normalization ***************/ + if (*pbTautFlags & TG_FLAG_MOVE_POS_CHARGES) + { + /******************* Find moveable charges ***************/ + do + { + /* Cycling while ret>0 added 2004-06-04 */ +#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) + pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; + CorrectFixing_NH_NH_Bonds( pBNS, at, num_atoms ); +#endif + + ret = MarkChargeGroups( pCG, at, num_atoms, + c_group_info, t_group_info, + pBNS, pBD ); +#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) + pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; +#endif + if (IS_BNS_ERROR( ret )) + { + bError = ret; + goto exit_function; + } + nChanges += ret; + if (ret > 0) + { + ret2 = ReInitBnStructAddGroups( pCG, pBNS, + at, num_atoms, + t_group_info, + c_group_info ); + if (IS_BNS_ERROR( ret2 )) + { + bError = ret2; + goto exit_function; + } + *pbTautFlagsDone |= TG_FLAG_MOVE_POS_CHARGES_DONE; + } + } while (ret > 0); + } + + /************************************************************************/ + /******** Find moveable bonds: **************/ + /******** test bonds for bond tautomerism **************/ + /******** replace moveable bonds with "alternating" bonds **************/ + /************************************************************************/ + ret = BnsTestAndMarkAltBonds( pBNS, pBD, at, num_atoms, fcd, bChangeFlow, 0 ); + if (IS_BNS_ERROR( ret )) + { + bError = ret; + goto exit_function; + } + nChanges += ret; + /****************** End of update bonds normalization ***************/ + + } + salt_found = 0; + } while (taut_found && !bError); + + + /**************** Regular bond/H/(-)/positive charges tautomerism cycle end **************/ + + if (bError) + { + break; + } + + + /******************* 'Salt' tautomerism permitted *************************/ + if (*pbTautFlags & TG_FLAG_TEST_TAUT__SALTS) + { + + if (*pbTautFlags & TG_FLAG_TEST_TAUT2_SALTS) + { + /*********** Requested one or more "salt" attachement migrartion test ********/ + if (!nChanges && salt_pass && salt_step) + { + break; /* done */ + } + if (!salt_step) + { + /* Salt step 0: process one attachment migrartion */ +#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) + pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; + CorrectFixing_NH_NH_Bonds( pBNS, at, num_atoms ); +#endif + salt_found = MarkSaltChargeGroups( pCG, at, num_atoms, + s_group_info, + t_group_info, + c_group_info, + pBNS, pBD ); +#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) + pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; +#endif + if (salt_found < 0) + { + bError = salt_found; + break; + } + else + { + if (salt_found > 0) + { + *pbTautFlagsDone |= TG_FLAG_TEST_TAUT__SALTS_DONE; + } + } + salt_step = !salt_found; + /* if new 'salt' atoms have been found then repeat regular taut. search + * MarkTautomerGroups() and do not perform salt step 1 + * if new 'salt' atoms have NOT been found then switch to salt step 1 + * and never repeat salt step 0 for the current structure + */ + } + + if (salt_step /*|| + (t_group_info->tni.bNormalizationFlags & FLAG_NORM_CONSIDER_TAUT)*/) + { + /* Salt step 1: process more than one attachment migration */ +#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) + pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; + CorrectFixing_NH_NH_Bonds( pBNS, at, num_atoms ); +#endif + salt_found = MarkSaltChargeGroups2( pCG, at, num_atoms, + s_group_info, + t_group_info, + c_group_info, + pBNS, pBD ); +#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) + pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; +#endif + if (salt_found < 0) + { + bError = salt_found; + break; + } + else + { + if (salt_found == 1 || salt_found == 5) + { + *pbTautFlagsDone |= TG_FLAG_TEST_TAUT2_SALTS_DONE; + if (salt_found == 5) + { + *pbTautFlagsDone |= TG_FLAG_TEST_TAUT3_SALTS_DONE; + } + /* salt_found == 2 => only negative charges involved */ + } + } + } + + salt_pass++; + } + else + { + /* !( *pbTautFlags & TG_FLAG_TEST_TAUT2_SALTS ) */ + /*************** Requested only one attachement migration test **********/ + if (!nChanges && salt_pass) + { + /* One attachment migration */ + break; + } + /* Salt step 0: process one attachment migration */ +#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) + pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; + CorrectFixing_NH_NH_Bonds( pBNS, at, num_atoms ); +#endif + salt_found = MarkSaltChargeGroups( pCG, at, num_atoms, + s_group_info, + t_group_info, + c_group_info, + pBNS, pBD ); +#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) + pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; +#endif + if (salt_found < 0) + { + bError = salt_found; + break; + } + else + { + if (salt_found > 0) + { + *pbTautFlagsDone |= TG_FLAG_TEST_TAUT__SALTS_DONE; + } + } + salt_pass++; + } /* ( *pbTautFlags & TG_FLAG_TEST_TAUT2_SALTS ) */ + } /* ( *pbTautFlags & TG_FLAG_TEST_TAUT__SALTS ) */ + } while (salt_found && !bError); + + /*************************************************************/ + /* */ + /* M A I N C Y C L E E N D */ + /* */ + /*************************************************************/ + + + if (*pbTautFlags & TG_FLAG_MERGE_TAUT_SALTS) + { + if (!bError && s_group_info /*&& s_group_info->num_candidates > 0*/) + { + ret = MergeSaltTautGroups( pCG, at, num_atoms, s_group_info, + t_group_info, c_group_info, pBNS ); + if (ret < 0) + { + bError = ret; + } + else + { + if (ret > 0) + { + *pbTautFlagsDone |= TG_FLAG_MERGE_TAUT_SALTS_DONE; + } + } + } + } + + if (!bError && t_group_info && + ( t_group_info->bTautFlags & TG_FLAG_VARIABLE_PROTONS ) && + ( t_group_info->bTautFlagsDone & ( TG_FLAG_FOUND_ISOTOPIC_ATOM_DONE | TG_FLAG_FOUND_ISOTOPIC_H_DONE ) )) + { + ret = MakeIsotopicHGroup( at, num_atoms, s_group_info, t_group_info ); + if (ret < 0) + { + bError = ret; + } + } + + /* Success */ + + remove_alt_bond_marks( at, num_atoms ); + + /************************************************ + * Temporarily ignore all non-alternating bonds + * and mark non-ring alt bonds non-stereogenic + ************************************************/ + + ReInitBnStructForAltBns( pBNS, at, num_atoms, 0 ); + MarkRingSystemsAltBns( pBNS, 0 ); + MarkNonStereoAltBns( pBNS, at, num_atoms, 0 ); +#if ( FIX_EITHER_DB_AS_NONSTEREO == 1 ) + /* second time unknown ("Either") alternating bonds are treated as non-stereogenic */ + /* stereobonds bonds that lost stereo get "Either" stereo_type */ + ReInitBnStructForAltBns( pBNS, at, num_atoms, 1 ); + MarkRingSystemsAltBns( pBNS, 1 ); + MarkNonStereoAltBns( pBNS, at, num_atoms, 1 ); +#endif + } + else + { + bError = BNS_OUT_OF_RAM; + /*printf("BNS_OUT_OF_RAM-3\n");*/ + } + + /*(@nnuk : Nauman Ullah Khan) */ + LOG_NO_ARGS("\n################# Modified state after (De)Protonation (L6014:ichi_bns.c) ################\n"); + for (at_prot = 0; at_prot < num_atoms; at_prot++) + { + LOG_MULT_ARGS("Atom %d: Element: %s, Num_H: %d, Charge: %hhd, Radical: %d\n", at_prot, at[at_prot].elname, at[at_prot].num_H, at[at_prot].charge, at[at_prot].radical); + } + LOG_NO_ARGS("\n##########################################################################################\n"); + +exit_function: + + /* djb-rwth: ignoring LLVM warning: variables used to store functions return values */ + pBNS = DeAllocateBnStruct(pBNS); + pBD = DeAllocateBnData(pBD); + /*#if ( MOVE_CHARGES == 1 )*/ + if (c_group_info) + { + if (c_group_info->c_group) + { + inchi_free( c_group_info->c_group ); + } + if (c_group_info->c_candidate) + { + inchi_free( c_group_info->c_candidate ); + } + } + /*#endif*/ + if (s_group_info && s_group_info->s_candidate) + { + inchi_free( s_group_info->s_candidate ); + } + if (pAATG && pAATG->nMarkedAtom) + { + inchi_free( pAATG->nMarkedAtom ); + qzfree( pAATG->nEndPoint ); + /*qzfree( pAATG->nAtTypeTotals );*/ /* nAtTypeTotals is a stack array */ + } + if (t_group_info && t_group_info->tGroupNumber) + { + inchi_free( t_group_info->tGroupNumber ); + t_group_info->tGroupNumber = NULL; + } + + if (!bError && num_atoms == 1 && at[0].at_type == ATT_PROTON && t_group_info && !t_group_info->tni.nNumRemovedExplicitH) + { + /* remove single isolated proton */ + t_group_info->tni.nNumRemovedProtons = 1; + t_group_info->tni.bNormalizationFlags |= FLAG_PROTON_SINGLE_REMOVED; + if (at[0].iso_atw_diff) + { +#if ( FIX_CURE53_ISSUE_NULL_DEREFERENCE_MAKE_A_COPY_OF_T_GROUP_INFO==1 || defined(FIX_IMPOSSIBLE_H_ISOTOPE_BUG) ) + if (at[0].iso_atw_diff <= NUM_H_ISOTOPES) + { + /* djb-rwth: possible false positive oss-fuzz issue #39064660 */ + t_group_info->tni.nNumRemovedProtonsIsotopic[at[0].iso_atw_diff - 1] ++; + } +#else + t_group_info->tni.nNumRemovedProtonsIsotopic[at[0].iso_atw_diff - 1] ++; +#endif + } + if (at_fixed_bonds_out) + { + memcpy(at_fixed_bonds_out, at, num_atoms * sizeof(at_fixed_bonds_out[0])); + } + /*num_atoms --;*/ + } + + + /* + Additional currently unused info: + + nOrigDelta > 0: original structure has been changed + due to fiund augmenting path(s) + nChanges > 0: either alt. bonds or taut. groups have been found + */ + +#ifdef FIX_AROM_RADICAL /* Added 2011-05-09 IPl */ + if (stored_radicals) + { + inchi_free( stored_radicals ); + } +#endif + + return bError ? bError : num_atoms; /* ret = 0 => success, any other => error */ +} + + +/****************************************************************************/ +int nMaxFlow2Check( BN_STRUCT *pBNS, int iedge ) +{ + BNS_EDGE *pEdge = pBNS->edge + iedge; + int nMaxFlow = ( pEdge->cap & EDGE_FLOW_MASK ); /* edge cap */ + + if (nMaxFlow > MAX_BOND_EDGE_CAP) + { + nMaxFlow = MAX_BOND_EDGE_CAP; + } + return nMaxFlow; +} + + +/****************************************************************************/ +int nCurFlow2Check( BN_STRUCT *pBNS, int iedge ) +{ + BNS_EDGE *pEdge = pBNS->edge + iedge; + int nCurFlow = ( pEdge->flow & EDGE_FLOW_MASK ); /* edge flow */ + return nCurFlow; +} + + +/****************************************************************************/ +int nMinFlow2Check( BN_STRUCT *pBNS, int iedge ) +{ + BNS_EDGE *pEdge = pBNS->edge + iedge; + Vertex v1 = pEdge->neighbor1; + Vertex v2 = v1 ^ pEdge->neighbor12; + int f12 = ( pEdge->flow & EDGE_FLOW_MASK ); + int rescap1, rescap2, rescap12, i, iedge_i; + + if (f12 > 0) + { + for (i = 0, rescap1 = 0; i < pBNS->vert[v1].num_adj_edges; i++) + { + iedge_i = pBNS->vert[v1].iedge[i]; + if (iedge_i == iedge) + { + continue; + } + rescap1 += ( pBNS->edge[iedge_i].cap & EDGE_FLOW_MASK ) - ( pBNS->edge[iedge_i].flow & EDGE_FLOW_MASK ); + } + for (i = 0, rescap2 = 0; i < pBNS->vert[v2].num_adj_edges; i++) + { + iedge_i = pBNS->vert[v2].iedge[i]; + if (iedge_i == iedge) + { + continue; + } + rescap2 += ( pBNS->edge[iedge_i].cap & EDGE_FLOW_MASK ) - ( pBNS->edge[iedge_i].flow & EDGE_FLOW_MASK ); + } + rescap12 = inchi_min( rescap1, rescap2 ); + rescap12 = inchi_min( rescap12, f12 ); + return f12 - rescap12; + } + + return 0; +} + + +/****************************************************************************/ +int bSetBondsAfterCheckOneBond( BN_STRUCT *pBNS, + BNS_FLOW_CHANGES *fcd, + int nTestFlow, + inp_ATOM *at, + int num_atoms, + int bChangeFlow0 ) +{ + int ifcd, iedge, new_flow, ret_val, nChanges = 0, bError = 0; + int bChangeFlow; + Vertex v1, v2; + int ineigh1, ineigh2; + BNS_EDGE *pEdge; + + bChangeFlow0 &= ~BNS_EF_CHNG_RSTR; /* do not change pEdge flow in SetBondType */ + if (!bChangeFlow0) + { + return 0; + } + + bChangeFlow = ( bChangeFlow0 & ~BNS_EF_SET_NOSTEREO ); + + /* Find the next to the last changed */ + if (bChangeFlow0 & BNS_EF_SET_NOSTEREO) + { + for (ifcd = 0; NO_VERTEX != ( iedge = fcd[ifcd].iedge ); ifcd++) /* djb-rwth: ignoring LLVM warning: variable used */ + { + iedge = fcd[ifcd].iedge; + pEdge = pBNS->edge + iedge; + if (!pEdge->pass) + { + continue; + } + + if (!ifcd && nTestFlow >= 0) + { + new_flow = nTestFlow; + } + else + { + new_flow = (int) pEdge->flow; + } + + v1 = pEdge->neighbor1; + v2 = pEdge->neighbor12 ^ v1; + if (v1 < num_atoms && v2 < num_atoms && new_flow != pEdge->flow0) + { + if (( pBNS->vert[v1].st_edge.cap0 == pBNS->vert[v1].st_edge.flow0 ) != + ( pBNS->vert[v1].st_edge.cap == pBNS->vert[v1].st_edge.flow ) || + ( pBNS->vert[v2].st_edge.cap0 == pBNS->vert[v2].st_edge.flow0 ) != + ( pBNS->vert[v2].st_edge.cap == pBNS->vert[v2].st_edge.flow )) + { + bChangeFlow |= BNS_EF_SET_NOSTEREO; + nChanges |= BNS_EF_SET_NOSTEREO; + } + } + } + } + else + { + for (ifcd = 0; NO_VERTEX != ( iedge = fcd[ifcd].iedge ); ifcd++) /* djb-rwth: ignoring LLVM warning: variable used */ + { + ; + } + } + + /* restore in reversed order to correctly handle vertex changed more than once */ + for (ifcd -= 1; 0 <= ifcd; ifcd--) + { + + iedge = fcd[ifcd].iedge; + pEdge = pBNS->edge + iedge; + if (!pEdge->pass) + { + continue; + } + + if (!ifcd && nTestFlow >= 0) + { + new_flow = nTestFlow; + } + else + { + new_flow = (int) pEdge->flow; + } + + v1 = pEdge->neighbor1; + v2 = pEdge->neighbor12 ^ v1; + if (v1 < num_atoms && v2 < num_atoms && bChangeFlow && new_flow != pEdge->flow0) + { + ineigh1 = pEdge->neigh_ord[0]; + ineigh2 = pEdge->neigh_ord[1]; + ret_val = SetAtomBondType( pEdge, &at[v1].bond_type[ineigh1], &at[v2].bond_type[ineigh2], new_flow - pEdge->flow0, bChangeFlow ); + if (!IS_BNS_ERROR( ret_val )) + { + nChanges |= ( ret_val > 0 ); + } + else + { + bError = ret_val; + } + } + pEdge->pass = 0; + } + + return bError ? bError : nChanges; +} + + +/****************************************************************************/ +int bRestoreFlowAfterCheckOneBond( BN_STRUCT *pBNS, BNS_FLOW_CHANGES *fcd ) +{ + int ifcd, iedge; + Vertex v1, v2; + BNS_EDGE *pEdge; + + /* Find the next to the last changed */ + for (ifcd = 0; NO_VERTEX != ( iedge = fcd[ifcd].iedge ); ifcd++) /* djb-rwth: ignoring LLVM warning: variable used */ + { + ; + } + + /* Restore in reversed order to correctly handle vertex changed more than once */ + for (ifcd -= 1; 0 <= ifcd; ifcd--) + { + /* Restore edge flow & cap */ + iedge = fcd[ifcd].iedge; + pEdge = pBNS->edge + iedge; + pEdge->flow = fcd[ifcd].flow; + pEdge->cap = fcd[ifcd].cap; + pEdge->pass = 0; + + /* Restore st-flow, cap */ + if (NO_VERTEX != ( v1 = fcd[ifcd].v1 )) + { + pBNS->vert[v1].st_edge.flow = fcd[ifcd].flow_st1; + pBNS->vert[v1].st_edge.cap = fcd[ifcd].cap_st1; + pBNS->vert[v1].st_edge.pass = 0; + } + if (NO_VERTEX != ( v2 = fcd[ifcd].v2 )) + { + pBNS->vert[v2].st_edge.flow = fcd[ifcd].flow_st2; + pBNS->vert[v2].st_edge.cap = fcd[ifcd].cap_st2; + pBNS->vert[v2].st_edge.pass = 0; + } + } + + return 0; +} + + +/****************************************************************************/ +int bSetFlowToCheckOneBond( BN_STRUCT *pBNS, + int iedge, + int flow, + BNS_FLOW_CHANGES *fcd ) +{ + BNS_EDGE *pEdge = pBNS->edge + iedge; + int f12 = ( pEdge->flow & EDGE_FLOW_MASK ); /* the original flow */ + int ifcd = 0; + int nDots = 0; + int i, iedge_i; + + fcd[ifcd].iedge = NO_VERTEX; + + if (f12 < flow) + { + /* Increase edge flow: Grab flow from the neighbors and delete it: set flow12=cap12 = 0 */ + /************************************************************************************/ + /* For example, simulate a new fixed double bond in place of a single bond and */ + /* creates ONE or NONE (in case of a radical on adjacent atom) augmenting paths and */ + /* makes it impossible for the BNS to set same flow as it originally was */ + /************************************************************************************/ + Vertex v1 = pEdge->neighbor1; + Vertex v2 = v1 ^ pEdge->neighbor12; + Vertex v_i; /* neighbor of v1 or v2 */ + BNS_EDGE *pEdge_i; + int delta1, delta2, f, st_edge_rescap; + + if (( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) < flow || + ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) < flow) + { + return BNS_CANT_SET_BOND; + } + if (( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ) < f12 || + ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ) < f12) + { + return BNS_CAP_FLOW_ERR; + } + + fcd[ifcd].iedge = iedge; + fcd[ifcd].flow = pEdge->flow; + fcd[ifcd].cap = pEdge->cap; + + fcd[ifcd].v1 = v1; + fcd[ifcd].flow_st1 = pBNS->vert[v1].st_edge.flow; + fcd[ifcd].cap_st1 = pBNS->vert[v1].st_edge.cap; + + fcd[ifcd].v2 = v2; + fcd[ifcd].flow_st2 = pBNS->vert[v2].st_edge.flow; + fcd[ifcd].cap_st2 = pBNS->vert[v2].st_edge.cap; + + fcd[++ifcd].iedge = NO_VERTEX; /* mark the end of the fcd[] data */ + pEdge->pass |= 64; + + delta1 = delta2 = flow - f12; + + if (f12 > 0) + { + /* Remove old edge flow from the flow and cap of the adjacent vertices' st-edges */ + pBNS->vert[v1].st_edge.cap = ( ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v1].st_edge.cap & ~EDGE_FLOW_ST_MASK ); + pBNS->vert[v2].st_edge.cap = ( ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v2].st_edge.cap & ~EDGE_FLOW_ST_MASK ); + pBNS->vert[v1].st_edge.flow = ( ( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v1].st_edge.flow & ~EDGE_FLOW_ST_MASK ); + pBNS->vert[v2].st_edge.flow = ( ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v2].st_edge.flow & ~EDGE_FLOW_ST_MASK ); + /* Delete current edge flow and capacity */ + pEdge->flow = ( pEdge->flow & ~EDGE_FLOW_MASK ); + } + pEdge->cap = ( pEdge->cap & ~EDGE_FLOW_MASK ); + + /* Grab the adjacent vertex1 radical (st_edge_rescap) if it exists */ + st_edge_rescap = ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) - ( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ); + while (st_edge_rescap && delta1) + { + st_edge_rescap--; /* grab the radical */ + delta1--; + pBNS->vert[v1].st_edge.cap = ( ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v1].st_edge.cap & ~EDGE_FLOW_ST_MASK ); + nDots--; + } + + /* Grab the adjacent vertex2 radical (st_edge_rescap) if it exists */ + st_edge_rescap = ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) - ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ); + while (st_edge_rescap && delta2) + { + st_edge_rescap--; /* grab the radical */ + delta2--; + pBNS->vert[v2].st_edge.cap = ( ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v2].st_edge.cap & ~EDGE_FLOW_ST_MASK ); + nDots--; + } + + /* Grab flows from v1 neighbors */ + for (i = 0; delta1 && i < pBNS->vert[v1].num_adj_edges; i++) + { + iedge_i = pBNS->vert[v1].iedge[i]; + if (iedge_i == iedge) + { + continue; + } + pEdge_i = pBNS->edge + iedge_i; + if (IS_FORBIDDEN( pEdge_i->forbidden, pBNS )) + { + continue; + } + f = ( pEdge_i->flow & EDGE_FLOW_MASK ); + if (f) + { + v_i = pEdge_i->neighbor12 ^ v1; + + fcd[ifcd].iedge = iedge_i; + fcd[ifcd].flow = pEdge_i->flow; + fcd[ifcd].cap = pEdge_i->cap; + + fcd[ifcd].v1 = v_i; + fcd[ifcd].flow_st1 = pBNS->vert[v_i].st_edge.flow; + fcd[ifcd].cap_st1 = pBNS->vert[v_i].st_edge.cap; + + fcd[ifcd].v2 = NO_VERTEX; + fcd[ifcd].flow_st2 = 0; + fcd[ifcd].cap_st2 = 0; + + fcd[++ifcd].iedge = NO_VERTEX; /* mark the end of the fcd[] data */ + pEdge_i->pass |= 64; + + while (f && delta1) + { + f--; + delta1--; + pEdge_i->flow = ( ( pEdge_i->flow & EDGE_FLOW_MASK ) - 1 ) | ( pEdge_i->flow & ~EDGE_FLOW_MASK ); + pBNS->vert[v_i].st_edge.flow = ( ( pBNS->vert[v_i].st_edge.flow & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v_i].st_edge.flow & ~EDGE_FLOW_ST_MASK ); + /* next 2 lines added 01-22-2002 */ + pBNS->vert[v1].st_edge.cap = ( ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v1].st_edge.cap & ~EDGE_FLOW_ST_MASK ); + pBNS->vert[v1].st_edge.flow = ( ( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v1].st_edge.flow & ~EDGE_FLOW_ST_MASK ); + + nDots++; + } + } + } + + /* Grab flows from v2 neighbors */ + for (i = 0; delta2 && i < pBNS->vert[v2].num_adj_edges; i++) + { + iedge_i = pBNS->vert[v2].iedge[i]; + if (iedge_i == iedge) + { + continue; + } + pEdge_i = pBNS->edge + iedge_i; + if (IS_FORBIDDEN( pEdge_i->forbidden, pBNS )) + { + continue; + } + f = ( pEdge_i->flow & EDGE_FLOW_MASK ); + if (f) + { + v_i = pEdge_i->neighbor12 ^ v2; + + fcd[ifcd].iedge = iedge_i; + fcd[ifcd].flow = pEdge_i->flow; + fcd[ifcd].cap = pEdge_i->cap; + + fcd[ifcd].v1 = v_i; + fcd[ifcd].flow_st1 = pBNS->vert[v_i].st_edge.flow; + fcd[ifcd].cap_st1 = pBNS->vert[v_i].st_edge.cap; + + fcd[ifcd].v2 = NO_VERTEX; + fcd[ifcd].flow_st2 = 0; + fcd[ifcd].cap_st2 = 0; + + fcd[++ifcd].iedge = NO_VERTEX; /* mark the end of the fcd[] data */ + pEdge_i->pass |= 64; + + while (f && delta2) + { + f--; + delta2--; + pEdge_i->flow = ( ( pEdge_i->flow & EDGE_FLOW_MASK ) - 1 ) | ( pEdge_i->flow & ~EDGE_FLOW_MASK ); + pBNS->vert[v_i].st_edge.flow = ( ( pBNS->vert[v_i].st_edge.flow & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v_i].st_edge.flow & ~EDGE_FLOW_ST_MASK ); + /* next 2 lines added 01-22-2002 */ + pBNS->vert[v2].st_edge.cap = ( ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v2].st_edge.cap & ~EDGE_FLOW_ST_MASK ); + pBNS->vert[v2].st_edge.flow = ( ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v2].st_edge.flow & ~EDGE_FLOW_ST_MASK ); + + nDots++; + } + } + } + if (delta1 || delta2) + { + return BNS_CANT_SET_BOND; + } + } + + if (f12 >= flow) + { + /* Decrease edge flow: Redirect flow to the neighbors and delete it on the edge: set flow12=cap12 = 0 */ + /* f12==flow fixes flow through the edge so that BNS cannot change it */ + /**********************************************************************************************/ + /* For example, simulate a removal of a double bond and create ONE or NONE augmenting path */ + /* Make it impossible for BNS to set same flow as it originally was */ + /**********************************************************************************************/ + Vertex v1 = pEdge->neighbor1; + Vertex v2 = ( v1 ^ pEdge->neighbor12 ); + int delta; + /* if NOT (st-cap >= st-flow >= f12 >= flow) then error in the BN structure */ + if (( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ) < f12 || + ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ) < f12 || + ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) < flow || + ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) < flow) + { + return BNS_CAP_FLOW_ERR; + } + fcd[ifcd].iedge = iedge; + fcd[ifcd].flow = pEdge->flow; + fcd[ifcd].cap = pEdge->cap; + + fcd[ifcd].v1 = v1; + fcd[ifcd].flow_st1 = pBNS->vert[v1].st_edge.flow; + fcd[ifcd].cap_st1 = pBNS->vert[v1].st_edge.cap; + + fcd[ifcd].v2 = v2; + fcd[ifcd].flow_st2 = pBNS->vert[v2].st_edge.flow; + fcd[ifcd].cap_st2 = pBNS->vert[v2].st_edge.cap; + + fcd[++ifcd].iedge = NO_VERTEX; /* mark the end of the fcd[] data */ + pEdge->pass |= 64; + + delta = f12 - flow; + + /* Remove current edge flow from st-edges */ + /* -- seem to be a bug -- + pBNS->vert[v1].st_edge.flow = ((pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK)-delta) | (pBNS->vert[v1].st_edge.flow & ~EDGE_FLOW_ST_MASK); + pBNS->vert[v2].st_edge.flow = ((pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK)-delta) | (pBNS->vert[v2].st_edge.flow & ~EDGE_FLOW_ST_MASK); + */ + + /* Replacement to the above 2 lines 01-16-2002 */ + /* Remove old edge flow from the flow of the adjacent vertices' st-edges */ + + pBNS->vert[v1].st_edge.flow = ( ( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v1].st_edge.flow & ~EDGE_FLOW_ST_MASK ); + pBNS->vert[v2].st_edge.flow = ( ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v2].st_edge.flow & ~EDGE_FLOW_ST_MASK ); + + /* Sdded 01-16-2002: reduce st-cap if new flow > 0 */ + /* Remove new edge flow from the cap of the adjacent vertices' st-edges */ + pBNS->vert[v1].st_edge.cap = ( ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) - flow ) | ( pBNS->vert[v1].st_edge.cap & ~EDGE_FLOW_ST_MASK ); + pBNS->vert[v2].st_edge.cap = ( ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) - flow ) | ( pBNS->vert[v2].st_edge.cap & ~EDGE_FLOW_ST_MASK ); + + /* delete current edge flow and capacity */ + pEdge->flow = ( pEdge->flow & ~EDGE_FLOW_MASK ); + pEdge->cap = ( pEdge->cap & ~EDGE_FLOW_MASK ); + nDots = 2 * delta; + } + + return nDots; +} + + +/**************************************************************************** +bAddNewVertex( ... ) + +Connect new (fictitious, temporary) vertex to nVertDoubleBond by a new edge +Add radical (set st-cap=1) to the new vertex, set cap=1 to the new edge +Add radical (set st-cap=1) to nVertSingleBond +Find augmenting path connecting new vertex to nVertSingleBond +This corresponds to moving H-atom from nVertSingleBond to nVertDoubleBond +****************************************************************************/ +int bAddNewVertex( BN_STRUCT *pBNS, + int nVertDoubleBond, + int nCap, + int nFlow, + int nMaxAdjEdges, + int *nDots ) +{ + Vertex vlast = pBNS->num_vertices - 1; + Vertex vnew = pBNS->num_vertices; + Vertex v2 = nVertDoubleBond; + BNS_VERTEX *pVert2 = pBNS->vert + v2; /* pointer to an old vertex */ + BNS_VERTEX *pNewVert = pBNS->vert + vnew; /* pointer to a new vertex */ + + EdgeIndex iedge = pBNS->num_edges; + BNS_EDGE *pEdge = pBNS->edge + iedge; /* pointer to a new edge */ + + if (iedge >= pBNS->max_edges || vnew >= pBNS->max_vertices) + { + return BNS_VERT_EDGE_OVFL; /* edges or vertices overflow */ + } + if (( pBNS->vert[vlast].iedge - pBNS->iedge ) + pBNS->vert[vlast].max_adj_edges + nMaxAdjEdges >= pBNS->max_iedges) + { + return BNS_VERT_EDGE_OVFL; /* iedges overflow */ + } + if (pVert2->num_adj_edges >= pVert2->max_adj_edges || nMaxAdjEdges <= 0) + { + return BNS_VERT_EDGE_OVFL; /* neighbors overflow */ + } + + /* Fill out the new edge, set its cap and flow, connect */ + /* memset( pEdge, 0, sizeof(*pEdge) ); */ + pEdge->cap = pEdge->cap0 = nCap; + pEdge->flow = pEdge->flow0 = nFlow; + pEdge->pass = 0; + pEdge->neighbor1 = v2; + pEdge->neighbor12 = v2 ^ vnew; + pEdge->forbidden = 0; + + /* Fill out the new vertex */ + /* memset( pNewVert, 0, sizeof(*pNewVert) ); */ + pNewVert->max_adj_edges = nMaxAdjEdges; + pNewVert->num_adj_edges = 0; + pNewVert->st_edge.cap0 = pNewVert->st_edge.cap = nCap; + pNewVert->st_edge.flow0 = pNewVert->st_edge.flow = nFlow; + pNewVert->st_edge.pass = 0; /* add initialization; added 2006-03-25 */ + pNewVert->iedge = pBNS->vert[vlast].iedge + pBNS->vert[vlast].max_adj_edges; + pNewVert->type = BNS_VERT_TYPE_TEMP; + *nDots += nCap - nFlow; + + pEdge->neigh_ord[v2 > vnew] = pVert2->num_adj_edges; + pEdge->neigh_ord[v2 < vnew] = pNewVert->num_adj_edges; + + /* Connect new edge to v2 */ + pVert2->iedge[pVert2->num_adj_edges++] = iedge; + /* Connect new edge to vnew */ + pNewVert->iedge[pNewVert->num_adj_edges++] = iedge; + + /* Fix v2 flow and cap */ + *nDots -= (int) pVert2->st_edge.cap - (int) pVert2->st_edge.flow; + pVert2->st_edge.flow += nFlow; + if (pVert2->st_edge.cap < pVert2->st_edge.flow) + { + pVert2->st_edge.cap = pVert2->st_edge.flow; + } + *nDots += (int) pVert2->st_edge.cap - (int) pVert2->st_edge.flow; + + pBNS->num_edges++; + pBNS->num_vertices++; + + return vnew; +} + + +/****************************************************************************/ +int AddNewEdge( BNS_VERTEX *p1, + BNS_VERTEX *p2, + BN_STRUCT *pBNS, + int nEdgeCap, + int nEdgeFlow ) +{ + int ip1 = (int) ( p1 - pBNS->vert ); + int ip2 = (int) ( p2 - pBNS->vert ); + int ie = pBNS->num_edges; + BNS_EDGE *e = pBNS->edge + ie; + + /* Debug: check bounds */ + if (ip1 >= pBNS->max_vertices || ip1 < 0 || + ip2 >= pBNS->max_vertices || ip2 < 0 || + ie >= pBNS->max_edges || ie < 0 || + ( p1->iedge - pBNS->iedge ) < 0 || + ( p1->iedge - pBNS->iedge ) + p1->max_adj_edges > pBNS->max_iedges || + ( p2->iedge - pBNS->iedge ) < 0 || + ( p2->iedge - pBNS->iedge ) + p2->max_adj_edges > pBNS->max_iedges || + p1->num_adj_edges >= p1->max_adj_edges || + p2->num_adj_edges >= p2->max_adj_edges) + { + return BNS_VERT_EDGE_OVFL; + } + + /* Clear the edge */ + memset( e, 0, sizeof( *e ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + + /* Connect */ + e->neighbor1 = inchi_min( ip1, ip2 ); + e->neighbor12 = ip1 ^ ip2; + p1->iedge[p1->num_adj_edges] = ie; + p2->iedge[p2->num_adj_edges] = ie; + e->neigh_ord[ip1 > ip2] = p1->num_adj_edges++; + e->neigh_ord[ip1 < ip2] = p2->num_adj_edges++; + e->cap = e->cap0 = nEdgeCap; + e->flow = e->flow0 = nEdgeFlow; + p1->st_edge.flow += nEdgeFlow; + p2->st_edge.flow += nEdgeFlow; + if (p1->st_edge.cap < p1->st_edge.flow) + { + p1->st_edge.cap = p1->st_edge.flow; + } + if (p2->st_edge.cap < p2->st_edge.flow) + { + p2->st_edge.cap = p2->st_edge.flow; + } + pBNS->num_edges++; + + return ie; +} + + +/****************************************************************************/ +BNS_IEDGE GetEdgeToGroupVertex( BN_STRUCT *pBNS, Vertex v1, AT_NUMB type ) +{ + if (v1 < pBNS->num_atoms) + { + Vertex v2; + BNS_EDGE *pEdge1; + BNS_VERTEX *pVert1 = pBNS->vert + v1; + int i = pVert1->num_adj_edges - 1; + + while (0 <= i) + { + pEdge1 = pBNS->edge + pVert1->iedge[i]; + v2 = pEdge1->neighbor12 ^ v1; + if (pBNS->vert[v2].type == type) + { + return IS_FORBIDDEN( pEdge1->forbidden, pBNS ) ? NO_VERTEX : pVert1->iedge[i]; + } + i--; + } + return NO_VERTEX; /* not found t-group */ + } + else + { + if (v1 < pBNS->num_vertices) + { + return NO_VERTEX; + } + } + + return BNS_VERT_EDGE_OVFL; +} + + +/****************************************************************************/ +Vertex GetGroupVertex( BN_STRUCT *pBNS, Vertex v1, AT_NUMB type ) +{ + if (v1 < pBNS->num_atoms) + { + Vertex v2; + BNS_EDGE *pEdge1; + BNS_VERTEX *pVert1 = pBNS->vert + v1; + int i = pVert1->num_adj_edges - 1; + + AT_NUMB type2; + + if (type == BNS_VERT_TYPE_ENDPOINT) + { + type2 = BNS_VERT_TYPE_TGROUP; + } + else + { + if (type == BNS_VERT_TYPE_C_POINT) + { + type2 = BNS_VERT_TYPE_C_GROUP; + } + else + { + type2 = 0; + } + } + + if (( pVert1->type & type ) == type) + { + while (0 <= i) + { + pEdge1 = pBNS->edge + pVert1->iedge[i]; + v2 = pEdge1->neighbor12 ^ v1; + if (pBNS->vert[v2].type == type2) + { + if (IS_FORBIDDEN( pEdge1->forbidden, pBNS )) + { + return NO_VERTEX; + } + return v2; + } + i--; + } + } + return BNS_BOND_ERR; /* not found t-group */ + } + else + { + if (v1 < pBNS->num_vertices) + { + return NO_VERTEX; + } + } + + return BNS_VERT_EDGE_OVFL; +} + + +/****************************************************************************/ +int bAddStCapToAVertex( BN_STRUCT *pBNS, + Vertex v1, + Vertex v2, + VertexFlow *nOldCapVertSingleBond, + int *nDots, + int bAdjacentDonors ) +{ + BNS_VERTEX *pVert1 = pBNS->vert + v1; + BNS_VERTEX *pVert; + BNS_EDGE *pEdge; + Vertex v; + int i, n; + VertexFlow nNewCap; + + /* Change v1: increment its st-cap */ + n = 0; + nOldCapVertSingleBond[n++] = pVert1->st_edge.cap; + /*if ( pVert1->st_edge.cap == pVert1->st_edge.flow ) {*/ + pVert1->st_edge.cap++; + *nDots += 1; + + /*}*/ + /* increment caps of adjacent edges if + (1) the neighbor has st-cap != 0 and + (2) (edge cap==0) OR (nSumEdgeCap < pVert1->st_edge.cap && pVert->st_edge.flow > pVert1->st_edge.cap) + */ + if (!( pVert1->type & BNS_VERT_TYPE_ANY_GROUP )) + { + /* + AT_NUMB nSumEdgeCap = 0; + for ( i = 0; i < pVert1->num_adj_edges; i ++ ) { + pEdge = pBNS->edge + pVert1->iedge[i]; + nSumEdgeCap += pEdge->cap; + } + */ + /* do not increment caps of t-group or c-group edges */ + for (i = 0; i < pVert1->num_adj_edges; i++) + { + pEdge = pBNS->edge + pVert1->iedge[i]; + nOldCapVertSingleBond[n++] = pEdge->cap; /* save edge cap */ + v = pEdge->neighbor12 ^ v1; + if (v == v2 && !bAdjacentDonors) + { + continue; + } + pVert = pBNS->vert + v; + if (pVert->type & BNS_VERT_TYPE_ANY_GROUP) + continue; + nNewCap = inchi_min( pVert->st_edge.cap, pVert1->st_edge.cap ); + nNewCap = inchi_min( nNewCap, MAX_BOND_EDGE_CAP ); + pEdge->cap = nNewCap; /* change edge cap */ + /* + if ( pVert->st_edge.cap > 0 && !pEdge->cap ) { + pEdge->cap ++; + } else + if ( pVert->st_edge.flow > pVert1->st_edge.cap && + pEdge->cap < MAX_BOND_EDGE_CAP && + nSumEdgeCap < pVert1->st_edge.cap ) { + pEdge->cap ++; + } + */ + } + } + + return n; /* number of elements in nOldCapVertSingleBond[*] */ +} + + +#define BNS_CHK_ALTP_NO_ALTPATH 0 +#define BNS_CHK_ALTP_SAME_TGROUP 1 +#define BNS_CHK_ALTP_SAME_VERTEX 2 +#define BNS_CHK_ALTP_SET_SUCCESS 4 + + +/****************************************************************************/ +int bSetBnsToCheckAltPath( BN_STRUCT *pBNS, + int nVertDoubleBond, + int nVertSingleBond, + AT_NUMB type, + int path_type, + ALT_PATH_CHANGES *apc, + BNS_FLOW_CHANGES *fcd, + int *nDots ) +{ + + if (!pBNS->vert[nVertDoubleBond].st_edge.flow && + + !( path_type == ALT_PATH_MODE_REM2H_CHG || + path_type == ALT_PATH_MODE_ADD2H_CHG || + path_type == ALT_PATH_MODE_REM2H_TST || + path_type == ALT_PATH_MODE_ADD2H_TST ) + ) + { + return BNS_CHK_ALTP_NO_ALTPATH; + } + else + { + Vertex vNew; + Vertex v1 = nVertSingleBond; + Vertex v2 = nVertDoubleBond; + + BNS_VERTEX *pVert1 = pBNS->vert + v1; + BNS_VERTEX *pVert2 = pBNS->vert + v2; + int n, bAdjacentDonors = 0; + int ifcd = 0; + + Vertex t1 = NO_VERTEX; + Vertex t2 = NO_VERTEX; + int iapc; + + /*#if ( TEST_REMOVE_S_ATOMS == 1 )*/ /* && ALT_PATH_MODE_4_SALT == path_type */ + if (( *pBNS->pbTautFlags & TG_FLAG_TEST_TAUT2_SALTS ) && + ALT_PATH_MODE_4_SALT2 == path_type && + ( BNS_VERT_TYPE_ENDPOINT & type )) + { + /* + --------------------------------------------------------- + \ action | DB action (v2) | SB action (v1) | + vertex \ | accept H @ vertex | donate H @ vertex | + type \ | nVertDoubleBond | nVertSingleBond | + ----------------+-------------------+-------------------+ + -ZH (v1) | error | -ZH(.) | + (cap>0 on edge | | increment | + except v1-v2) | | st-cap on Z | + ----------------+-------------------+-------------------+ + =Z (v2) | =Z-(.) | error | + (st-flow>0) | add fict vertex | | + | with st-cap=1 | | + ----------------+-------------------+-------------------+ + endpoint | T(.) | T-(.) | + of t-group | increment | add fict vertex | + represented | st-cap on T | with st-cap=1 | + by fictitious | | | + vertex T | | | + --------------------------------------------------------- + */ + + int bSet_v1; /* indicator: v1 has been set */ + int bSet_v2; /* indicator: v2 has been set */ + int i; + + Vertex v1t = NO_VERTEX; + Vertex v2t = NO_VERTEX; + Vertex v1Act, v2Act; + Vertex v; + + memset( apc, 0, sizeof( *apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + fcd[ifcd].iedge = NO_VERTEX; + *nDots = 0; + + if (v1 == v2) + { + return BNS_CHK_ALTP_SAME_VERTEX; + } + + /* Check whether v1 has neighbors adjacent to multiple bonds */ + for (i = 0, n = 0; i < pVert1->num_adj_edges; i++) + { + v = ( pBNS->edge + pVert1->iedge[i] )->neighbor12 ^ v1; /* v is adjacent to v1 */ + if (v == v2) + { + continue; /* ignore connection to v2 */ + } + n += ( pBNS->vert[v].st_edge.cap > 0 ); + } + if (!n) + { + return BNS_CHK_ALTP_NO_ALTPATH; /* the vertex cannot have flow */ + } + + v1Act = v1; + v2Act = v2; + + /* find t-group that contains v1 */ + if (( pVert1->type & type ) == type) + { + v1t = GetGroupVertex( pBNS, v1, type ); + if (IS_BNS_ERROR( v1t )) + { + return v1t; + } + if (v1t != NO_VERTEX) + { + v1Act = v1t; + } + } + /* Find t-group that contains v2 */ + if (( pVert2->type & type ) == type) + { + v2t = GetGroupVertex( pBNS, v2, type ); + if (IS_BNS_ERROR( v2t )) + { + return v2t; + } + if (v2t != NO_VERTEX) + { + v2Act = v2t; + } + } + if (v1t != NO_VERTEX && v1t == v2t) + { + return BNS_CHK_ALTP_SAME_TGROUP; + } + + bSet_v1 = bSet_v2 = 0; + /* create new edges adjacent to v1t or v2 */ + iapc = 0; + if (v1t != NO_VERTEX) + { + /* Create new edge and vertex, connect to v1t */ + vNew = bAddNewVertex( pBNS, v1t, 1, 0, 1, nDots ); + if (IS_BNS_ERROR( vNew )) + { + return vNew; + } + apc->vNewVertex[iapc] = vNew; + apc->bSetNew[iapc] = 1; + bSet_v1 = 1; + iapc++; + } + if (v2t == NO_VERTEX) + { + /* Create new edge and vertex, connect to v2 */ + vNew = bAddNewVertex( pBNS, v2, 1, 0, 1, nDots ); + if (IS_BNS_ERROR( vNew )) + { + return vNew; + } + apc->vNewVertex[iapc] = vNew; + apc->bSetNew[iapc] = 1; + bSet_v2 = 1; + iapc++; + } + + /* Add st-cap to v1 and/or v2t */ + iapc = 0; + if (!bSet_v1) + { + /* Add st-cap to v1 */ + if (v1t != NO_VERTEX) /* djb-rwth: addressing coverity CID #499551 -- condition properly written */ + { + return BNS_BOND_ERR; + } + n = bAddStCapToAVertex( pBNS, v1, v2Act, apc->nOldCapsVert[iapc], nDots, 0 ); + apc->bSetOldCapsVert[iapc] = n; + apc->vOldVert[iapc] = v1; + iapc++; + } + if (!bSet_v2) + { + /* Add st-cap to v2t */ + if (v2t == NO_VERTEX) + { + return BNS_BOND_ERR; + } + n = bAddStCapToAVertex( pBNS, v2t, v1Act, apc->nOldCapsVert[iapc], nDots, 0 ); + apc->bSetOldCapsVert[iapc] = n; + apc->vOldVert[iapc] = v2t; + iapc++; + } + if (*nDots < 0 || *nDots % 2) + { + return BNS_SET_ALTP_ERR; + } + return BNS_CHK_ALTP_SET_SUCCESS; + } + + /* ( *pBNS->pbTautFlags & TG_FLAG_TEST_TAUT2_SALTS ) */ + + /*#endif*/ + + /* ( TEST_REMOVE_S_ATOMS == 1 && ALT_PATH_MODE_4_SALT == path_type ) */ + + if (path_type == ALT_PATH_MODE_REM2H_CHG || + path_type == ALT_PATH_MODE_ADD2H_CHG || + path_type == ALT_PATH_MODE_REM2H_TST || + path_type == ALT_PATH_MODE_ADD2H_TST) + { + /* added 2004-03-18 */ + + int bDonors = ( path_type == ALT_PATH_MODE_REM2H_CHG ) || ( path_type == ALT_PATH_MODE_REM2H_TST ); + + int bSet_v1; /* indicator: v1 has been set */ + int bSet_v2; /* indicator: v2 has been set */ + int i, cap = 1; + Vertex v1t = NO_VERTEX; + Vertex v2t = NO_VERTEX; + Vertex v1Act, v2Act; + Vertex v; + + memset( apc, 0, sizeof( *apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + fcd[ifcd].iedge = NO_VERTEX; + *nDots = 0; + /* + if ( v1 == v2 ) { + return BNS_CHK_ALTP_SAME_VERTEX; + } + */ + + /* Check whether v1 and v2 have proper neighbors */ + for (i = 0, n = bAdjacentDonors = 0; i < pVert1->num_adj_edges; i++) + { + v = ( pBNS->edge + pVert1->iedge[i] )->neighbor12 ^ v1; /* v is adjacent to v1 */ + /* do not ignore connection to v2 + if ( v == v2 ) + continue; + */ + n += bDonors ? ( pBNS->vert[v].st_edge.cap > 0 ) + : ( ( pBNS->edge + pVert1->iedge[i] )->flow > 0 ); + bAdjacentDonors += bDonors ? ( v == v2 ) && ( ( pBNS->edge + pVert1->iedge[i] )->flow < MAX_BOND_EDGE_CAP ) : 0; + /* two donors connected by a single or double bond */ + } + + if (!n && !bAdjacentDonors) + { + return BNS_CHK_ALTP_NO_ALTPATH; /* the vertex cannot have flow */ + } + for (i = 0, n = bAdjacentDonors = 0; i < pVert2->num_adj_edges; i++) + { + v = ( pBNS->edge + pVert2->iedge[i] )->neighbor12 ^ v2; /* v is adjacent to v2 */ + /* do not ignore connection to v1 + if ( v == v1 ) + continue; + */ + n += bDonors ? ( pBNS->vert[v].st_edge.cap > 0 ) : ( ( pBNS->edge + pVert2->iedge[i] )->flow > 0 ); + bAdjacentDonors += bDonors ? ( v == v1 ) && ( ( pBNS->edge + pVert2->iedge[i] )->flow < MAX_BOND_EDGE_CAP ) : 0; + /* two donors connected by a single or double bond */ + } + + if (!n && !bAdjacentDonors) + { + return BNS_CHK_ALTP_NO_ALTPATH; /* the vertex cannot have flow */ + } + + v1Act = v1; + v2Act = v2; + + /* Find t-group that contains v1 */ + if (( pVert1->type & type ) == type) + { + v1t = GetGroupVertex( pBNS, v1, type ); + if (BNS_BOND_ERR == v1t) + { + v1t = NO_VERTEX; + } + else + { + if (IS_BNS_ERROR( v1t )) + { + return v1t; + } + else + { + if (v1t != NO_VERTEX) + { + v1Act = v1t; + } + } + } + } + + /* Find t-group that contains v2 */ + if (( pVert2->type & type ) == type) + { + v2t = GetGroupVertex( pBNS, v2, type ); + if (BNS_BOND_ERR == v2t) + { + v2t = NO_VERTEX; + } + else + { + if (IS_BNS_ERROR( v2t )) + { + return v2t; + } + else + { + if (v2t != NO_VERTEX) + { + v2Act = v2t; + } + } + } + } + + if (v1t != NO_VERTEX && v1t == v2t) + { + cap = 2; /* same t-group */ + } + + /* bAddNewVertex: (bDonors != 0) == (vit != NO_VERTEX), i=1,2 */ + bSet_v1 = bSet_v2 = 0; + /* create new edges adjacent to v1t or v2 */ + iapc = 0; + if (( bDonors != 0 ) == ( v1t != NO_VERTEX )) + { + /* Create new edge and vertex, connect to v1Act */ + vNew = bAddNewVertex( pBNS, v1Act, cap, 0, 1, nDots ); + if (IS_BNS_ERROR( vNew )) + { + return vNew; + } + apc->vNewVertex[iapc] = vNew; + apc->bSetNew[iapc] = 1; + bSet_v1 = 1; + iapc++; + } + if (( bDonors != 0 ) == ( v2t != NO_VERTEX ) && cap == 1) + { + /* Create new edge and vertex, connect to v2Act; do not do it if cap==2 */ + vNew = bAddNewVertex( pBNS, v2Act, cap, 0, 1, nDots ); + if (IS_BNS_ERROR( vNew )) + { + return vNew; + } + apc->vNewVertex[iapc] = vNew; + apc->bSetNew[iapc] = 1; + bSet_v2 = 1; + iapc++; + } + else + { + if (( bDonors != 0 ) == ( v2t != NO_VERTEX )) + { + bSet_v2 = 1; + } + } + + /* Add st-cap to v1 and/or v2t */ + iapc = 0; + /* If cap=2 then just increment st_cap 2 times */ + if (!bSet_v1) + { + /* Add st-cap to v1 */ + if (( bDonors != 0 ) == ( v1t != NO_VERTEX )) + { + return BNS_BOND_ERR; + } + n = bAddStCapToAVertex( pBNS, v1Act, v2Act, apc->nOldCapsVert[iapc], nDots, bAdjacentDonors ); + apc->bSetOldCapsVert[iapc] = n; + apc->vOldVert[iapc] = v1Act; + iapc++; + } + if (!bSet_v2) + { + /* Add st-cap to v2t */ + if (( bDonors != 0 ) == ( v2t != NO_VERTEX )) + { + return BNS_BOND_ERR; + } + n = bAddStCapToAVertex( pBNS, v2Act, v1Act, apc->nOldCapsVert[iapc], nDots, bAdjacentDonors ); + apc->bSetOldCapsVert[iapc] = n; + apc->vOldVert[iapc] = v2Act; + iapc++; + } + if (*nDots < 0 || *nDots % 2) + { + return BNS_SET_ALTP_ERR; + } + return BNS_CHK_ALTP_SET_SUCCESS; + } + + if (path_type == ALT_PATH_MODE_REM_PROTON) + { + /* added 2004-03-05 */ + if (v1 >= 0 && v2 >= 0 && + ( pVert1->type & BNS_VERT_TYPE_ANY_GROUP ) && + ( pVert2->type & BNS_VERT_TYPE_ANY_GROUP )) + { + /* Create new edge and vertex, connect to v2 */ + if (( pBNS->vert[v1].type & BNS_VERT_TYPE_C_GROUP ) && + ( pBNS->vert[v1].st_edge.flow == 2 * pBNS->vert[v1].num_adj_edges )) + { + /* so far in a charge group max edge flow = 1 2004-03-08 */ + return BNS_CHK_ALTP_NO_ALTPATH; + } + memset( apc, 0, sizeof( *apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + fcd[ifcd].iedge = NO_VERTEX; + *nDots = 0; + iapc = 0; + + vNew = bAddNewVertex( pBNS, v2, 1, 0, 1, nDots ); + if (IS_BNS_ERROR( vNew )) + { + return vNew; + } + apc->vNewVertex[iapc] = vNew; + apc->bSetNew[iapc] = 1; + /*iapc ++;*/ + /* add st-cap (dot) to v1 */ + n = bAddStCapToAVertex( pBNS, v1, v2, apc->nOldCapsVert[iapc], nDots, 0 ); + apc->bSetOldCapsVert[iapc] = n; + apc->vOldVert[iapc] = v1; + iapc++; + return BNS_CHK_ALTP_SET_SUCCESS; + } + } + +#if ( NEUTRALIZE_ENDPOINTS == 1 ) /* { */ + + *nDots = 0; + memset( apc, 0, sizeof( *apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + fcd[ifcd].iedge = NO_VERTEX; + + if (type & BNS_VERT_TYPE_ENDPOINT) + { + BNS_IEDGE iedge; + AT_NUMB type2; + int ret2; + /* prohibit charge movement */ + type2 = BNS_VERT_TYPE_C_GROUP; + iedge = GetEdgeToGroupVertex( pBNS, v1, type2 ); + if (iedge != NO_VERTEX) + { + /* Set flow=1 on an edge to a c-group vertex to make sure + there is no positive charge when moving tautomeric H-atoms */ + ret2 = bSetFlowToCheckOneBond( pBNS, iedge, 1, fcd + ifcd ); + if (IS_BNS_ERROR( ret2 )) + { + return ret2; + } + *nDots += ret2; + while (fcd[ifcd].iedge != NO_VERTEX) + { + ifcd++; + } + } + + iedge = GetEdgeToGroupVertex( pBNS, v2, type2 ); + + if (iedge != NO_VERTEX) + { + /* Set flow=1 on an edge to a c-group vertex to make sure + there is no positive charge when moving tautomeric H-atoms */ + + ret2 = bSetFlowToCheckOneBond( pBNS, iedge, 1, fcd + ifcd ); + + if (IS_BNS_ERROR( ret2 )) + { + return ret2; + } + *nDots += ret2; + while (fcd[ifcd].iedge != NO_VERTEX) + { + ifcd++; + } + } + + /* Set hydrogen counts */ + type2 = BNS_VERT_TYPE_TGROUP; + iedge = GetEdgeToGroupVertex( pBNS, v1, type2 ); + if (iedge != NO_VERTEX) + { + /* Set flow=1 on an edge to a t-group vertex to make sure there is + a moveable hydrogen atom or (-) on v1 when moving tautomeric H-atoms */ +#if ( FIX_H_CHECKING_TAUT == 1 ) + ret2 = bSetFlowToCheckOneBond( pBNS, iedge, 1, fcd + ifcd ); + if (IS_BNS_ERROR( ret2 )) + { + return ret2; + } + *nDots += ret2; + while (fcd[ifcd].iedge != NO_VERTEX) + { + ifcd++; + } +#else + t1 = pBNS->edge[iedge].neighbor12 ^ v1; +#endif + } + + iedge = GetEdgeToGroupVertex( pBNS, v2, type2 ); + if (iedge != NO_VERTEX) + { + /* Set flow=0 on an edge to a t-group vertex to make sure there is + no moveable hydrogen atom or (-) on v2 when moving tautomeric H-atoms */ +#if ( FIX_H_CHECKING_TAUT == 1 ) + ret2 = bSetFlowToCheckOneBond( pBNS, iedge, 0, fcd + ifcd ); + if (IS_BNS_ERROR( ret2 )) + { + return ret2; + } + *nDots += ret2; + while (fcd[ifcd].iedge != NO_VERTEX) + { + ifcd++; + } +#else + t2 = pBNS->edge[iedge].neighbor12 ^ v2; +#endif + } + +#if ( FIX_H_CHECKING_TAUT == 1 ) +#else + if (t1 == t2 && t1 != NO_VERTEX) + { + return BNS_CHK_ALTP_SAME_TGROUP; + } +#endif + + iapc = 0; + /* Create new edge and vertex with cap=1 at v2 and/or t1 */ + if (t1 != NO_VERTEX) + { + /* Create new edge and vertex, connect to t1 */ + vNew = bAddNewVertex( pBNS, t1, 1/*cap*/, 0/*flow*/, 1/*max_adj_edges*/, nDots ); + if (IS_BNS_ERROR( vNew )) + { + return vNew; + } + apc->vNewVertex[iapc] = vNew; + apc->bSetNew[iapc] = 1; + iapc++; + } + if (t2 == NO_VERTEX) + { + /* Create new edge and vertex, connect to v2 */ + vNew = bAddNewVertex( pBNS, v2, 1/*cap*/, 0/*flow*/, 1/*max_adj_edges*/, nDots ); + if (IS_BNS_ERROR( vNew )) + { + return vNew; + } + apc->vNewVertex[iapc] = vNew; + apc->bSetNew[iapc] = 1; + iapc++; + } + + /* Add st-cap to v1 and/or v2t */ + iapc = 0; + if (t1 == NO_VERTEX) + { + /* Add st-cap to v1 */ + n = bAddStCapToAVertex( pBNS, v1, (Vertex) ( t2 == NO_VERTEX ? v2 : t2 ), apc->nOldCapsVert[iapc], nDots, 0 ); /* djb-rwth: addressing coverity CID #499501 -- condition works as expected for t2 == -2 */ + apc->bSetOldCapsVert[iapc] = n; + apc->vOldVert[iapc] = v1; + iapc++; + } + if (t2 != NO_VERTEX) + { + /* Add st-cap to t2 */ + n = bAddStCapToAVertex( pBNS, t2, (Vertex) ( t1 == NO_VERTEX ? v1 : t1 ), apc->nOldCapsVert[iapc], nDots, 0 ); + apc->bSetOldCapsVert[iapc] = n; + apc->vOldVert[iapc] = t2; + iapc++; + } + } + else + { + /* Create new edge and vertex, connect to v2 */ + vNew = bAddNewVertex( pBNS, v2, 1 /* cap*/, 0 /* flow */, 1 /* max_adj_edges */, nDots ); + if (IS_BNS_ERROR( vNew )) + { + return vNew; + } + apc->vNewVertex[0] = vNew; + apc->bSetNew[0] = 1; + + /* add st-cap to v1 */ + n = bAddStCapToAVertex( pBNS, v1, v2, apc->nOldCapsVert[0], nDots, 0 ); + apc->bSetOldCapsVert[0] = n; + apc->vOldVert[0] = v1; + } +#else /* } NEUTRALIZE_ENDPOINTS == 0 {*/ + + *nDots = 0; + memset( apc, 0, sizeof( *apc ) ); + fcd[ifcd].iedge = NO_VERTEX; + + /* Create new edge and vertex, connect to v2 */ + vNew = bAddNewVertex( pBNS, v2, 1 /* cap*/, 0 /* flow */, 1 /* max_adj_edges */, nDots, 0 ); + if (IS_BNS_ERROR( vNew )) + { + return vNew; + } + apc->vNewVertex[0] = vNew; + apc->bSetNew[0] = 1; + + /* Add st-cap to v1 */ + n = bAddStCapToAVertex( pBNS, v1, v2, apc->nOldCapsVert[0], nDots ); + apc->bSetOldCapsVert[0] = n; + apc->vOldVert[0] = v1; +#endif /* } NEUTRALIZE_ENDPOINTS */ + + if (*nDots < 0 || *nDots % 2) + { + return BNS_SET_ALTP_ERR; + } + return BNS_CHK_ALTP_SET_SUCCESS; + } + + /*return BNS_CHK_ALTP_NO_ALTPATH;*/ +} + + +/****************************************************************************/ +int bRestoreBnsAfterCheckAltPath( BN_STRUCT *pBNS, + ALT_PATH_CHANGES *apc, + int bChangeFlow ) + /* int nVertDoubleBond, int nVertSingleBond, int nNewVertex, AT_NUMB *nOldCapVertSingleBond */ +{ + BNS_EDGE *pEdge; + Vertex vNew; + Vertex vOld; + BNS_VERTEX *pOldVert; + BNS_VERTEX *pNewVert; + int i, j, n; /* djb-rwth: removing redundant variables */ + + /* djb-rwth: removing redundant code */ + + if (bChangeFlow & BNS_EF_UPD_H_CHARGE) + { + /* Remove new temp. vertices and edges connectong them to the structure */ + for (i = sizeof( apc->bSetNew ) / sizeof( apc->bSetNew[0] ) - 1; 0 <= i; i--) + { + if (apc->bSetNew[i]) + { + vNew = apc->vNewVertex[i]; + pNewVert = pBNS->vert + vNew; + for (j = 0; j < pNewVert->num_adj_edges; j++) + { + pEdge = pBNS->edge + pNewVert->iedge[j]; + vOld = pEdge->neighbor12 ^ vNew; + pOldVert = pBNS->vert + vOld; + pOldVert->st_edge.flow -= pEdge->flow; + pOldVert->st_edge.cap -= pEdge->flow; + /* disconnect new edge from pOldVert */ + pOldVert->iedge[--pOldVert->num_adj_edges] = 0; + /* clear the new edge */ + memset( pEdge, 0, sizeof( *pEdge ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + /* and decrement the total number of edges */ + pBNS->num_edges--; + } + /* Clear the new vertex */ + memset( pNewVert, 0, sizeof( *pNewVert ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + /* and decrement the total number of vertices + (new vertice ids are contiguous) */ + pBNS->num_vertices--; + /* djb-rwth: removing redundant code */ + } + } + + /* Restore changed caps of old vertices */ + for (i = sizeof( apc->bSetOldCapsVert ) / sizeof( apc->bSetOldCapsVert[0] ) - 1; + 0 <= i; + i--) + { + if ((n = apc->bSetOldCapsVert[i])) /* djb-rwth: addressing LLVM warning */ + { + pOldVert = pBNS->vert + apc->vOldVert[i]; + if (pOldVert->st_edge.flow <= apc->nOldCapsVert[i][0]) + { + pOldVert->st_edge.cap = apc->nOldCapsVert[i][0]; + n--; + /* djb-rwth: removing redundant code */ + for (j = 0; j < n && j < pOldVert->num_adj_edges; j++) + { + pEdge = pBNS->edge + pOldVert->iedge[j]; + pEdge->cap = apc->nOldCapsVert[i][j + 1]; + } + } + } + } + } + else + { + /* Restore changed caps of old vertices */ + for (i = sizeof( apc->bSetOldCapsVert ) / sizeof( apc->bSetOldCapsVert[0] ) - 1; 0 <= i; i--) + { + if ((n = apc->bSetOldCapsVert[i])) /* djb-rwth: addressing LLVM warning */ + { + pOldVert = pBNS->vert + apc->vOldVert[i]; + pOldVert->st_edge.cap = apc->nOldCapsVert[i][0]; + n--; + /* djb-rwth: removing redundant code */ + for (j = 0; j < n && j < pOldVert->num_adj_edges; j++) + { + pEdge = pBNS->edge + pOldVert->iedge[j]; + pEdge->cap = apc->nOldCapsVert[i][j + 1]; + } + } + } + + /* Remove new temp. vertices and edges connectong them to the structure */ + for (i = sizeof( apc->bSetNew ) / sizeof( apc->bSetNew[0] ) - 1; 0 <= i; i--) + { + if (apc->bSetNew[i]) + { + vNew = apc->vNewVertex[i]; + pNewVert = pBNS->vert + vNew; + for (j = 0; j < pNewVert->num_adj_edges; j++) + { + pEdge = pBNS->edge + pNewVert->iedge[j]; + vOld = pEdge->neighbor12 ^ vNew; + pOldVert = pBNS->vert + vOld; + /* disconnect new edge from pOldVert */ + pOldVert->iedge[--pOldVert->num_adj_edges] = 0; + /* clear the new edge */ + memset( pEdge, 0, sizeof( *pEdge ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + /* and decrement the total number of edges */ + pBNS->num_edges--; + } + /* Clear the new vertex */ + memset( pNewVert, 0, sizeof( *pNewVert ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + /* and decrement the total number of vertices (new vertice ids are contiguous */ + pBNS->num_vertices--; + /* djb-rwth: removing redundant code */ + } + } + } + + return 0; +} + + +/****************************************************************************/ +int bExistsAnyAltPath( CANON_GLOBALS *pCG, + BN_STRUCT *pBNS, + BN_DATA *pBD, + inp_ATOM *at, + int num_atoms, + int nVert2, + int nVert1, + int path_type ) +{ + int nRet1, nRet2; + + nRet1 = bExistsAltPath( pCG, pBNS, pBD, NULL, at, num_atoms, nVert2, nVert1, path_type ); + + if (nRet1 > 0) + { + return nRet1; + } + + nRet2 = bExistsAltPath( pCG, pBNS, pBD, NULL, at, num_atoms, nVert1, nVert2, path_type ); + + if (nRet2 > 0) + { + return nRet2; + } + if (IS_BNS_ERROR( nRet1 )) + { + return nRet1; + } + if (IS_BNS_ERROR( nRet2 )) + { + return nRet2; + } + + return 0; +} + + +#define ALT_PATH_TAUTOM 1 +#define ALT_PATH_CHARGE 2 +#define ALT_PATH_4_SALT 3 + + +/****************************************************************************/ +int bIsBnsEndpoint( BN_STRUCT *pBNS, int v ) +{ + int i, vt; + BNS_VERTEX *pVert; /* vertices */ + BNS_EDGE *pEdge; /* edges */ + + if (0 <= v && v < pBNS->num_atoms && ( pVert = pBNS->vert + v ) && ( pVert->type & BNS_VERT_TYPE_ENDPOINT )) + { + for (i = pVert->num_adj_edges - 1; 0 <= i; i--) + { + pEdge = pBNS->edge + pVert->iedge[i]; + vt = pEdge->neighbor12 ^ v; + if (pBNS->vert[vt].type & BNS_VERT_TYPE_TGROUP) + { + return !IS_FORBIDDEN( pEdge->forbidden, pBNS ); + } + } + } + + return 0; +} + + +#if ( BNS_RAD_SEARCH == 1 ) + + +/****************************************************************************/ +int bRadChangesAtomType( BN_STRUCT *pBNS, + BN_DATA *pBD, + Vertex v, + Vertex v_1, + Vertex v_2 ) +{ + + EdgeIndex iuv; + Vertex v_O, v_ChgOrH; + + /* The previous atom along the path: should be a terminal atom */ + if (v_1 == NO_VERTEX) + { + v_1 = GetPrevVertex( pBNS, v, pBD->SwitchEdge, &iuv ); + } + v_O = v_1 / 2 - 1; + + if (v_O < 0 || v_O >= pBNS->num_atoms) + { + return 0; + } + + /* Make sure v_O is a terminal atom: its second neighbor is not an atom */ + if (pBNS->vert[pBNS->edge[pBNS->vert[v_O].iedge[1]].neighbor12 ^ v_O].type & BNS_VERT_TYPE_ATOM) + { + return 0; + } + + /* The next to previous vertex vertex along the path: should be a Charge or Taut group vertex */ + if (v_2 == NO_VERTEX) + { + v_2 = GetPrevVertex( pBNS, v_1, pBD->SwitchEdge, &iuv ); + } + + v_ChgOrH = v_2 / 2 - 1; + if (v_ChgOrH < pBNS->num_atoms) + { + return 0; + } + + /* Make sure v_ChgOrH is a charge or taut_group */ + if (pBNS->vert[v_ChgOrH].type & ( BNS_VERT_TYPE_TGROUP | BNS_VERT_TYPE_C_GROUP )) + { + return 1; + } + + return 0; +} + + +/****************************************************************************/ +int RegisterRadEndpoint( BN_STRUCT *pBNS, BN_DATA *pBD, Vertex u ) +{ + EdgeIndex iuv; + int i, num_found; + Vertex v, w; + Vertex u_last, v2; + switch (pBD->bRadSrchMode) + { + case RAD_SRCH_NORM: + /* Go backwards along alt path and stop at the 1st found atom (not a fictitious vertex) */ + /* we need only vertices where a radical may be moved, therefore exclude u%2=1 (odd) vertices */ + /* atom number = u/2-1; u = 0 or 1 is 's' or 't' vertices, respectively, they are not atoms */ + num_found = 0; + while (u > Vertex_t && ( u % 2 || u / 2 > pBNS->num_atoms )) + { + u = GetPrevVertex( pBNS, u, pBD->SwitchEdge, &iuv ); + } + w = u / 2 - 1; /* Check whether u is a radical endpoint */ + if (Vertex_t < u && w < pBNS->num_atoms && + pBNS->vert[w].st_edge.cap == ( pBNS->vert[w].st_edge.flow & EDGE_FLOW_ST_MASK )) + { + /* u is an atom; it is not a radical atom */ + /* now search for the starting radical atom by following the path back from u */ + v = u_last = u; + while (v > Vertex_t) + { + u = v; + v = GetPrevVertex( pBNS, u, pBD->SwitchEdge, &iuv ); /* Radical endpoint */ + } + /* Check whether u is a radical atom */ + if (!( u % 2 ) && Vertex_t < u && + ( u = u / 2 - 1 ) < pBNS->num_atoms && + pBNS->vert[u].st_edge.cap > ( pBNS->vert[u].st_edge.flow & EDGE_FLOW_ST_MASK )) + { + /* at pBNS->vert[u] we have found the radical that originated the path */ + /* pBD->RadEndpoints[2k] is the radical, pBD->RadEndpoints[2k+1] is the farthest atom */ + /* to which the radical may be moved (farthest reachable atom) */ + + /* add *all* atoms that may receive radical from u_rad */ + /* exception: at2 in: ==(+/-/H)---at1==at2(possible rad endpoint) if pBNS->type_TACN */ + for (v = u_last; v > Vertex_t; v = GetPrevVertex( pBNS, v, pBD->SwitchEdge, &iuv )) + { + if (!( v % 2 ) && ( v2 = v / 2 - 1 ) < pBNS->num_atoms && + pBNS->vert[v2].st_edge.cap == ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK )) + { + /* Check exception */ + if (pBNS->type_TACN && + bRadChangesAtomType( pBNS, pBD, v, NO_VERTEX, NO_VERTEX )) + { + continue; + } + /* Add */ + for (i = 0; i < pBD->nNumRadEndpoints; i += 2) + { + /* Check whether this pair, (u,w), has already been saved */ + if (u == pBD->RadEndpoints[i] && + v2 == pBD->RadEndpoints[i + 1]) + { + break; + } + } + if (i >= pBD->nNumRadEndpoints) + { + /* Add new (u,w) pair */ + if (pBD->nNumRadEndpoints + 2 <= pBD->max_num_vertices) + { + /* add */ + pBD->RadEndpoints[pBD->nNumRadEndpoints++] = u; /* radical */ + pBD->RadEndpoints[pBD->nNumRadEndpoints++] = v2; /* endpoint */ + num_found++; + /*return 1;*/ /* registered */ + } + else + { + return BNS_VERT_EDGE_OVFL; + } + } + } + } + if (num_found) + { + return 1; + } + } + } + break; + + case RAD_SRCH_FROM_FICT: + /* Find the nearest atom accessible from a fictitious vertex */ + /* go backwards along alt path and stop at the 1st found atom (not a fictitious vertex) */ + + v = u; + w = NO_VERTEX; /* the nearest atom -- radical-endpoint */ + u = NO_VERTEX; /* fictitious vertex carrying a radical */ + + while (v > Vertex_t) + { + u = v; + if (!( v % 2 ) && v / 2 <= pBNS->num_atoms && + pBNS->vert[v / 2 - 1].st_edge.cap - pBNS->vert[v / 2 - 1].st_edge.flow < 2) + { + w = v; /* vertex w is atom that may be singlet or doublet but not triplet */ + } + v = GetPrevVertex( pBNS, u, pBD->SwitchEdge, &iuv ); + } + v = u / 2 - 1; /* vertex u may be the radical from which the path originated; w is the nearest atom */ + if (w == NO_VERTEX || u == NO_VERTEX || w % 2 || u == w || v < pBNS->num_atoms || + pBNS->vert[v].st_edge.cap == pBNS->vert[v].st_edge.flow || + ( w = w / 2 - 1 ) >= pBNS->num_atoms) + { + break; /* reject */ + } + u = v; + /* At pBNS->vert[u] we have found the radical that originated the path, w is the nearest atom */ + for (i = 0; i < pBD->nNumRadEndpoints; i += 2) + { + if (u == pBD->RadEndpoints[i] && + w == pBD->RadEndpoints[i + 1]) + { + break; /* this pair has already been stored */ + } + } + if (i >= pBD->nNumRadEndpoints) + { + /* A new pair has been found */ + if (pBD->nNumRadEndpoints + 2 <= pBD->max_num_vertices) + { + /* Add */ + pBD->RadEndpoints[pBD->nNumRadEndpoints++] = u; /* radical */ + pBD->RadEndpoints[pBD->nNumRadEndpoints++] = w; /* endpoint */ + return 1; /* registered */ + } + else + { + return BNS_VERT_EDGE_OVFL; + } + } + break; + } + + return 0; /* rejected */ +} + + +/****************************************************************************/ +int cmp_rad_endpoints( const void *a1, const void *a2 ) +{ + /* Vertex radical_vertex, radical_endpoint */ + const Vertex *p1 = (const Vertex *) a1; + const Vertex *p2 = (const Vertex *) a2; + + if (p1[0] < p2[0]) + { + return -1; + } + if (p1[0] > p2[0]) + { + return 1; + } + if (p1[1] < p2[1]) + { + return -1; + } + if (p1[1] > p2[1]) + { + return 1; + } + + return 0; +} + + +/****************************************************************************/ +int RemoveRadEndpoints( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at ) +{ + BNS_EDGE *e; + EdgeIndex ie; + BNS_VERTEX *p1, *p2; + Vertex v1, v2; + int i, delta, rad; + + for (i = pBD->nNumRadEdges - 1; 0 <= i; i--) + { + ie = pBD->RadEdges[i]; + if (ie < 0 || ie >= pBNS->num_edges) + { + goto error_exit; + } + e = pBNS->edge + ie; + v1 = e->neighbor1; + v2 = e->neighbor12 ^ v1; /* v2 > v1 <=> v2 was added later */ + if (ie + 1 != pBNS->num_edges || + v1 < 0 || v1 >= pBNS->num_vertices || + v2 < 0 || v2 >= pBNS->num_vertices) + { + goto error_exit; + } + p1 = pBNS->vert + v1; + p2 = pBNS->vert + v2; + + if (p2->iedge[p2->num_adj_edges - 1] != ie || + p1->iedge[p1->num_adj_edges - 1] != ie) + { + goto error_exit; + } + + p2->num_adj_edges--; + p1->num_adj_edges--; + p2->iedge[p2->num_adj_edges] = 0; + p1->iedge[p1->num_adj_edges] = 0; + p2->st_edge.flow -= e->flow; + p1->st_edge.flow -= e->flow; + + if (!p2->num_adj_edges && v2 >= pBNS->num_atoms) + { + if (v2 + 1 != pBNS->num_vertices) + { + goto error_exit; + } + memset( p2, 0, sizeof( *p2 ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + pBNS->num_vertices--; + } + + if (!p1->num_adj_edges && v1 >= pBNS->num_atoms) + { + if (v1 + 1 != pBNS->num_vertices) + { + goto error_exit; + } + memset( p1, 0, sizeof( *p1 ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + pBNS->num_vertices--; + } + + if (at && v1 < pBNS->num_atoms) + { + delta = p1->st_edge.cap - p1->st_edge.flow; + rad = at[v1].radical; + switch (delta) + { + case 0: + if (rad == RADICAL_DOUBLET) + { + rad = 0; + } + break; + case 1: + if (rad != RADICAL_DOUBLET) + { + rad = RADICAL_DOUBLET; + } + } + at[v1].radical = rad; + } + memset( e, 0, sizeof( *e ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + pBNS->num_edges--; + } + pBD->nNumRadEdges = 0; + pBD->nNumRadicals = 0; + pBD->bRadSrchMode = RAD_SRCH_NORM; + return 0; + +error_exit: + + return BNS_PROGRAM_ERR; +} + + +/****************************************************************************/ +int RestoreRadicalsOnly( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at ) +{ + BNS_EDGE *e; + EdgeIndex ie; + BNS_VERTEX *p1, *p2; + Vertex v1, v2; + int i, delta, rad; + int p1_num_adj_edges, p2_num_adj_edges; + + for (i = pBD->nNumRadEdges - 1; 0 <= i; i--) + { + ie = pBD->RadEdges[i]; + if (ie < 0 || ie >= pBNS->num_edges) + { + goto error_exit; + } + e = pBNS->edge + ie; + v1 = e->neighbor1; /* atom */ + v2 = e->neighbor12 ^ v1; /* v2 > v1 <=> v2 was added later */ + if (v1 < 0 || v1 >= pBNS->num_atoms || + v2 < pBNS->num_atoms || v2 >= pBNS->num_vertices) + { + goto error_exit; + } + p1 = pBNS->vert + v1; + p2 = pBNS->vert + v2; + + p1_num_adj_edges = e->neigh_ord[0]; + p2_num_adj_edges = e->neigh_ord[1]; + + if (p2->iedge[p2_num_adj_edges] != ie || + p1->iedge[p1_num_adj_edges] != ie) + { + goto error_exit; + } + + if (at && v1 < pBNS->num_atoms) + { + delta = p1->st_edge.cap - p1->st_edge.flow + e->flow; + rad = at[v1].radical; + switch (delta) + { + case 0: + if (rad == RADICAL_DOUBLET) + rad = 0; + break; + case 1: + if (rad != RADICAL_DOUBLET) + rad = RADICAL_DOUBLET; + } + at[v1].radical = rad; + } + } + return 0; + +error_exit: + + return BNS_PROGRAM_ERR; +} + + +/****************************************************************************/ +int SetRadEndpoints( BN_STRUCT *pBNS, BN_DATA *pBD, BRS_MODE bRadSrchMode ) +{ + int ret, i, j, k, delta; /* djb-rwth: removing redundant variables */ + BNS_VERTEX *pRad, *pEndp; + Vertex wRad, vRad, vEndp, nNumRadicals; + int nDots = 0 /* added initialization, 2006-03 */, nNumEdges; + + if (pBNS->tot_st_cap <= pBNS->tot_st_flow) + { + return 0; + } + + pBD->nNumRadEndpoints = 0; + pBD->nNumRadEdges = 0; + pBD->bRadSrchMode = bRadSrchMode; + pBNS->alt_path = pBNS->altp[0]; + pBNS->bChangeFlow = 0; + ret = BalancedNetworkSearch( pBNS, pBD, BNS_EF_RAD_SRCH ); + ReInitBnData( pBD ); + ReInitBnStructAltPaths( pBNS ); + if (!ret && pBD->nNumRadEndpoints >= 2) + { + /* Sort by radical locations */ + qsort( pBD->RadEndpoints, pBD->nNumRadEndpoints / 2, 2 * sizeof( pBD->RadEndpoints[0] ), cmp_rad_endpoints ); + /* djb-rwth: removing redundant code */ + nNumRadicals = 0; + + /* Create new vertices (type=BNS_VERT_TYPE_TEMP) and edges with flow=cap=1 */ + /* connecting the new vertices radical vertices */ + for (i = 0; i < pBD->nNumRadEndpoints; i = j) + { + wRad = pBD->RadEndpoints[i]; + pRad = pBNS->vert + wRad; + delta = pRad->st_edge.cap - ( pRad->st_edge.flow & EDGE_FLOW_ST_MASK ); + if (delta <= 0) + { + delta = 1; + } + nNumEdges = 0; + for (j = i; j < pBD->nNumRadEndpoints && wRad == pBD->RadEndpoints[j]; j += 2) + { + nNumEdges++; + } + /* Add new aux vertex to the radical atom/vertex */ + vRad = bAddNewVertex( pBNS, wRad, delta, delta, nNumEdges + 1, &nDots ); + if (IS_BNS_ERROR( vRad )) + { + ret = vRad; + goto error_exit; + } + pRad = pBNS->vert + vRad; + pBD->RadEdges[pBD->nNumRadEdges++] = pRad->iedge[pRad->num_adj_edges - 1]; + /* Replace references to vertex wRad with vRad */ + for (k = i, nNumEdges = 0; k < j; k += 2) /* djb-rwth: ignoring LLVM warning: variable used */ + { + pBD->RadEndpoints[k] = vRad; + } + nNumRadicals++; + } + /* All vRad vertex indices should be in the range vFirstNewVertex...vFirstNewVertex+nNumRadicals-1 */ + /* connect new vertices to the radical endpoints thus replacing radicals with even-length alternating cycles */ + for (i = 0; i < pBD->nNumRadEndpoints; i = j) + { + vRad = pBD->RadEndpoints[i]; + pRad = pBNS->vert + vRad; + for (j = i; j < pBD->nNumRadEndpoints && vRad == pBD->RadEndpoints[j]; j += 2) + { + /* Connect vew vertex pRad to radical endpoints */ + vEndp = pBD->RadEndpoints[j + 1]; + pEndp = pBNS->vert + vEndp; + ret = AddNewEdge( pRad, pEndp, pBNS, 1, 0 ); + if (IS_BNS_ERROR( ret )) + { + goto error_exit; + } + pBD->RadEdges[pBD->nNumRadEdges++] = ret; + } + } + pBD->nNumRadicals = nNumRadicals; + return nNumRadicals; /* done */ + } + + return 0; /* nothing to do */ + +error_exit: + RemoveRadEndpoints( pBNS, pBD, NULL ); + + return ret; +} + + +#define MAX_NUM_RAD 256 + + +/****************************************************************************/ +int SetRadEndpoints2( CANON_GLOBALS *pCG, + BN_STRUCT *pBNS, + BN_DATA *pBD, + BRS_MODE bRadSrchMode ) +{ + int ret = 0, i, j, k, n, delta = 1; /* djb-rwth: removing redundant variables */ + BNS_VERTEX *pRad, *pEndp; + Vertex wRad, vRad, vEndp, nNumRadicals; + Vertex vRadList[MAX_NUM_RAD], vRadEqul[MAX_NUM_RAD]; + int nNumRad = 0; + int edge_flow; + int nDots = 0 /* added initialization, 2006-03 */, nNumEdges; + NodeSet VertSet; + + if (pBNS->tot_st_cap <= pBNS->tot_st_flow) + { + return 0; + } + + /* Find all radicals: their vertices have st_cap-st_flow=delta */ + /* save radical atom numbers in vRadList[] and remove radical by making st_cap=st_flow */ + for (i = 0; i < pBNS->num_atoms; i++) + { + if (pBNS->vert[i].st_edge.cap - delta == ( pBNS->vert[i].st_edge.flow & EDGE_FLOW_ST_MASK )) + { + if (nNumRad < MAX_NUM_RAD) + { + pBNS->vert[i].st_edge.cap -= delta; + pBNS->tot_st_cap -= delta; + vRadList[nNumRad] = i; /* radical position; i > j <=> vRadList[i] > vRadList[j] */ + vRadEqul[nNumRad] = nNumRad; /* the smallest radical atom that has reachable + * atoms in common with this radical atom + * always keep vRadEqul[nNumRad] <= nNumRad */ + nNumRad++; + } + } + } + + if (pBNS->tot_st_cap - pBNS->tot_st_flow > nNumRad) + { + return BNS_CAP_FLOW_ERR; /* extra st_cap on non-atoms or program error */ + } + + memset( &VertSet, 0, sizeof( VertSet ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + + /* Find reachable atoms by enabling each radical separately */ + for (j = 0; j < nNumRad; j++) + { + i = vRadList[j]; + pBD->nNumRadEndpoints = 0; + pBD->nNumRadEdges = 0; + pBD->bRadSrchMode = bRadSrchMode; + pBNS->alt_path = pBNS->altp[0]; + pBNS->bChangeFlow = 0; + pBNS->vert[i].st_edge.cap += delta; /* enable single radical */ + pBNS->tot_st_cap += delta; + ret = BalancedNetworkSearch( pBNS, pBD, BNS_EF_RAD_SRCH ); /* find reachable atoms */ + ReInitBnData( pBD ); + ReInitBnStructAltPaths( pBNS ); + pBD->bRadSrchMode = RAD_SRCH_NORM; + pBNS->vert[i].st_edge.cap -= delta; /* disable single radical */ + pBNS->tot_st_cap -= delta; + if (IS_BNS_ERROR( ret )) + { + goto error_exit; + } + else + { + if (ret) + { + ret = BNS_RADICAL_ERR; /* found augmenting path: should not happen since only one radical was enabled */ + goto error_exit; + } + } + if (!ret && pBD->nNumRadEndpoints >= 2) + { + /* Sort by: primary_key=radical locations, secondary_key=radical endoint */ + + qsort( pBD->RadEndpoints, pBD->nNumRadEndpoints / 2, 2 * sizeof( pBD->RadEndpoints[0] ), cmp_rad_endpoints ); + + if (pBD->RadEndpoints[0] != i || pBD->RadEndpoints[pBD->nNumRadEndpoints - 2] != i) + { + ret = BNS_RADICAL_ERR; /* more than one radical vertex */ + goto error_exit; + } + if (nNumRad > 1) + { + /* If more than one radical then save reachable atoms in bitmaps to allow */ + /* faster finding whether same atoms are reachable by two or more radicals */ + /* Later merge such sets */ + if (NULL == VertSet.bitword) + { + SetBitCreate( pCG ); + if (!NodeSetCreate( pCG, &VertSet, pBNS->num_atoms, nNumRad )) + { + ret = BNS_OUT_OF_RAM; /* out of RAM */ + goto error_exit; + } + } + + NodeSetFromRadEndpoints( pCG, &VertSet, j, pBD->RadEndpoints, pBD->nNumRadEndpoints ); + + /* Do not allow any radical center be treated as a reachable atom: */ + + RemoveFromNodeSet( pCG, &VertSet, j, vRadList, nNumRad ); + } + } + } + + /* Restore radical st_cap so that st_cap-st_flow=delta */ + for (j = 0; j < nNumRad; j++) + { + i = vRadList[j]; + pBNS->vert[i].st_edge.cap += delta; + pBNS->tot_st_cap += delta; + } + + /* Merge lists that have common radical endpoints */ + /* defect: if vertex sets i and j do not intersect they will be compared 2 times */ + /* total up to nNumRad*(nNumRad-1)/2 calls to DoNodeSetsIntersect() */ + if (nNumRad > 1) + { + for (i = 0; i < nNumRad; i++) + { + if (vRadEqul[i] != i) + { + continue; + } + do + { + n = 0; + for (j = i + 1; j < nNumRad; j++) + { + if (vRadEqul[j] != j) + { + continue; + } + if (DoNodeSetsIntersect( &VertSet, i, j )) + { + AddNodeSet2ToNodeSet1( &VertSet, i, j ); + vRadEqul[j] = i; /* Set j was copied to set i; i < j */ + n++; + } + } + } while (n); + } + /* Fill out pBD->RadEndpoints[] */ + for (i = 0, n = 0; i < nNumRad; i++) + { + if (i == vRadEqul[i]) + { + if (!IsNodeSetEmpty( &VertSet, i )) + { + /* Store equivalent radicals */ + for (j = i + 1; j < nNumRad; j++) + { + if (i == vRadEqul[j]) + { + pBD->RadEndpoints[n++] = vRadList[i]; + pBD->RadEndpoints[n++] = -vRadList[j] - 2; /* equivalent radical, alvays not zero */ + } + } + /* Store endpoints */ + n = AddNodesToRadEndpoints( pCG, &VertSet, i, pBD->RadEndpoints, vRadList[i], n, pBD->max_len_Pu_Pv ); + if (n < 0) + { + ret = BNS_RADICAL_ERR; /* pBD->RadEndpoints overflow */ + goto error_exit; + } + } + else + { + pBD->RadEndpoints[n++] = vRadList[i]; + pBD->RadEndpoints[n++] = -1; /* immobile radical, only one edge to add */ + } + } + } + pBD->nNumRadEndpoints = n; + NodeSetFree( pCG, &VertSet ); + } + else + { + if (nNumRad == 1 && !pBD->nNumRadEndpoints) + { + /* 2006-07-30: a single radical; no possible endpoint found */ + for (i = 0, n = 0; i < nNumRad; i++) + { + pBD->RadEndpoints[n++] = vRadList[i]; + pBD->RadEndpoints[n++] = -1; /* immobile radical, only one edge to add */ + } + pBD->nNumRadEndpoints = n; + } + } + + if (!ret && pBD->nNumRadEndpoints >= 2) + { + /* Already sorted by radical locations */ + /* djb-rwth: removing redundant code */ + nNumRadicals = 0; + /************************************************************************** + * Create new vertices (type=BNS_VERT_TYPE_TEMP) and edges with flow=cap=1 + * connecting the new vertices radical vertices + * + * + * Original structure: atom A is a radical center A==B--C*--D==E + * A*--B==C--D==E atoms C and E are reachable: A==B--C===D--E* + * + * Resultant temporary structure: + * A---B==C--D==E + * || / / + * || / / The additional new vertex (*) and its + * || / / 3 edges replace the radical with alternating + * || / / circuits that allow same bond changes + * || / / as moving the radical to atoms C or E. + * ||// "Double bonds" here have edge cap=1, flow=1 + * (*) "Single bonds" have edge cap=1, flow=0 + * + * The "equivalent radical centers" (which have at least one reachable atom + * in common) are connected to (*) with "double bonds" (edge cap=1, flow=1). + * Reachable non-radical atoms are connected by edges with cap=1, flow=0 + * After running BNS to find alt.path a "double bond" from (*) may move + * to another atom thus muving the radical. + * + * Number of additional (*) vertices = number of sets of + * "equivalent radical centers". + * Each such a set may include one or more radical centers. + * + * The radicals will be re-created in RemoveRadEndpoints() + ***************************************************************************/ + for (i = 0; i < pBD->nNumRadEndpoints; i = j) + { + wRad = pBD->RadEndpoints[i]; + pRad = pBNS->vert + wRad; + delta = pRad->st_edge.cap - ( pRad->st_edge.flow & EDGE_FLOW_ST_MASK ); + if (delta <= 0) + { + delta = 1; + } + nNumEdges = 0; + for (j = i; j < pBD->nNumRadEndpoints && wRad == pBD->RadEndpoints[j]; j += 2) + { + nNumEdges += ( pBD->RadEndpoints[j + 1] != -1 ); /* immobile radicals have one edge only */ + } + /* Add new aux vertex to the radical atom/vertex making st_cap-st_flow=0 */ + /* in case of immobile radical there will be no additional eddges since nNumEdges=0 */ + vRad = bAddNewVertex( pBNS, wRad, delta, delta, nNumEdges + 1, &nDots ); + if (IS_BNS_ERROR( vRad )) + { + ret = vRad; + goto error_exit; + } + pRad = pBNS->vert + vRad; + pBD->RadEdges[pBD->nNumRadEdges++] = pRad->iedge[pRad->num_adj_edges - 1]; + /* replace references to vertex wRad with vRad */ + for (k = i, nNumEdges = 0; k < j; k += 2) /* djb-rwth: ignoring LLVM warning: variable used */ + { + pBD->RadEndpoints[k] = vRad; + } + nNumRadicals++; + } + /* All vRad vertex indices should be in the range vFirstNewVertex...vFirstNewVertex+nNumRadicals-1 */ + /* connect new vertices to the radical endpoints thus replacing radicals with even-length alternating cycles */ + for (i = 0; i < pBD->nNumRadEndpoints; i = j) + { + vRad = pBD->RadEndpoints[i]; + pRad = pBNS->vert + vRad; + for (j = i; j < pBD->nNumRadEndpoints && vRad == pBD->RadEndpoints[j]; j += 2) + { + /* connect vew vertex pRad to radical endpoints */ + vEndp = pBD->RadEndpoints[j + 1]; + if (vEndp == -1) + continue; + if (vEndp < 0) + { + edge_flow = 1; + vEndp = -vEndp - 2; /* equivalent radical centers */ + } + else + { + edge_flow = 0; + } + pEndp = pBNS->vert + vEndp; + ret = AddNewEdge( pRad, pEndp, pBNS, 1, edge_flow ); + if (IS_BNS_ERROR( ret )) + { + goto error_exit; + } + pBD->RadEdges[pBD->nNumRadEdges++] = ret; + } + } + pBD->nNumRadicals = nNumRadicals; + return nNumRadicals; /* done */ + } + return 0; /* nothing to do */ + +error_exit: + RemoveRadEndpoints( pBNS, pBD, NULL ); + NodeSetFree( pCG, &VertSet ); + + return ret; +} + + +#else +/****************************************************************************/ +int SetRadEndpoints( BN_STRUCT *pBNS, BN_DATA *pBD, BRS_MODE bRadSrchMode ) +{ + return 0; +} +int RemoveRadEndpoints( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at ) +{ + return 0; +} +int SetRadEndpoints2( CANON_GLOBALS *pCG, BN_STRUCT *pBNS, BN_DATA *pBD, BRS_MODE bRadSrchMode ) +{ + return 0; +} +#endif + + +/**************************************************************************** +bExistsAltPath( ... ) + +Return value ret bits if not IS_BNS_ERROR(ret): + +ret & 1 => Success +ret & 2 => Bonds changed to Alt +(ret & ~3) >> 2 => nDelta: number of removed dots +****************************************************************************/ +int bExistsAltPath( CANON_GLOBALS *pCG, + BN_STRUCT *pBNS, + BN_DATA *pBD, + BN_AATG *pAATG, + inp_ATOM *at, + int num_atoms, + int nVertDoubleBond, + int nVertSingleBond, + int path_type ) +{ + ALT_PATH_CHANGES apc; + int ret, ret_val, bError, bSuccess, bChangeFlow = 0, nDots, nDelta, bDoMarkChangedBonds = 1; + int bAdjustRadicals = 0; + AT_NUMB type; + BNS_FLOW_CHANGES fcd[4 * BNS_MAX_NUM_FLOW_CHANGES + 1]; + ENDPOINT_INFO eif; +#if ( KETO_ENOL_TAUT == 1 ) + ENDPOINT_INFO eif2; +#endif + + /* Initialize */ + switch (path_type) + { + case ALT_PATH_MODE_TAUTOM: + /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ + type = BNS_VERT_TYPE_ENDPOINT; + bChangeFlow = BNS_EF_CHNG_RSTR; + if (!at[nVertSingleBond].endpoint && + ( !nGetEndpointInfo( at, nVertSingleBond, &eif ) || !eif.cDonor )) + { + return 0; + } + if (!at[nVertDoubleBond].endpoint && + ( !nGetEndpointInfo( at, nVertDoubleBond, &eif ) || !eif.cAcceptor )) + { + return 0; + } + break; + +#if ( TAUT_PT_22_00 == 1 ) + case ALT_PATH_MODE_TAUTOM_PT_22_00: + /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ + type = BNS_VERT_TYPE_ENDPOINT; + bChangeFlow = BNS_EF_CHNG_RSTR; + if (!at[nVertSingleBond].endpoint && + (!nGetEndpointInfo_PT_22_00(at, nVertSingleBond, &eif) || !eif.cDonor)) + return 0; + if (!at[nVertDoubleBond].endpoint && + (!nGetEndpointInfo_PT_22_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) + return 0; + break; +#endif + +#if ( TAUT_PT_16_00 == 1 ) + case ALT_PATH_MODE_TAUTOM_PT_16_00: + /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ + type = BNS_VERT_TYPE_ENDPOINT; + bChangeFlow = BNS_EF_CHNG_RSTR; + if (!at[nVertSingleBond].endpoint && + (!nGetEndpointInfo_PT_16_00(at, nVertSingleBond, &eif) || !eif.cDonor)) + return 0; + if (!at[nVertDoubleBond].endpoint && + (!nGetEndpointInfo_PT_16_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) + return 0; + break; +#endif + +#if ( TAUT_PT_06_00 == 1 ) + case ALT_PATH_MODE_TAUTOM_PT_06_00: + /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ + type = BNS_VERT_TYPE_ENDPOINT; + bChangeFlow = BNS_EF_CHNG_RSTR; + if (!at[nVertSingleBond].endpoint && + (!nGetEndpointInfo_PT_06_00(at, nVertSingleBond, &eif) || !eif.cDonor)) + return 0; + if (!at[nVertDoubleBond].endpoint && + (!nGetEndpointInfo_PT_06_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) + return 0; + break; +#endif + +#if ( TAUT_PT_39_00 == 1 ) + case ALT_PATH_MODE_TAUTOM_PT_39_00: + /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ + type = BNS_VERT_TYPE_ENDPOINT; + bChangeFlow = BNS_EF_CHNG_RSTR; + if (!at[nVertSingleBond].endpoint && + (!nGetEndpointInfo_PT_39_00(at, nVertSingleBond, &eif) || !eif.cDonor)) + return 0; + if (!at[nVertDoubleBond].endpoint && + (!nGetEndpointInfo_PT_39_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) + return 0; + break; +#endif + +#if ( TAUT_PT_13_00 == 1 ) + case ALT_PATH_MODE_TAUTOM_PT_13_00: + /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ + type = BNS_VERT_TYPE_ENDPOINT; + bChangeFlow = BNS_EF_CHNG_RSTR; + if (!at[nVertSingleBond].endpoint && + (!nGetEndpointInfo_PT_13_00(at, nVertSingleBond, &eif) || !eif.cDonor)) + return 0; + if (!at[nVertDoubleBond].endpoint && + (!nGetEndpointInfo_PT_13_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) + return 0; + break; +#endif + +#if ( TAUT_PT_18_00 == 1 ) + case ALT_PATH_MODE_TAUTOM_PT_18_00: + /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ + type = BNS_VERT_TYPE_ENDPOINT; + bChangeFlow = BNS_EF_CHNG_RSTR; + if (!at[nVertSingleBond].endpoint && + (!nGetEndpointInfo_PT_18_00(at, nVertSingleBond, &eif) || !eif.cDonor)) + return 0; + if (!at[nVertDoubleBond].endpoint && + (!nGetEndpointInfo_PT_18_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) + return 0; + break; +#endif + + +#if ( KETO_ENOL_TAUT == 1 ) + case ALT_PATH_MODE_TAUTOM_KET: + /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ + type = BNS_VERT_TYPE_ENDPOINT; + bChangeFlow = BNS_EF_CHNG_RSTR; + + if (!at[nVertSingleBond].endpoint && + ( !nGetEndpointInfo_KET( at, nVertSingleBond, &eif ) || !eif.cDonor )) + { + return 0; + } + if (!at[nVertDoubleBond].endpoint && + ( !nGetEndpointInfo_KET( at, nVertDoubleBond, &eif2 ) || !eif2.cAcceptor )) + { + return 0; + } + /* + if ( eif.cKetoEnolCode + eif2.cKetoEnolCode != 3 ) + return 0; + */ + break; + +#endif + case ALT_PATH_MODE_CHARGE: + /* Find alt path allowing to move (+). Purpose: establish "charge groups", + mark alt. bonds due to (+) charge movement */ + type = BNS_VERT_TYPE_C_POINT; + bChangeFlow = ( BNS_EF_CHNG_RSTR | BNS_EF_ALTR_BONDS ); + break; + + case ALT_PATH_MODE_4_SALT: + case ALT_PATH_MODE_4_SALT2: + /* Find alt paths allowing to move (-) and H between "acidic oxygen atoms". + Purpose: mark alt bonds due to this "long range" tautomerism. */ + type = BNS_VERT_TYPE_ENDPOINT; + bChangeFlow = ( BNS_EF_CHNG_RSTR | BNS_EF_ALTR_BONDS ); + if (!bIsBnsEndpoint( pBNS, nVertSingleBond ) /* !at[nVertSingleBond].endpoint*/ && + ( !nGetEndpointInfo( at, nVertSingleBond, &eif ) || !eif.cDonor )) + { + return 0; + } + if (!bIsBnsEndpoint( pBNS, nVertDoubleBond ) /* !at[nVertDoubleBond].endpoint*/ && + ( !nGetEndpointInfo( at, nVertDoubleBond, &eif ) || !eif.cAcceptor )) + { + return 0; + } + memset( &apc, 0, sizeof( apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + break; + + case ALT_PATH_MODE_REM2H_CHG: + bChangeFlow |= BNS_EF_ALTR_BONDS; /* fall through */ + case ALT_PATH_MODE_REM2H_TST: + bChangeFlow |= BNS_EF_CHNG_RSTR; + type = BNS_VERT_TYPE_ENDPOINT; + /* Allow non-tautomeric donors or any tautomeric atom */ + if (!bIsBnsEndpoint( pBNS, nVertSingleBond ) /* not linked to a t-group or the edge forbidden */ && + ( !nGetEndpointInfo( at, nVertSingleBond, &eif ) || !eif.cDonor )) /* not a donor */ + { + return 0; + } + if (!bIsBnsEndpoint( pBNS, nVertDoubleBond ) /* not connected to a t-group */ && + ( !nGetEndpointInfo( at, nVertDoubleBond, &eif ) || !eif.cDonor )) + { + return 0; + } + memset( &apc, 0, sizeof( apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + break; + + case ALT_PATH_MODE_ADD2H_CHG: + bChangeFlow |= BNS_EF_ALTR_BONDS; /* fall through */ + case ALT_PATH_MODE_ADD2H_TST: + bChangeFlow |= BNS_EF_CHNG_RSTR; + type = BNS_VERT_TYPE_ENDPOINT; + /* Allow non-tautomeric acceptors or any tautomeric atom */ + if (!bIsBnsEndpoint( pBNS, nVertSingleBond ) /* !at[nVertSingleBond].endpoint*/ && + ( !nGetEndpointInfo( at, nVertSingleBond, &eif ) || !eif.cAcceptor )) + { + return 0; + } + if (!bIsBnsEndpoint( pBNS, nVertDoubleBond ) /* !at[nVertSingleBond].endpoint*/ && + ( !nGetEndpointInfo( at, nVertDoubleBond, &eif ) || !eif.cAcceptor )) + { + return 0; + } + break; + + case ALT_PATH_MODE_REM_PROTON: + /* alt path is between the t-group (nVertDoubleBond) and + the (+)-charge group (nVertSingleBond) */ + type = 0; + /*bDoMarkChangedBonds = 0;*/ + bChangeFlow = ( BNS_EF_SAVE_ALL | BNS_EF_UPD_H_CHARGE ) | BNS_EF_ALTR_NS; /* added BNS_EF_ALTR_NS: set non-stereo altern non-ring bonds 2004-07-02*/ + break; + default: + type = 0; + bChangeFlow = BNS_EF_CHNG_RSTR; + break; + } + + bError = 0; + bSuccess = 0; + nDelta = 0; + + ret = SetRadEndpoints2( pCG, pBNS, pBD, RAD_SRCH_NORM ); + if (IS_BNS_ERROR( ret )) + { + return ret; + } + + /* Set BNS to check alt path */ + ret = bSetBnsToCheckAltPath( pBNS, nVertDoubleBond, nVertSingleBond, type, path_type, &apc, fcd, &nDots ); + switch (ret) + { + case BNS_CHK_ALTP_NO_ALTPATH: + ret = RemoveRadEndpoints( pBNS, pBD, NULL ); + return ret; + case BNS_CHK_ALTP_SAME_TGROUP: + bSuccess = 1; + goto reinit_BNS; + case BNS_CHK_ALTP_SAME_VERTEX: + ret = RemoveRadEndpoints( pBNS, pBD, NULL ); + return ret ? ret : 1; /* very strange ... set a breakpoint here */ + case BNS_CHK_ALTP_SET_SUCCESS: + break; /* actually check the existence of the altpath */ + case BNS_CANT_SET_BOND: + goto reinit_BNS; + default: + ret_val = RemoveRadEndpoints( pBNS, pBD, NULL ); /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + if (IS_BNS_ERROR( ret )) + { + return ret; + } + return BNS_PROGRAM_ERR; + } + + bAdjustRadicals = ( ( bChangeFlow & BNS_EF_UPD_RAD_ORI ) && !( bChangeFlow & BNS_EF_RSTR_FLOW ) ); + + /***************************************************************** + * nDots = 2 for ALT_PATH_CHARGE (checking moveable positive charges) + * Now nDots for ALT_PATH_TAUTOM or ALT_PATH_4_SALT can be greater + * because some of the bonds are effectively removed and dots + * (vertex st-caps) may be added + * -- to make sure there is no (+) charge on a tautomeric endpoint + * -- to fix positions of moveable tautomeric attachements + * (H and (-)-charges) at the ends of an alt path + */ + + /* Run BNS */ + + ret = RunBalancedNetworkSearch( pBNS, pBD, bChangeFlow ); + + if (IS_BNS_ERROR( ret )) + { + bError = ret; + } + else if (ret > 0) + { + if (2 * ret >= nDots) + { + nDelta = 2 * ret - nDots; /* non-zero means augmentation created another alt. path -- between radicals */ + if (pAATG && pAATG->nMarkedAtom) + { + if (pAATG->nAtTypeTotals && ( bChangeFlow & BNS_EF_UPD_H_CHARGE )) + { + memset( pAATG->nMarkedAtom, 0, num_atoms * sizeof( pAATG->nMarkedAtom[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + /* Mark atoms that have charge or H changed, check their input types (that is, before changes), + and subtract their input charge/H from nAtTypeTotals */ + SubtractOrChangeAtHChargeBNS( pBNS, at, num_atoms, pAATG->nAtTypeTotals, pAATG->nMarkedAtom, NULL, 1 ); + /* ZChange charges and/or H, update t_group_info, do not check types or change nAtTypeTotals */ + /* Atom types will be checked and nAtTypeTotals will be changed in + AddChangedAtHChargeBNS() later */ + SubtractOrChangeAtHChargeBNS( pBNS, at, num_atoms, NULL, NULL, pAATG->t_group_info, 0 ); + } + else + { + if (!pAATG->nAtTypeTotals) + { + bDoMarkChangedBonds = MarkAtomsAtTautGroups( pBNS, num_atoms, pAATG, nVertSingleBond, nVertDoubleBond ); + if (bDoMarkChangedBonds < 0) + { + bError = bDoMarkChangedBonds; + bDoMarkChangedBonds = 0; + } + } + } + } + if (bDoMarkChangedBonds) + { + /* Mark bonds that were changed to configure bond testing */ + ret_val = bSetBondsAfterCheckOneBond( pBNS, fcd, -1, at, num_atoms, bChangeFlow ); + if (IS_BNS_ERROR( ret_val )) + { + bError = ret_val; + } + /*ret = SetBondsRestoreBnStructFlow( pBNS, at, num_atoms, bChangeFlow );*/ + /* mark all other changed bonds */ + ret = SetBondsFromBnStructFlow( pBNS, at, num_atoms, bChangeFlow ); + if (IS_BNS_ERROR( ret )) + { + bError = ret; + } + else + { + if (!( ret & 1 ) && !( ret_val & 1 )) + { + bSuccess = 1; + } + else + { + if ((( ( ret & 1 ) || ( ret_val & 1 ) ) && + ( bChangeFlow & BNS_EF_ALTR_BONDS )) || ( bChangeFlow & BNS_EF_UPD_H_CHARGE )) /* djb-rwth: addressing LLVM warning */ + { + /* Some bonds have been changed to alternating */ + bSuccess = 3; + } + else + { + bError = BNS_BOND_ERR; + } + } + } + if (!bError && pAATG && pAATG->nMarkedAtom && ( bChangeFlow & BNS_EF_UPD_H_CHARGE )) + { + /* Update radicals to avoid errors in atom type check in AddChangedAtHChargeBNS() */ + if (bAdjustRadicals) + { + ret_val = RestoreRadicalsOnly( pBNS, pBD, at ); + if (IS_BNS_ERROR( ret_val )) + { + bError = ret_val; + } + } + /* Check atom types of marked atoms and add charge/H changes to nAtTypeTotals */ + /* Changing atoms were marked in the 1st call to SubtractOrChangeAtHChargeBNS(..., 1) above */ + AddChangedAtHChargeBNS( at, num_atoms, pAATG->nAtTypeTotals, pAATG->nMarkedAtom ); + if (bChangeFlow & BNS_EF_CHNG_FLOW) + { + /* Eliminate ambiguities in already changed flow: + replace (+)--N==(-) with (+)==N--(-) (both represent neutral N) */ + EliminatePlusMinusChargeAmbiguity( pBNS, num_atoms ); + } + } + } + } + + ret = RestoreBnStructFlow( pBNS, bChangeFlow & BNS_EF_CHNG_RSTR ); + + if (IS_BNS_ERROR( ret )) + { + bError = ret; + } + } + +reinit_BNS: + + /* --- Reinitialize to repeat the calculations --- */ + bRestoreBnsAfterCheckAltPath( pBNS, &apc, bChangeFlow & BNS_EF_UPD_H_CHARGE ); + bRestoreFlowAfterCheckOneBond( pBNS, fcd ); + ret_val = RemoveRadEndpoints( pBNS, pBD, bAdjustRadicals ? at : NULL ); + ReInitBnStructAltPaths( pBNS ); + + return bError ? bError : ret_val ? ret_val : ( bSuccess + 4 * nDelta ); +} + + +/****************************************************************************/ +BN_STRUCT* AllocateAndInitBnStruct( inp_ATOM *at, + int num_atoms, + int nMaxAddAtoms, + int nMaxAddEdges, + int max_altp, + int *pNum_changed_bonds ) +{ + BN_STRUCT *pBNS = NULL; + BNS_VERTEX *vert; + + int neigh, num_changed_bonds = 0; + U_CHAR bond_type, bond_mark; + + int i, j, k, n_edges, num_bonds, num_edges, f1, f2, edge_cap, edge_flow, st_flow; /* djb-rwth: removing redundant variables */ + int tot_st_cap, tot_st_flow; + int max_tg, max_edges, max_vertices, len_alt_path, max_iedges, num_altp; +#if ( BNS_RAD_SEARCH == 1 ) + int num_rad = 0; + + nMaxAddEdges += 1; +#endif +#if ( FIX_NUM_TG == 1 ) + max_tg = inchi_max( num_atoms / 2, 5 ); +#else + max_tg = num_atoms; +#endif + num_changed_bonds = 0; + + for (i = 0, num_bonds = 0; i < num_atoms; i++) + { + /*(@nnuk : Nauman Ullah Khan) */ + LOG_NO_ARGS("\n################# (L8916:ichi_bns.c) ###################\n"); + LOG_MULT_ARGS("Number of changed bonds (Start): %d\n", num_changed_bonds); + LOG_NO_ARGS("\n########################################################\n"); + + num_bonds += at[i].valence; +#if ( BNS_RAD_SEARCH == 1 ) + num_rad += ( at[i].radical == RADICAL_DOUBLET ); +#endif + } + /* Each atom has enough edges to belong to a tautomeric group + nMaxAddEdges */ + /* number of atoms is large enough to accommodate max. possible number of t-groups + nMaxAddAtoms */ + /* max_altp cannot be larger than BN_MAX_ALTP = 16 */ + num_edges = ( num_bonds /= 2 ); + /* +1 for a super-tautomeric group */ + max_vertices = num_atoms + nMaxAddAtoms + max_tg + 1; + /* +max_tg for edges between t-groups and super-tautomeric group */ + max_edges = num_edges + ( nMaxAddEdges + NUM_KINDS_OF_GROUPS )*max_vertices + max_tg; +#if ( BNS_RAD_SEARCH == 1 ) + if (num_rad) + { + max_vertices *= 2; + max_edges *= 2; + } +#endif + max_iedges = 2 * max_edges; + len_alt_path = max_vertices + iALTP_HDR_LEN + 1; /* may overflow if an edge is traversed in 2 directions */ + + if (!( pBNS = (BN_STRUCT *) inchi_calloc( 1, sizeof( BN_STRUCT ) ) ) || + !( pBNS->edge = (BNS_EDGE *) inchi_calloc( max_edges, sizeof( BNS_EDGE ) ) ) || + !( pBNS->vert = (BNS_VERTEX *) inchi_calloc( max_vertices, sizeof( BNS_VERTEX ) ) ) || + !( pBNS->iedge = (BNS_IEDGE *) inchi_calloc( max_iedges, sizeof( BNS_IEDGE ) ) )) + { + return DeAllocateBnStruct( pBNS ); + } + /* Alt path init */ + for (num_altp = 0; num_altp < max_altp && num_altp < BN_MAX_ALTP; num_altp++) + { + if (!( pBNS->altp[num_altp] = (BNS_ALT_PATH*) inchi_calloc( len_alt_path, sizeof( BNS_ALT_PATH ) ) )) + { + return DeAllocateBnStruct( pBNS ); + } + ALTP_ALLOCATED_LEN( pBNS->altp[num_altp] ) = len_alt_path; + pBNS->len_alt_path = len_alt_path; /* ??? duplication ??? */ + /* re-init */ + ALTP_DELTA( pBNS->altp[num_altp] ) = 0; + ALTP_START_ATOM( pBNS->altp[num_altp] ) = NO_VERTEX; + ALTP_END_ATOM( pBNS->altp[num_altp] ) = NO_VERTEX; + ALTP_PATH_LEN( pBNS->altp[num_altp] ) = 0; + } + pBNS->alt_path = NULL; + pBNS->num_altp = 0; + pBNS->max_altp = num_altp; + + /* Fill vertices (no connectivity) */ + pBNS->vert[0].iedge = pBNS->iedge; + for (i = 0; i < num_atoms; i++) + { + k = pBNS->vert[i].max_adj_edges = at[i].valence + ( nMaxAddEdges + NUM_KINDS_OF_GROUPS ); + pBNS->vert[i + 1].iedge = pBNS->vert[i].iedge + k; + } + pBNS->num_atoms = num_atoms; /* number of real atoms */ + pBNS->num_added_atoms = 0; + pBNS->num_t_groups = 0; /* number of added t-groups */ + pBNS->num_c_groups = 0; + pBNS->nMaxAddAtoms = nMaxAddAtoms; + pBNS->nMaxAddEdges = nMaxAddEdges; + + pBNS->num_vertices = num_atoms; /* current number of vertices, a sum of + pBNS->num_atoms + pBNS->num_t_groups + pBNS->num_added_atoms */ + pBNS->max_vertices = max_vertices; + + + pBNS->num_bonds = num_bonds; /* number of real edges (bonds) */ + pBNS->max_edges = max_edges; + pBNS->max_iedges = max_iedges; + + /* + To remove t-groups and added atoms: + In atoms i = 0..pBNS->num_atoms-1 + pBNS->vert[i].num_adj_edges = pBNS->vert[i].max_adj_edges - pBNS->nMaxAddEdges - NUM_KINDS_OF_GROUPS; + pBNS->num_vertices = pBNS->num_atoms; + pBNS->num_edges = pBNS->num_bonds; + pBNS->num_added_atoms = 0; + pBNS->num_t_groups = 0; + pBNS->num_added_edges = 0; + + ALTP_DELTA(pBNS->alt_path) = 0; + ALTP_START_ATOM(pBNS->alt_path) = NO_VERTEX; + ALTP_END_ATOM(pBNS->alt_path) = NO_VERTEX; + ALTP_PATH_LEN(pBNS->alt_path) = 0; + */ + + /* Fill edges and connectivity */ + tot_st_cap = tot_st_flow = 0; + for (i = 0, n_edges = 0; i < num_atoms; i++) + { + vert = &pBNS->vert[i]; + /* djb-rwth: removing redundant code */ + st_flow = 0; + /* djb-rwth: removing redundant code */ + for (j = 0; j < at[i].valence; j++) + { + neigh = at[i].neighbor[j]; + /* find this bond at the neighbor */ + for (k = 0; k < at[neigh].valence; k++) + { + if (at[neigh].neighbor[k] == i) + { + break; + } + } + bond_type = ( at[i].bond_type[j] & BOND_TYPE_MASK ); + bond_mark = ( at[i].bond_type[j] & ~BOND_TYPE_MASK ); + if (bond_type != BOND_SINGLE && bond_type != BOND_DOUBLE && + bond_type != BOND_TRIPLE /*&& bond_type != BOND_ALTERN*/) + { + /* Make Unknown or Alternating bonds single */ + bond_type = 1; + at[i].bond_type[j] = bond_mark | bond_type; + num_changed_bonds++; + } + if (neigh > i) + { + /* This is the first time we encounter this bond */ + f1 = MAX_AT_FLOW( at[i] ); + f2 = MAX_AT_FLOW( at[neigh] ); + edge_flow = bond_type - 1; + if (edge_flow > MAX_BOND_EDGE_CAP) + { + /* djb-rwth: removing redundant code */ + edge_flow = 0; /* BNS will determine flows (that is, bonds) */ + edge_cap = AROM_BOND_EDGE_CAP; + } + else + { +#if ( 0 && KETO_ENOL_TAUT == 1 ) /* ????? */ + edge_cap = inchi_max( f1, f2 ); +#else + edge_cap = inchi_min( f1, f2 ); +#endif + edge_cap = inchi_min( edge_cap, MAX_BOND_EDGE_CAP ); /* max capacity = 2 means up to triple bond */ + } + + pBNS->edge[n_edges].neighbor1 = (AT_NUMB) i; + pBNS->edge[n_edges].neighbor12 = (AT_NUMB) ( i ^ neigh ); + pBNS->edge[n_edges].flow = pBNS->edge[n_edges].flow0 = edge_flow; + pBNS->edge[n_edges].cap = pBNS->edge[n_edges].cap0 = edge_cap; + pBNS->edge[n_edges].neigh_ord[0] = j; + pBNS->edge[n_edges].neigh_ord[1] = k; + pBNS->edge[n_edges].pass = 0; + pBNS->edge[n_edges].forbidden = 0; + + vert->iedge[j] = pBNS->vert[neigh].iedge[k] = n_edges++; + } + else + { + /* This is the second time we encounter this bond. It was stored at */ + int iedge = pBNS->vert[neigh].iedge[k]; + edge_cap = pBNS->edge[iedge].cap; /* djb-rwth: ignoring LLVM warning: variable used */ + edge_flow = pBNS->edge[iedge].flow; + } + st_flow += edge_flow; + /* djb-rwth: removing redundant code */ + } + vert->num_adj_edges = j; + vert->st_edge.cap = + vert->st_edge.cap0 = MAX_AT_FLOW( at[i] ); + vert->st_edge.flow = + vert->st_edge.flow0 = st_flow; + vert->type = BNS_VERT_TYPE_ATOM; + tot_st_cap += vert->st_edge.cap; + tot_st_flow += vert->st_edge.flow; + } + *pNum_changed_bonds = num_changed_bonds / 2; + + pBNS->num_edges = n_edges; /* number of edges */ + pBNS->num_added_edges = 0; + + /*(@nnuk : Nauman Ullah Khan) */ + LOG_NO_ARGS("\n################# (L9108:ichi_bns.c) ################\n"); + for (i = 0, num_bonds = 0; i < num_atoms; i++) { + + LOG_MULT_ARGS("Element : %s, Number of changed bonds (End): %d\n", at[i].elname, *pNum_changed_bonds); + } + LOG_NO_ARGS("\n#####################################################\n"); + + pBNS->tot_st_cap = tot_st_cap; + pBNS->tot_st_flow = tot_st_flow; + + return pBNS; +} + + +/****************************************************************************/ +BN_STRUCT* DeAllocateBnStruct( BN_STRUCT *pBNS ) +{ + int i; + if (pBNS) + { + if (pBNS->edge) + { + inchi_free( pBNS->edge ); + } + for (i = 0; i < pBNS->max_altp && i < BN_MAX_ALTP; i++) + { + if (pBNS->altp[i]) + { + inchi_free( pBNS->altp[i] ); + } + } + if (pBNS->vert) + { + if (pBNS->vert[0].iedge) + { + inchi_free( pBNS->vert[0].iedge ); + } + inchi_free( pBNS->vert ); + } + inchi_free( pBNS ); + } + + return NULL; +} + + +/****************************************************************************/ +int ReInitBnStructAltPaths( BN_STRUCT *pBNS ) +{ + int i; + for (i = 0; i < pBNS->max_altp && i < BN_MAX_ALTP; i++) + { + if (pBNS->altp[i]) + { + ALTP_DELTA( pBNS->altp[i] ) = 0; + ALTP_PATH_LEN( pBNS->altp[i] ) = 0; + ALTP_START_ATOM( pBNS->altp[i] ) = NO_VERTEX; + ALTP_END_ATOM( pBNS->altp[i] ) = NO_VERTEX; + } + } + pBNS->alt_path = NULL; + pBNS->num_altp = 0; + return i; +} + + +/****************************************************************************/ +int ReInitBnStructAddGroups( CANON_GLOBALS *pCG, + BN_STRUCT *pBNS, + inp_ATOM *at, + int num_atoms, + T_GROUP_INFO *tgi, + C_GROUP_INFO *cgi ) +{ + int ret; + /* strip all t-groups and c-groups */ + ret = ReInitBnStruct( pBNS, at, num_atoms, 0 ); + if (ret) + { + ret = BNS_REINIT_ERR; + goto exit_function; + } + /*#if ( MOVE_CHARGES == 1 )*/ + if (*pBNS->pbTautFlags & TG_FLAG_MOVE_POS_CHARGES) + { + /* Add c-groups */ + ret = AddCGroups2BnStruct( pCG, pBNS, at, num_atoms, cgi ); + if (IS_BNS_ERROR( ret )) + { + goto exit_function; + } + } + /*#endif*/ + /* Add t-groups */ + ret = AddTGroups2BnStruct( pCG, pBNS, at, num_atoms, tgi ); + if (IS_BNS_ERROR( ret )) + { + goto exit_function; + } + +exit_function: + + return ret; +} + + +/****************************************************************************/ +int ReInitBnStruct( BN_STRUCT *pBNS, + inp_ATOM *at, + int num_at, + int bRemoveGroupsFromAtoms ) +{ + int i, vfict, kfict, iedgefict, endpoint, centerpoint, iedge, k; + int ret = 0; + if (pBNS) + { + if (pBNS->vert && pBNS->edge) + { + /* Debug */ + for (k = 0, i = 0; k < pBNS->num_edges; k++) + { + if (pBNS->edge[k].pass) + { + i++; + } + } + ret += i * 100; + /* Restore flow and cap on edges to vertices connected to fictitious atoms */ + for (vfict = pBNS->num_atoms; vfict < pBNS->num_vertices; vfict++) + { + for (kfict = 0; kfict < pBNS->vert[vfict].num_adj_edges; kfict++) + { + iedgefict = pBNS->vert[vfict].iedge[kfict]; /* fictitious edge to the endpoint */ + endpoint = pBNS->edge[iedgefict].neighbor12 ^ vfict; /* the endpoint */ + /* To simlify restore cap and flow in ALL edges to the endpoint */ + if (bRemoveGroupsFromAtoms && endpoint < num_at) + { + at[endpoint].c_point = 0; + at[endpoint].endpoint = 0; + } + for (k = 0; k < pBNS->vert[endpoint].num_adj_edges; k++) + { + iedge = pBNS->vert[endpoint].iedge[k]; /* edge to endpoint */ + centerpoint = pBNS->edge[iedge].neighbor12 ^ endpoint; + pBNS->edge[iedge].cap = pBNS->edge[iedge].cap0; + pBNS->edge[iedge].flow = pBNS->edge[iedge].flow0; + pBNS->edge[iedge].pass = 0; +#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) + pBNS->edge[iedge].forbidden &= pBNS->edge_forbidden_mask; +#endif + pBNS->vert[centerpoint].st_edge.cap = pBNS->vert[centerpoint].st_edge.cap0; + pBNS->vert[centerpoint].st_edge.flow = pBNS->vert[centerpoint].st_edge.flow0; + } + pBNS->vert[endpoint].st_edge.cap = pBNS->vert[endpoint].st_edge.cap0; + pBNS->vert[endpoint].st_edge.flow = pBNS->vert[endpoint].st_edge.flow0; + pBNS->vert[endpoint].type &= BNS_VERT_TYPE_ATOM; + } + } + /* Reset number of neighbors */ + if (pBNS->num_edges > pBNS->num_bonds) + { + for (i = 0; i < pBNS->num_atoms; i++) + { + pBNS->vert[i].num_adj_edges = + pBNS->vert[i].max_adj_edges - pBNS->nMaxAddEdges - NUM_KINDS_OF_GROUPS; + } + } + } + else + { + ret += 2; + } + if (!pBNS->edge) + { + ret += 4; + } + if (!pBNS->iedge) + { + ret += 8; + } + + ReInitBnStructAltPaths( pBNS ); + + pBNS->num_vertices = pBNS->num_atoms; + pBNS->num_edges = pBNS->num_bonds; + pBNS->num_added_atoms = 0; + pBNS->num_t_groups = 0; + pBNS->num_c_groups = 0; + pBNS->num_added_edges = 0; + } + else + { + ret += 1; + } + + return ret; +} + + +/****************************************************************************/ +int CompTGroupNumber( const void *tg1, const void *tg2, void *p ) +{ + return (int) ( (const T_GROUP *) tg1 )->nGroupNumber - (int) ( (const T_GROUP *) tg2 )->nGroupNumber; +} + + +/****************************************************************************/ +int CompCGroupNumber( const void *cg1, const void *cg2, void *p ) +{ + return (int) ( (const C_GROUP *) cg1 )->nGroupNumber - (int) ( (const C_GROUP *) cg2 )->nGroupNumber; +} + + +/****************************************************************************/ +int AddTGroups2BnStruct( CANON_GLOBALS *pCG, + BN_STRUCT *pBNS, + inp_ATOM *at, + int num_atoms, + T_GROUP_INFO *tgi ) +{ + int ret = 0; + /* ret = ReInitBnStruct( pBNS ); */ + if (tgi && tgi->num_t_groups && tgi->t_group) + { + int i, k, endpoint, centerpoint, fictpoint; + int num_tg = tgi->num_t_groups; + int num_edges = pBNS->num_edges; + int num_vertices = pBNS->num_vertices; + BNS_VERTEX *vert_ficpoint, *ver_ficpont_prev; /* fictitious vertex describing t-group */ + BNS_VERTEX *vert_endpoint; + BNS_EDGE *edge; /* edge between that vertex and the tautomeric endpoint */ + int nMaxTGroupNumber = 0; + ENDPOINT_INFO eif; + + /* Debug: check overflow */ + if (num_vertices + num_tg >= pBNS->max_vertices) + { + return BNS_VERT_EDGE_OVFL; + } + /* Find the largest t-group ID */ + for (i = 0; i < num_tg; i++) + { + if (tgi->t_group[i].nGroupNumber > nMaxTGroupNumber) + { + nMaxTGroupNumber = tgi->t_group[i].nGroupNumber; + } + } + /* Since t-group IDs may be not contiguous, clear all vertices that will be added. + all-zeroes-vertex will be ignored by the BNS + */ + memset( pBNS->vert + num_vertices, 0, nMaxTGroupNumber * sizeof( pBNS->vert[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + /* Make sure the last t-group has the largest t-group ID: + this is necessary to correctly add new edges + and vertices for testing augmenting paths */ +#if ( bRELEASE_VERSION != 1 ) + insertions_sort( pCG, tgi->t_group, num_tg, sizeof( tgi->t_group[0] ), CompTGroupNumber ); + for (i = 1; i < num_tg; i++) + { + if (1 != tgi->t_group[i].nGroupNumber - tgi->t_group[i - 1].nGroupNumber) + { + return BNS_BOND_ERR; + } + } +#else + if (nMaxTGroupNumber != tgi->t_group[num_tg - 1].nGroupNumber) + { + insertions_sort( pCG, tgi->t_group, num_tg, sizeof( tgi->t_group[0] ), CompTGroupNumber ); + } +#endif + /* Initialize new fictitious vertices */ + ver_ficpont_prev = pBNS->vert + num_vertices - 1; + + for (i = 0; i < num_tg; i++, ver_ficpont_prev = vert_ficpoint) + { + /* + vert_ficpoint-1 is the last vertex; + vert_ficpoint is the vertex that is being added + Note: nGroupNumber are not contiguous + */ + vert_ficpoint = pBNS->vert + num_vertices + tgi->t_group[i].nGroupNumber - 1; + vert_ficpoint->iedge = ver_ficpont_prev->iedge + ver_ficpont_prev->max_adj_edges; + vert_ficpoint->max_adj_edges = tgi->t_group[i].nNumEndpoints + BNS_ADD_EDGES + BNS_ADD_SUPER_TGROUP; + vert_ficpoint->num_adj_edges = 0; + vert_ficpoint->st_edge.flow = vert_ficpoint->st_edge.flow0 = 0; + vert_ficpoint->st_edge.cap = vert_ficpoint->st_edge.cap0 = 0; + vert_ficpoint->type = BNS_VERT_TYPE_TGROUP; + } + + for (endpoint = 0; endpoint < num_atoms; endpoint++) + { + if (!at[endpoint].endpoint) + { + continue; + } + fictpoint = at[endpoint].endpoint + num_vertices - 1; + vert_ficpoint = pBNS->vert + fictpoint; + vert_endpoint = pBNS->vert + endpoint; + /* Debug: check overflow */ + if (fictpoint >= pBNS->max_vertices || + num_edges >= pBNS->max_edges || + vert_ficpoint->num_adj_edges >= vert_ficpoint->max_adj_edges || + vert_endpoint->num_adj_edges >= vert_endpoint->max_adj_edges) + { + ret = BNS_VERT_EDGE_OVFL; + break; + } + /* Obtain donor/acceptor info */ + if (!nGetEndpointInfo(at, endpoint, &eif) +#if ( TAUT_PT_22_00 == 1 ) + && !((tgi->bTautFlags & TG_FLAG_PT_22_00) && nGetEndpointInfo_PT_22_00(at, endpoint, &eif)) +#endif +#if ( TAUT_PT_16_00 == 1 ) + && !((tgi->bTautFlags & TG_FLAG_PT_16_00) && nGetEndpointInfo_PT_16_00(at, endpoint, &eif)) +#endif +#if ( TAUT_PT_06_00 == 1 ) + && !((tgi->bTautFlags & TG_FLAG_PT_06_00) && nGetEndpointInfo_PT_06_00(at, endpoint, &eif)) +#endif +#if ( TAUT_PT_39_00 == 1 ) + && !((tgi->bTautFlags & TG_FLAG_PT_39_00) && nGetEndpointInfo_PT_39_00(at, endpoint, &eif)) +#endif +#if ( TAUT_PT_13_00 == 1 ) + && !((tgi->bTautFlags & TG_FLAG_PT_13_00) && nGetEndpointInfo_PT_13_00(at, endpoint, &eif)) +#endif +#if ( TAUT_PT_18_00 == 1 ) + && !((tgi->bTautFlags & TG_FLAG_PT_18_00) && nGetEndpointInfo_PT_18_00(at, endpoint, &eif)) +#endif + ) { +#if ( KETO_ENOL_TAUT == 1 ) + if (!( ( tgi->bTautFlags & TG_FLAG_KETO_ENOL_TAUT ) && + nGetEndpointInfo_KET( at, endpoint, &eif ) )) +#endif + { + ret = BNS_BOND_ERR; + break; + } + } + + vert_endpoint->type |= BNS_VERT_TYPE_ENDPOINT; + + /* Set capacity = 1 to the edges from the endpoint to the centerpoint(s) */ + for (k = 0; k < vert_endpoint->num_adj_edges; k++) + { + int iedge = vert_endpoint->iedge[k]; + if (!pBNS->edge[iedge].cap) + { + /* Single bond, possibly between endpoint and centerpoint */ + centerpoint = ( pBNS->edge[iedge].neighbor12 ^ endpoint ); + if (centerpoint < pBNS->num_atoms && + pBNS->vert[centerpoint].st_edge.cap >= 1) + { + int bond_type = ( at[endpoint].bond_type[k] & BOND_TYPE_MASK ); + if (bond_type == BOND_TAUTOM || + bond_type == BOND_ALTERN || + bond_type == BOND_ALT12NS || + bond_type == BOND_SINGLE) + { + pBNS->edge[iedge].cap = 1; + } + } + } + } + + /* Create a new edge connecting endpoint to the new fictitious t-group vertex vert_ficpoint */ + edge = pBNS->edge + num_edges; + edge->cap = 1; + edge->flow = 0; + edge->pass = 0; +#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) + edge->forbidden &= pBNS->edge_forbidden_mask; +#endif + /* Later include case when the charge change allows the endpoint to become tautomeric */ + /* mark endoint having moveable H atom with flow=1 */ + + /* -- old "no charges" version -- */ + /* if (at[endpoint].chem_bonds_valence == at[endpoint].valence) */ + /* -- the following line takes charges into account -- */ + if (eif.cDonor) /* means the endpoint has an H-atom to donate */ + { + /* increment edge flow */ + edge->flow++; + /* increment one vertex st-flow & cap */ + vert_ficpoint->st_edge.flow++; + vert_ficpoint->st_edge.cap++; + /* increment another vertex st-flow & cap */ + vert_endpoint->st_edge.flow++; + vert_endpoint->st_edge.cap++; + } + /* Connect edge to endpoint and fictpoint and increment the counters of neighbors and edges */ + edge->neighbor1 = endpoint; /* the smallest out of v1=endopoint and v2=num_vertices */ + edge->neighbor12 = endpoint ^ fictpoint; /* v1 ^ v2 */ + vert_endpoint->iedge[vert_endpoint->num_adj_edges] = num_edges; + vert_ficpoint->iedge[vert_ficpoint->num_adj_edges] = num_edges++; + edge->neigh_ord[0] = vert_endpoint->num_adj_edges++; + edge->neigh_ord[1] = vert_ficpoint->num_adj_edges++; + edge->cap0 = edge->cap; + edge->flow0 = edge->flow; + } + + pBNS->num_edges = num_edges; + pBNS->num_vertices += nMaxTGroupNumber; + pBNS->num_t_groups = num_tg; + } + + return ret; +} + + +/*#if ( MOVE_CHARGES == 1 )*/ /* { */ + + + /****************************************************************************/ +int AddCGroups2BnStruct( CANON_GLOBALS *pCG, + BN_STRUCT *pBNS, + inp_ATOM *at, + int num_atoms, + C_GROUP_INFO *cgi ) +{ + int ret = 0; + /* ret = ReInitBnStruct( pBNS ); */ + if (cgi && cgi->num_c_groups && cgi->c_group) + { + int i, k, c_point, centerpoint, fictpoint; + int num_cg = cgi->num_c_groups; + int num_edges = pBNS->num_edges; + int num_vertices = pBNS->num_vertices; + BNS_VERTEX *vert_ficpoint, *ver_ficpont_prev; /* fictitious vertex describing charge c-group */ + BNS_VERTEX *vertex_cpoint; + BNS_EDGE *edge; /* edge between that vertex and the tautomeric c_point */ + int nMaxCGroupNumber = 0; + + /* Debug: check overflow */ + if (num_vertices + num_cg >= pBNS->max_vertices) + { + return BNS_VERT_EDGE_OVFL; + } + /* Find the largest t-group ID */ + for (i = 0; i < num_cg; i++) + { + if (cgi->c_group[i].nGroupNumber > nMaxCGroupNumber) + { + nMaxCGroupNumber = cgi->c_group[i].nGroupNumber; + } + } + /* Since t-group IDs may be not contiguous, clear all vertices that will be added. + all-zeroes-vertex will be ignored by the BNS + */ + memset( pBNS->vert + num_vertices, 0, nMaxCGroupNumber * sizeof( pBNS->vert[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + /* Make sure the last t-group has the largest t-group ID: + this is necessary to correctly add new edges and vertices for testing augmenting paths + */ +#if ( bRELEASE_VERSION != 1 ) + insertions_sort( cgi->c_group, num_cg, sizeof( cgi->c_group[0] ), CompCGroupNumber ); + for (i = 1; i < num_cg; i++) + { + if (1 != cgi->c_group[i].nGroupNumber - cgi->c_group[i - 1].nGroupNumber) + { + return BNS_BOND_ERR; + } + } +#else + if (nMaxCGroupNumber != cgi->c_group[num_cg - 1].nGroupNumber) + { + insertions_sort( pCG, cgi->c_group, num_cg, + sizeof( cgi->c_group[0] ), + CompCGroupNumber ); + } +#endif + /**************************************/ + /* initialize new fictitious vertices */ + /* representing c-point groups */ + /**************************************/ + ver_ficpont_prev = pBNS->vert + num_vertices - 1; + + for (i = 0; i < num_cg; i++, ver_ficpont_prev = vert_ficpoint) + { + /* + vert_ficpoint-1 is the last vertex; + vert_ficpoint is the being added vertex + Note: nGroupNumber are not contiguous + */ + vert_ficpoint = pBNS->vert + num_vertices + cgi->c_group[i].nGroupNumber - 1; + vert_ficpoint->iedge = ver_ficpont_prev->iedge + ver_ficpont_prev->max_adj_edges; + vert_ficpoint->max_adj_edges = cgi->c_group[i].num_CPoints + BNS_ADD_EDGES; + vert_ficpoint->num_adj_edges = 0; + vert_ficpoint->st_edge.flow = vert_ficpoint->st_edge.flow0 = 0; + vert_ficpoint->st_edge.cap = vert_ficpoint->st_edge.cap0 = 0; + vert_ficpoint->type = BNS_VERT_TYPE_C_GROUP; + } + + /************************************************/ + /* Connect c-points to the fictitious vertices */ + /* representing c-point groups; set caps, flows */ + /************************************************/ + for (c_point = 0; c_point < num_atoms; c_point++) + { + if (!at[c_point].c_point) + { + continue; + } + fictpoint = at[c_point].c_point + num_vertices - 1; /* c-group vertex index */ + vert_ficpoint = pBNS->vert + fictpoint; /* c-group vertex */ + vertex_cpoint = pBNS->vert + c_point; /* c_point vertex */ + /* Debug: check overflow */ + if (fictpoint >= pBNS->max_vertices || + num_edges >= pBNS->max_edges || + vert_ficpoint->num_adj_edges >= vert_ficpoint->max_adj_edges || + vertex_cpoint->num_adj_edges >= vertex_cpoint->max_adj_edges) + { + ret = BNS_VERT_EDGE_OVFL; + break; + } + vertex_cpoint->type |= BNS_VERT_TYPE_C_POINT; +#if ( FIX_CPOINT_BOND_CAP != 1 ) /* { */ + /* set capacity = 1 to the edges from the c_point to the centerpoint(s) */ + /* if their current capacity is zero */ + /* the centerpoint is any adjacent atom that is adjacent to a multiple bond */ + for (k = 0; k < vertex_cpoint->num_adj_edges; k++) + { + int iedge = vertex_cpoint->iedge[k]; + if (!pBNS->edge[iedge].cap) + { + /* single bond, possibly between c_point and centerpoint */ + centerpoint = ( pBNS->edge[iedge].neighbor12 ^ c_point ); + if (centerpoint < pBNS->num_atoms && + pBNS->vert[centerpoint].st_edge.cap >= 1) + { + int bond_type = ( at[c_point].bond_type[k] & BOND_TYPE_MASK ); + if (bond_type == BOND_TAUTOM || + bond_type == BOND_ALTERN || + bond_type == BOND_SINGLE) + { + pBNS->edge[iedge].cap = 1; + } + } + } + } +#endif /* } FIX_CPOINT_BOND_CAP */ + + /* Create a new edge connecting c_point to the new fictitious c-group vertex vert_ficpoint */ + edge = pBNS->edge + num_edges; + edge->cap = 1; + edge->flow = 0; + edge->pass = 0; +#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) + edge->forbidden &= pBNS->edge_forbidden_mask; +#endif + /* Mark edge to c-point having NO moveable charge with flow=1 */ + if (!CHARGED_CPOINT( at, c_point )) + { + /* Increment edge flow */ + edge->flow++; + /* Increment c-group vertex st-flow & cap */ + vert_ficpoint->st_edge.flow++; + vert_ficpoint->st_edge.cap++; + /* Increment c-point vertex st-flow & cap */ + vertex_cpoint->st_edge.flow++; + vertex_cpoint->st_edge.cap++; + } + +#if ( FIX_CPOINT_BOND_CAP == 1 ) /* { */ + + /* Set capacity = 1 to the edges from the c_point to the centerpoint(s) */ + /* if their current capacity is zero */ + /* the centerpoint is any adjacent atom that is adjacent to a multiple bond */ + for (k = 0; k < vertex_cpoint->num_adj_edges; k++) + { + int iedge = vertex_cpoint->iedge[k]; + VertexFlow nNewCap = vertex_cpoint->st_edge.cap; + centerpoint = ( pBNS->edge[iedge].neighbor12 ^ c_point ); + if (!pBNS->edge[iedge].cap) + { + /* Single bond, possibly between c_point and centerpoint */ + if (centerpoint < pBNS->num_atoms && + pBNS->vert[centerpoint].st_edge.cap >= 1) + { + nNewCap = inchi_min( pBNS->vert[centerpoint].st_edge.cap, nNewCap ); + nNewCap = inchi_min( nNewCap, MAX_BOND_EDGE_CAP ); + pBNS->edge[iedge].cap = nNewCap; + } +#if ( FIX_CPOINT_BOND_CAP2 == 1 ) /* multiple bond */ + else + if (centerpoint < pBNS->num_atoms && + edge->flow && pBNS->edge[iedge].cap < MAX_BOND_EDGE_CAP) + { + pBNS->edge[iedge].cap++; + } +#endif + } + } +#endif /* } FIX_CPOINT_BOND_CAP */ + + /* Connect edge to c_point and fictpoint and increment the counters of neighbors and edges */ + edge->neighbor1 = c_point; /* the smallest out of v1=endopoint and v2=num_vertices */ + edge->neighbor12 = c_point ^ fictpoint; /* v1 ^ v2 */ + vertex_cpoint->iedge[vertex_cpoint->num_adj_edges] = num_edges; + vert_ficpoint->iedge[vert_ficpoint->num_adj_edges] = num_edges++; + edge->neigh_ord[0] = vertex_cpoint->num_adj_edges++; + edge->neigh_ord[1] = vert_ficpoint->num_adj_edges++; + edge->cap0 = edge->cap; + edge->flow0 = edge->flow; + } + + pBNS->num_edges = num_edges; + pBNS->num_vertices += nMaxCGroupNumber; + pBNS->num_c_groups = num_cg; + } + + return ret; +} +/*#endif*/ /* } MOVE_CHARGES == 1 */ + + + + /****************************************************************************/ +void ClearAllBnDataVertices( Vertex *v, Vertex value, int size ) +{ + int i; + for (i = 0; i < size; i++) + { + v[i] = value; + } +} + + +/****************************************************************************/ +void ClearAllBnDataEdges( Edge *e, Vertex value, int size ) +{ + int i; + for (i = 0; i < size; i++) + { + e[i][0] = value; + } +} + + +/****************************************************************************/ +BN_DATA *DeAllocateBnData( BN_DATA *pBD ) +{ + if (pBD) + { + if (pBD->BasePtr) + { + inchi_free( pBD->BasePtr ); + } + if (pBD->SwitchEdge) + { + inchi_free( pBD->SwitchEdge ); + } + if (pBD->Tree) + { + inchi_free( pBD->Tree ); + } + if (pBD->ScanQ) + { + inchi_free( pBD->ScanQ ); + } + if (pBD->Pu) + { + inchi_free( pBD->Pu ); + } + if (pBD->Pv) + { + inchi_free( pBD->Pv ); + } +#if ( BNS_RAD_SEARCH == 1 ) + if (pBD->RadEndpoints) + { + inchi_free( pBD->RadEndpoints ); + } + if (pBD->RadEdges) + { + inchi_free( pBD->RadEdges ); + } +#endif + inchi_free( pBD ); + } + + return NULL; +} + + +/****************************************************************************/ +BN_DATA *AllocateAndInitBnData( int max_num_vertices ) +{ + BN_DATA *pBD = NULL; + int max_len_Pu_Pv; + max_num_vertices = 2 * max_num_vertices + 2; + max_len_Pu_Pv = max_num_vertices / 2 + 1; + max_len_Pu_Pv += max_len_Pu_Pv % 2; /* even length */ + if (!( pBD = (BN_DATA *) inchi_calloc( 1, sizeof( BN_DATA ) ) ) || + !( pBD->BasePtr = (Vertex *) inchi_calloc( max_num_vertices, sizeof( Vertex ) ) ) || + !( pBD->SwitchEdge = (Edge *) inchi_calloc( max_num_vertices, sizeof( Edge ) ) ) || + !( pBD->Tree = (S_CHAR *) inchi_calloc( max_num_vertices, sizeof( S_CHAR ) ) ) || + !( pBD->ScanQ = (Vertex *) inchi_calloc( max_num_vertices, sizeof( Vertex ) ) ) || + !( pBD->Pu = (Vertex *) inchi_calloc( max_len_Pu_Pv, sizeof( Vertex ) ) ) || +#if ( BNS_RAD_SEARCH == 1 ) + !( pBD->RadEndpoints = (Vertex *) inchi_calloc( max_len_Pu_Pv, sizeof( Vertex ) ) ) || + !( pBD->RadEdges = (EdgeIndex*) inchi_calloc( max_len_Pu_Pv, sizeof( EdgeIndex ) ) ) || +#endif + !( pBD->Pv = (Vertex *) inchi_calloc( max_len_Pu_Pv, sizeof( Vertex ) ) ) + ) + { + pBD = DeAllocateBnData( pBD ); + } + else + { + /* Initialize data */ + ClearAllBnDataEdges( pBD->SwitchEdge, NO_VERTEX, max_num_vertices ); + ClearAllBnDataVertices( pBD->BasePtr, NO_VERTEX, max_num_vertices ); + memset( pBD->Tree, TREE_NOT_IN_M, max_num_vertices ); /* djb-rwth: memset_s C11/Annex K variant? */ + pBD->QSize = -1; + pBD->max_len_Pu_Pv = max_len_Pu_Pv; + pBD->max_num_vertices = max_num_vertices; +#if ( BNS_RAD_SEARCH == 1 ) + pBD->nNumRadEndpoints = 0; +#endif + } + + return pBD; +} + + +/****************************************************************************/ +int ReInitBnData( BN_DATA *pBD ) +{ + int i, ret = 0; + Vertex u, v; + if (pBD) + { + if (!pBD->ScanQ) + { + ret += 2; + } + if (!pBD->BasePtr) + { + ret += 4; + } + if (!pBD->SwitchEdge) + { + ret += 8; + } + if (!pBD->Tree) + { + ret += 16; + } + if (!ret) + { + for (i = 0; i <= pBD->QSize; i++) + { + u = pBD->ScanQ[i]; + v = prim( u ); + pBD->BasePtr[u] = + pBD->BasePtr[v] = + pBD->SwitchEdge_Vert1( u ) = + pBD->SwitchEdge_Vert1( v ) = NO_VERTEX; + pBD->Tree[u] = + pBD->Tree[v] = TREE_NOT_IN_M; + } + } + pBD->QSize = -1; + if (!pBD->Pu) + { + ret += 32; + } + if (!pBD->Pv) + { + ret += 64; + } + } + else + { + ret += 1; + } + + return ret; +} + + +/****************************************************************************/ +int GetVertexDegree( BN_STRUCT* pBNS, Vertex v ) +{ + int i = v / 2 - 1; + if (i >= 0) + { + if (pBNS->vert[i].st_edge.cap > 0) + { + return pBNS->vert[i].num_adj_edges + 1; /* add 1 neighbor for s or t */ + } + else + { + return 0; /* since the edge s-v has zero capacity, we ignore vertex v */ + } + } + else + { + return pBNS->num_vertices; + } +} + + +/****************************************************************************/ +Vertex Get2ndEdgeVertex( BN_STRUCT* pBNS, Edge uv ) +{ + /* + Vertex ret; + */ + if (uv[1] >= 0) + { + /* -- debug -- + if ( uv[1] > pBNS->num_edges || uv[0] > 2*pBNS->num_vertices+3 ) { + int stop = 1; + } + ret = ((uv[0]-2) ^ (2*pBNS->edge[uv[1]].neighbor12+1)) + 2; + if ( ret > 2*pBNS->num_vertices+3 ) { + int stop = 1; + } + return ret; + -- end debug -- */ + + return ( ( uv[0] - 2 ) ^ ( 2 * pBNS->edge[uv[1]].neighbor12 + 1 ) ) + 2; + + /*short u = uv[0]-FIRST_INDX; */ + /*short t = 2*(((u / 2 - 1) ^ pBNS->edge[uv[1]].neighbor12) + 1) + ((u+1) & 1) + FIRST_INDX; */ + /*return t; */ + } + + if (uv[0] <= 1) + { + return -( 1 + uv[1] ); /* vertex1 is s or t, return x or y */ + } + else + { + return uv[0] % 2; /* vertex1 is x or y, return s or t; never happens? -- NSC 3737, 7634,... */ + } + +} + + +/****************************************************************************/ +Vertex GetVertexNeighbor( BN_STRUCT* pBNS, + Vertex v, + int neigh, + EdgeIndex *iedge ) +{ + /* neigh = 0 => the neighbor is s or t except case when v is s or t. */ + /* v= FIRST_INDX or FIRST_INDX+1: v is s or t respectively */ + int i, neighbor; + if (( i = v - 2 ) >= 0) + { + /* Neighbor of x or y */ + if (neigh) + { + neigh--; + /* x or y */ + *iedge = pBNS->vert[i / 2].iedge[neigh]; + if (!( pBNS->edge[*iedge].cap & EDGE_FLOW_MASK ) || IS_FORBIDDEN( pBNS->edge[*iedge].forbidden, pBNS )) + { + return NO_VERTEX; + } + neighbor = ( i ^ ( 2 * pBNS->edge[*iedge].neighbor12 + 1 ) ) + 2; /* parity opposite to v parity */ + } + else + { + /* neighbor of x or y is s or t */ + neighbor = ( v & 1 ); /* s or t, same parity as v */ + *iedge = -( neighbor + 1 ); + } + } + else + { + /* neighbor of s or t: x or y, same parity as v */ + if (!( pBNS->vert[neigh].st_edge.cap & EDGE_FLOW_ST_MASK )) + { + return NO_VERTEX; + } + neighbor = 2 * neigh + 2 + ( v & 1 ); /* parity same as the parity of v */ + *iedge = -( neighbor + 1 ); + } + + return neighbor; +} + + +/****************************************************************************/ +int GetEdgePointer( BN_STRUCT* pBNS, + Vertex u, + Vertex v, + EdgeIndex iuv, + BNS_EDGE **uv, + S_CHAR *s_or_t ) +{ + int i = u / 2 - 1; + int j = v / 2 - 1; + int bBackward = BNS_WRONG_PARMS; + *uv = NULL; + if (i >= 0) + { + /* u is an atom */ + if (j >= 0) + { + /* v is an atom */ + if (( u + v ) % 2) + { + *uv = pBNS->edge + iuv; + bBackward = ( u & 1 ); + *s_or_t = 0; + } + } + else + { + /* v is s or t */ + if (v >= 0 && !( ( u + v ) % 2 )) + { + *uv = (BNS_EDGE*) &pBNS->vert[i].st_edge; + bBackward = !( v & 1 ); + *s_or_t = v + 3; /* 3=> v=s, 4=> v=t */ + } + } + } + else + { + if (j >= 0) + { + /* u is s or t */ + if (u >= 0 && !( ( u + v ) % 2 )) + { + /* v is an atom */ + *uv = (BNS_EDGE*) &pBNS->vert[j].st_edge; + bBackward = ( u & 1 ); + *s_or_t = u + 1; /* 1=> u=s, 2=> u=t */ + } + } + } + + return bBackward; +} + + +/****************************************************************************/ +int AugmentEdge( BN_STRUCT* pBNS, + Vertex u, + Vertex v, + EdgeIndex iuv, + int delta, + S_CHAR bReverse, + int bChangeFlow ) +{ + int f, flow, ret = 0; + + BNS_ST_EDGE *pst_edge; + BNS_EDGE *pedge; + S_CHAR s_or_t; + int bBackward = GetEdgePointer( pBNS, u, v, iuv, &pedge, &s_or_t ); + if (!IS_BNS_ERROR( bBackward )) + { + if (bBackward) + { + delta = -delta; + } + + if (s_or_t) + { + pst_edge = (BNS_ST_EDGE *) pedge; + flow = pst_edge->flow; + f = ( flow & EDGE_FLOW_ST_MASK ) + delta; /* new flow */ + if (!delta) + { + /*((BNS_ST_EDGE *)pedge)->flow = pst_edge->flow & ~EDGE_FLOW_ST_PATH;*/ + pst_edge->flow = pst_edge->flow & ~EDGE_FLOW_ST_PATH; + } + else + { + int cap = pst_edge->cap; + if (f < 0 || f > cap) + { + ret = BNS_WRONG_PARMS; + } + else + { + if (!( bChangeFlow & BNS_EF_CHNG_FLOW )) + { + f -= delta; /* do not actually change the flow, only find the augmenting path */ + } + else + { + if (delta) + { + /*((BNS_ST_EDGE *)pedge)->pass ++;*/ + pst_edge->pass++; + } + } + flow = ( flow & ~( EDGE_FLOW_ST_PATH | EDGE_FLOW_ST_MASK ) ) + f; + /*((BNS_ST_EDGE *)pedge)->flow = flow;*/ + pst_edge->flow = flow; + /*((BNS_ST_EDGE *)pedge)->delta += delta; */ + if (bReverse) + { + /* u <- v; Note: in case of bReverse s_or_t has actually been determined + for the u' <- v' pair; therefore s and t should be switched + in order to correctly determine the 1st or the last atom + on the augmenting path. + */ + switch (s_or_t) + { + case 1: /* u = t: t<-v, v is the last vertex */ + ALTP_END_ATOM( pBNS->alt_path ) = v / 2 - 1; + break; + case 2: /* u = s: s<-v, error */ + ret = BNS_WRONG_PARMS; + break; + case 3: /* v = t: u<-t, error */ + ret = BNS_WRONG_PARMS; + break; + case 4: /* v = s: u<-s, u is the first vertex */ + ALTP_START_ATOM( pBNS->alt_path ) = u / 2 - 1; + ALTP_DELTA( pBNS->alt_path ) = delta; + break; + default: + ret = BNS_WRONG_PARMS; + break; + } + } + else + { + /* u -> v */ + switch (s_or_t) + { + case 1: /* u = s: s->v, v is the first vertex */ + ALTP_START_ATOM( pBNS->alt_path ) = v / 2 - 1; + ALTP_DELTA( pBNS->alt_path ) = delta; + break; + case 2: /* u = t: t->v, error */ + ret = BNS_WRONG_PARMS; + break; + case 3: /* v = s: u->s, error */ + ret = BNS_WRONG_PARMS; + break; + case 4: /* v = t: u->t, u is the last vertex */ + ALTP_END_ATOM( pBNS->alt_path ) = u / 2 - 1; + break; + default: + ret = BNS_WRONG_PARMS; + break; + } + } + } + } + } + else + { + f = ( pedge->flow & EDGE_FLOW_MASK ) + delta; + if (!delta) + { + pedge->flow &= ~EDGE_FLOW_PATH; + } + else + { + if (f < 0 || f > pedge->cap) + { + ret = BNS_WRONG_PARMS; + } + else + { + AT_NUMB iu = u / 2 - 1; + AT_NUMB iv = v / 2 - 1; + int indx; + if (!( bChangeFlow & BNS_EF_CHNG_FLOW )) + { + f -= delta; /* do not actually change the flow, only find the augmenting path */ + } + else + { + if (delta) + { + pedge->pass++; + } + } + pedge->flow = ( pedge->flow & ~( EDGE_FLOW_PATH | EDGE_FLOW_MASK ) ) | f; + if (ALTP_MAY_ADD( pBNS->alt_path )) + { + /* bReverse? u <- v : u -> v */ + indx = bReverse ? ( pedge->neighbor1 == iv ) : ( pedge->neighbor1 == iu ); + ALTP_CUR_THIS_ATOM_NEIGHBOR( pBNS->alt_path ) = pedge->neigh_ord[1 - indx]; + ALTP_CUR_NEXT_ATOM_NEIGHBOR( pBNS->alt_path ) = pedge->neigh_ord[indx]; + ALTP_NEXT( pBNS->alt_path ); + } + else + { + ALTP_OVERFLOW( pBNS->alt_path ) = 1; + ret = BNS_ALTPATH_OVFL; + } + } + } + } + return ret ? ret : f; + } + + return bBackward; +} + + +/**************************************************************************** +rescap_mark( ... ) + +Find residual capacity and mark the edge +as belonging to the augmenting path +****************************************************************************/ +int rescap_mark( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv ) +{ + BNS_ST_EDGE *pst_edge; + BNS_EDGE *pedge; + + int f, flow; + S_CHAR s_or_t; + int bBackward = GetEdgePointer( pBNS, u, v, iuv, &pedge, &s_or_t ); + + if (!IS_BNS_ERROR( bBackward )) + { + if (s_or_t) + { + pst_edge = (BNS_ST_EDGE *) pedge; + flow = pst_edge->flow; + f = ( flow & EDGE_FLOW_ST_MASK ); + if (!bBackward) + { + f = (int) pst_edge->cap - f; + } + if (flow & EDGE_FLOW_ST_PATH) + { + pBNS->bNotASimplePath++; + f /= 2; /* this is the second time we pass the same edge: reduce flow by a factor of 2 */ + } + else + { + pst_edge->flow |= EDGE_FLOW_ST_PATH; /* mark the edge */ + } + } + else + { + flow = pedge->flow; + f = flow & EDGE_FLOW_MASK; + if (!bBackward) + { + f = (int) pedge->cap - f; + } + if (flow & EDGE_FLOW_PATH) + { + f /= 2; /* this is the second time we pass the same edge: reduce flow by a factor of 2 */ + pBNS->bNotASimplePath++; + } + else + { + pedge->flow |= EDGE_FLOW_PATH; /* mark the edge */ + } + } + return f; + } + + return bBackward; +} + + +/**************************************************************************** +GetPrevVertex( ... ) + +Get previous vertex in the searched path +z is SwitchEdge_Vert2(y) != y. Go backward from z to y +****************************************************************************/ +Vertex GetPrevVertex( BN_STRUCT* pBNS, Vertex y, Edge *SwitchEdge, EdgeIndex *iuv ) +{ + Vertex w, z, x2, y2; /* djb-rwth: removing redundant variables */ + EdgeIndex iwy; + + w = SwitchEdge_Vert1( y ); + z = SwitchEdge_Vert2( y ); + iwy = SwitchEdge_IEdge( y ); + if (z == y) + { + *iuv = iwy; + return w; + } + x2 = prim( y ); + y2 = prim( z ); + /* djb-rwth: removing redundant code */ + while (y2 != NO_VERTEX) + { + w = SwitchEdge_Vert1( y2 ); + z = SwitchEdge_Vert2( y2 ); + iwy = SwitchEdge_IEdge( y2 ); + if (w == x2) + { + *iuv = iwy; + /*return z; */ + return ( y + z ) % 2 ? z : prim( z ); + } + /* djb-rwth: removing redundant code */ + /* + #ifdef _DEBUG + if ( n ) { + int stop = 1; + } + #endif + */ + if (w == y2) + { + return NO_VERTEX; + } + y2 = w; + } + + return y2; +} + + + +#define CHECK_TACN 1 + + +/**************************************************************************** +The purpose is to avoid paths + +(H-group)[u]---atom[v]---((-)-cgroup)[w], + +where atom[v] is not acidic and (-) and H are not interchangeable without +explicit bond tautomerism. + +It is important that acidic atoms are only O,S,Se,Te and should have +only one chemical bond. Only because of this an early rejection of +the vertex v (before it gets on SCANQ) is possible. + +CHECK_TACN == 1 prohibits replacing (-) on N with H unless H can be moved to N +along an alternating path from another heteroatom (t-group will be detected). +****************************************************************************/ + + +#if ( FIX_TACN_POSSIBLE_BUG == 1 ) /* { */ + + +/****************************************************************************/ +int bIgnoreVertexNonTACN_atom( BN_STRUCT* pBNS, Vertex u, Vertex v ) +{ +#define TYPE_T 1 /* t-group [also called H-group] */ +#define TYPE_CN 2 /* (-)c-group */ + int i, degree, ret, u_is_taut = 0, w_is_taut, num_allowed = 0, num_found_groups = 0; + Vertex w; + EdgeIndex ivw; + if (!pBNS->type_TACN || u <= 1 || v <= 1 || + ( pBNS->vert[v / 2 - 1].type & pBNS->type_TACN )) + { + return 0; /* add/remove H(+) is allowed for acidic atoms */ + } + if (!pBNS->type_T || !pBNS->type_CN) + { + return 0; /* should not happen */ + } + u_is_taut = ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) ? TYPE_T : + ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ? TYPE_CN : 0; + if (u_is_taut) + { + /* u is either t-group vertex or (-) c-group */ + degree = GetVertexDegree( pBNS, v ); + for (i = 0; i < degree; i++) + { + /* v = vert[u].neighbor[i]; */ + w = GetVertexNeighbor( pBNS, v, i, &ivw ); + if (w == NO_VERTEX || w <= 1) + { + continue; /* the atom has only single bonds or it is s or t, ignore it */ + } + if (w != u && ( ret = rescap( pBNS, v, w, ivw ) ) > 0) + { + num_allowed++; + w_is_taut = ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ? TYPE_CN : + ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) ? TYPE_T : 0; + if (( u_is_taut | w_is_taut ) == ( TYPE_T | TYPE_CN )) + { + num_found_groups++; + } + } + } + if (num_found_groups && num_allowed == 1) + { + return 1; /* reject */ + } + } + + return 0; +#undef TYPE_T +#undef TYPE_CN +} + + +#else /* } FIX_TACN_POSSIBLE_BUG { */ + + +/****************************************************************************/ +int bIgnoreVertexNonTACN_atom( BN_STRUCT* pBNS, Vertex u, Vertex v ) +{ + int i, degree, ret, u_is_taut = 0, num_allowed = 0, num_found_groups = 0; + Vertex w; + EdgeIndex ivw; + if (!pBNS->type_TACN || u <= 1 || v <= 1 || + ( pBNS->vert[v / 2 - 1].type & pBNS->type_TACN )) + { + return 0; /* add/remove H(+) is allowed for acidic atoms */ + } + if (!pBNS->type_T || !pBNS->type_CN) + { + return 0; /* should not happen */ + } + if (( u_is_taut = ( pBNS->vert[u / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) || + ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN )) + { + /* u is either t-group vertex or (-) c-group */ + degree = GetVertexDegree( pBNS, v ); + for (i = 0; i < degree; i++) + { + /* v = vert[u].neighbor[i]; */ + w = GetVertexNeighbor( pBNS, v, i, &ivw ); + if (w == NO_VERTEX || w <= 1) + { + continue; /* the atom has only single bonds or it is s or t, ignore it */ + } + if (w != u && ( ret = rescap( pBNS, v, w, ivw ) ) > 0) /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + { + num_allowed++; + if (( u_is_taut ? ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) : + ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) )) + { + num_found_groups++; + } + } + } + if (num_found_groups && num_allowed == 1) + { + return 1; /* reject */ + } + } + + return 0; +} + + + +#endif /* } FIX_TACN_POSSIBLE_BUG */ + + + +/**************************************************************************** +The purpose is to avoid paths +(H-group)[u]---atom[v]---((-)-cgroup)[w], + +where atom[v] is not acidic and (-) and H are not interchangeable without +explicit bond tautomerism. + +It is important that acidic atoms are only O,S,Se,Te and should have +only one chemical bond. Only because of this an early rejection of +the vertex v (before it gets on SCANQ) is possible. +****************************************************************************/ + + +#if ( FIX_TACN_POSSIBLE_BUG == 1 ) /* { */ + + +/****************************************************************************/ +int bIgnoreVertexNonTACN_group( BN_STRUCT* pBNS, + Vertex v, + Vertex w, + Edge *SwitchEdge ) +{ +#define TYPE_T 1 /* t-group [also called H-group] */ +#define TYPE_CN 2 /* (-)c-group */ + int u_is_taut = 0, w_is_taut = 0; + Vertex u; + EdgeIndex iuv; + if (v <= 1 || w <= 1) + return 0; +#if ( CHECK_TACN == 1 ) + if (!pBNS->type_TACN || + ( pBNS->vert[v / 2 - 1].type & pBNS->type_TACN )) + { + return 0; + } + if (!pBNS->type_T || !pBNS->type_CN) + { + return 0; /* should not happen */ + } +#endif + u = GetPrevVertex( pBNS, v, SwitchEdge, &iuv ); + /* + u = SwitchEdge_Vert1(v); + iuv = SwitchEdge_IEdge(v); + */ + if (u == NO_VERTEX || iuv < 0) + return 0; /* should not happen */ + /* check edge adjacency */ + if (pBNS->edge[iuv].neighbor1 != ( u / 2 - 1 ) && pBNS->edge[iuv].neighbor1 != v / 2 - 1 || + ( pBNS->edge[iuv].neighbor12 ^ ( u / 2 - 1 ) ) != ( v / 2 - 1 )) + { + return 0; /* !!! should not happen !!! */ + } + +#if ( CHECK_TACN == 1 ) + u_is_taut = ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) ? TYPE_T : + ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ? TYPE_CN : 0; + w_is_taut = ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) ? TYPE_T : + ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ? TYPE_CN : 0; + if (( u_is_taut | w_is_taut ) == ( TYPE_T | TYPE_CN )) + { + /* rescap must have already been checked */ + return 1; + } +#endif + + return 0; +#undef TYPE_T +#undef TYPE_CN +} + + +#else /* } FIX_TACN_POSSIBLE_BUG { */ + + +/****************************************************************************/ +int bIgnoreVertexNonTACN_group( BN_STRUCT* pBNS, + Vertex v, + Vertex w, + Edge *SwitchEdge ) +{ + int u_is_taut = 0, w_is_taut = 0; + Vertex u; + EdgeIndex iuv; + if (v <= 1 || w <= 1) + return 0; +#if ( CHECK_TACN == 1 ) + if (!pBNS->type_TACN || + ( pBNS->vert[v / 2 - 1].type & pBNS->type_TACN )) + { + return 0; + } + if (!pBNS->type_T || !pBNS->type_CN) + { + return 0; /* should not happen */ + } +#endif + u = GetPrevVertex( pBNS, v, SwitchEdge, &iuv ); + /* + u = SwitchEdge_Vert1(v); + iuv = SwitchEdge_IEdge(v); + */ + if (u == NO_VERTEX || iuv < 0) + { + return 0; /* should not happen */ + } + /* check edge adjacency */ + if ((pBNS->edge[iuv].neighbor1 != ( u / 2 - 1 ) && pBNS->edge[iuv].neighbor1 != v / 2 - 1) || + (( pBNS->edge[iuv].neighbor12 ^ ( u / 2 - 1 ) ) != ( v / 2 - 1 ))) /* djb-rwth: addressing LLVM warning */ + { + return 0; /* !!! should not happen !!! */ + } + +#if ( CHECK_TACN == 1 ) + if (( ( u_is_taut = ( pBNS->vert[u / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) || + ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ) && + ( ( w_is_taut = ( pBNS->vert[w / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) || + ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ) && + u_is_taut + w_is_taut == 1) + { + /* rescap must have already been checked */ + return 1; + } +#endif + + return 0; +} +#endif /* } FIX_TACN_POSSIBLE_BUG { */ + + + +#if ( FIX_KEEP_H_ON_NH_ANION == 1 ) + + +/**************************************************************************** +bIsRemovedHfromNHaion( ... ) + +Detect an attempt to remove H from -NH(-) to make =N(-); +all taut atoma except N are 'acidic' +****************************************************************************/ +int bIsRemovedHfromNHaion( BN_STRUCT* pBNS, Vertex u, Vertex v ) +{ + int i, u2, v2, vat2; + Vertex vtg, vat; + BNS_VERTEX *pvAT, *pvCN; + BNS_EDGE *pEdge; + if (!pBNS->type_TACN || u <= 1 || v <= 1 || + u % 2 || !( v % 2 ) /* the edge flow may only increase */) + { + return 0; + } + if (( pBNS->vert[u2 = u / 2 - 1].type & pBNS->type_TACN ) || + ( pBNS->vert[v2 = v / 2 - 1].type & pBNS->type_TACN )) + { + return 0; /* add/remove H is allowed for acidic atoms */ + } + if (!pBNS->type_T || !pBNS->type_CN) + { + return 0; /* should not happen */ + } + /* find which of u, v vertices is N and which is t-group */ + if (( ( pBNS->vert[u2].type & pBNS->type_T ) == pBNS->type_T ) && v2 < pBNS->num_atoms) + { + vtg = u; + vat = v; + } + else + { + if (( ( pBNS->vert[v2].type & pBNS->type_T ) == pBNS->type_T ) && u2 < pBNS->num_atoms) + { + vtg = v; + vat = u; + } + else + { + return 0; + } + } + + vat2 = vat / 2 - 1; + pvAT = pBNS->vert + vat2; /* atom */ + for (i = pvAT->num_adj_edges - 1; 0 <= i; i--) + { + pEdge = pBNS->edge + pvAT->iedge[i]; + pvCN = pBNS->vert + ( pEdge->neighbor12 ^ vat2 ); + if (( ( pvCN->type & pBNS->type_CN ) == pBNS->type_CN ) && pEdge->flow > 0) + { + return 1; /* detected */ + } + } + + return 0; +} +#endif + + +#if ( FIX_AVOID_ADP == 1 ) + +/**************************************************************************** +bIsAggressiveDeprotonation( ... ) + +Detect (tg)-N=A-A=A-A=N-(tg) +u v w +k = 5 4 3 2 1 0 1 2 +^ +odd number means ADP +****************************************************************************/ +int bIsAggressiveDeprotonation( BN_STRUCT* pBNS, + Vertex v, + Vertex w, + Edge *SwitchEdge ) +{ +#define TYPE_T 1 /* t-group [also called H-group] */ +#define TYPE_CN 2 /* (-)c-group */ +#define TYPE_AT 4 + int k, v2, u2, w2, u2_next, type0, type1, type2, type; + Vertex u, u_next; + EdgeIndex iuv; + + if (v <= 1 || w <= 1) + { + return 0; + } + + if (!pBNS->type_TACN || !pBNS->type_T || !pBNS->type_CN) + { + return 0; /* should not happen */ + } + + v2 = v / 2 - 1; + w2 = w / 2 - 1; + if (v2 >= pBNS->num_atoms || w2 < pBNS->num_atoms) + { + goto cross_edge; + } + + if (!( ( pBNS->vert[w2].type & pBNS->type_T ) == pBNS->type_T ) && + !( ( pBNS->vert[w2].type & pBNS->type_CN ) == pBNS->type_CN )) + { + goto cross_edge; + } + + /* v ia an atom, w is a t-group, v != w' */ + for (k = 0, u = v; 1 < ( u_next = u, u = GetPrevVertex( pBNS, u, SwitchEdge, &iuv ) ); k++) + { + u2 = u / 2 - 1; + if (u2 >= pBNS->num_atoms) + { + /* Moving backward along the alt path we have found a vertex + that is not an atom. Possibly it is a t- or (-)c-group */ + if (!( k % 2 )) + { + return 0; /* even vertex -- always okay */ + } + if (!( ( pBNS->vert[u2].type & pBNS->type_T ) == pBNS->type_T ) && + !( ( pBNS->vert[u2].type & pBNS->type_CN ) == pBNS->type_CN )) + { + /* not a t- or (-)c-group */ + return 0; + } + u2_next = u_next / 2 - 1; + if (!( pBNS->vert[v2].type & pBNS->type_TACN ) && + !( pBNS->vert[u2_next].type & pBNS->type_TACN )) + { + /* none of the atoms at the ends are N */ + return 0; + } + return 1; + } + } + + return 0; + +cross_edge: + + /***************************************************************************** + * v and w (v=w') are same vertex reached with opposite "phases". + * w cannot be (t) because this would have been detected earlier -- ??? + * (t)-A=A-A=A-A=A-(t) + * v + * 3 2 1 0 1 2 3 4 + * kv kw + * (kv + kw)%2 == 1 <==> aggressive deprotonation + *****************************************************************************/ + + if (v == prim( w )) + { + type0 = 0; + if (v2 >= pBNS->num_atoms) + { + type0 = ( ( pBNS->vert[v2].type & pBNS->type_T ) == pBNS->type_T ) ? TYPE_T : + ( ( pBNS->vert[v2].type & pBNS->type_CN ) == pBNS->type_CN ) ? TYPE_CN : 0; + } + } + + return 0; +} +#endif + + +/****************************************************************************/ +int rescap( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv ) +{ + BNS_ST_EDGE *pst_edge; + BNS_EDGE *pedge; + + int f; + S_CHAR s_or_t; + int bBackward = GetEdgePointer( pBNS, u, v, iuv, &pedge, &s_or_t ); + + if (!IS_BNS_ERROR( bBackward )) + { + + if (s_or_t) + { + pst_edge = (BNS_ST_EDGE *) pedge; + f = ( pst_edge->flow & EDGE_FLOW_ST_MASK ); + if (!bBackward) + { + f = (int) pst_edge->cap - f; + } + } + else + { + f = ( pedge->flow & EDGE_FLOW_MASK ); + if (!bBackward) + { + f = (int) pedge->cap - f; + } + } + return f; + } + + return bBackward; /* error */ +} + + +/**************************************************************************** +W.Kocay, D.Stone, +"An Algorithm for Balanced Flows", +The Journal of Combinatorial Mathematics and Combinatorial Computing, +vol. 19 (1995) pp. 3-31 + +W.Kocay, D.Stone, +"Balanced network flows", +Bulletin of the Institute of Combinatorics and its Applications, +vol. 7 (1993), pp. 17--32 + +N = a balanced network (bipartite directed graph) of: +n=2*V+2 vertices (incl. s (source) and t (target); +each other vertex i is included 2 times: +set X (x[i]) of V vertices (v) and a set Y (y[j]) of +V complementary vertices (v') so that x[i]' = y[i], x[i]''=x[i], and +m=2*E+2*V edges (each original undirected edge i-j is represented as +2 directed edges: x[i]->y[j] and x[j]->y[i]; plus +V edges s->x[i] and V edges y[j]->t) +v' = a complement vertex to v +v'u' = (uv)' = a complement edge to uv +rescap(uv) = cap(uv)-f(uv) if uv is a forward edge += f(uv) if uv is a backward edge +(i) 0 <= f(uv) <= cap(uv) +(ii) f+(u) = f-(u) for all u in X, Y where f+(u) is a total flow out of u, +and f-(u) is a total flow into u +(iii) f(uv) = f((uv)') (balanced flow condition) + +S = a set of all s-searchable vertices +S- = all other vertices +if t in S, then N contains a valid augmenting path P, so that flow can be +augmented on both P and P' +if t not in S, then let K=[S,S-], the set of all edges directed from S to S-. +K is an edge-cut that has a special structure. +Let +A = {x[i], y[i] |x[i] not in S, y[i] in S} +B = {x[i], y[i] |x[i] in S, y[i] not in S} +C = {x[i], y[i] |x[i] in S, y[i] in S} +D = {x[i], y[i] |x[i] not in S, y[i] not in S} +N[C] = subgraph of N induced by C; +it consists of of a number of connected components C[i] +K[i] = those edges of K with one endpoint in C[i]. + +If t is in S- then + +i) Each C[i] = C[i]' +ii) There are no edges between C and D +iii) Each K[i] has odd capacity, it is called a balanced edge-cut. + +balcap(K) = cap(K) - odd(K), where odd(K) is the number of connected components in N[C]. +Name "odd(K)" is because each cap(K[i]) is odd. + +Max-Balanced-Flow-Min-Balanced-Cut Theorem: + +Let f be a balanced flow in N, and let K be any balanced edge-cut. +The value of a maximum balanced flow equals the capacity of a minimum +edge-cut, that is, val(f) = balcap(K) when f is maximum and K is minimum. + +****************************************************************************/ + + +/*******************************************************/ +/* */ +/* VERTEX NUMBERING */ +/* */ +/* Total number of atoms = n */ +/* Total number of vertices = 2*n+2 */ +/*******************************************************/ +/* */ +/* atom numbering starts from 0: */ +/* */ +/* atoms s t x0 y0 x1 y1 ... xi yi ...xn yn */ +/* vertices 0 1 2 3 4 5 ... 2i-2 2i-1 ...2n-2 2n-1 */ +/* */ +/* atom = vertex/2-1; if negative then s or t */ +/* */ +/* vertex = (atom + 1) * 2 + i; i=0 for x, i=1 for y */ +/* */ +/*******************************************************/ + +/*********************************************************************************/ +/* v' variable is called prim(v) for now */ +/*********************************************************************************/ + +/* +BalancedNetworkSearch( ... ) + +N has source s, target t, the mirror network M is constructed. +The tree T contains a valid sv-path for each v in T. Simultaneously, the complementary +tree T' is built as indicated in comments. The trees T and T' must have no edges or +vertices in common. Initially T will be built as in breadth-first-search, and T' will +be the complementary tree, it will contain the complementary valid v't-path. + +NB: this procedure is _not_ recursive + +*/ + + +/****************************************************************************/ +int BalancedNetworkSearch( BN_STRUCT* pBNS, BN_DATA *pBD, int bChangeFlow ) + +{ + Vertex *BasePtr = pBD->BasePtr; + Edge *SwitchEdge = pBD->SwitchEdge; + S_CHAR *Tree = pBD->Tree; + Vertex *ScanQ = pBD->ScanQ; + int QSize = pBD->QSize; + Vertex *Pu = pBD->Pu; + Vertex *Pv = pBD->Pv; + int max_len_Pu_Pv = pBD->max_len_Pu_Pv; + + /* added to translate into C */ + int i, k, degree, delta, ret = 0; + Vertex u, b_u, v, b_v, w; + EdgeIndex iuv; +#if ( BNS_RAD_SEARCH == 1 ) + int n, bRadSearch = ( BNS_EF_RAD_SRCH & bChangeFlow ) && pBD->RadEndpoints; + BRS_MODE bRadSrchMode = RAD_SRCH_NORM; + int bRadSearchPrelim = 0; + if (bRadSearch) + { + pBD->nNumRadEndpoints = 0; + bRadSrchMode = pBD->bRadSrchMode; + bRadSearchPrelim = pBNS->type_TACN && bRadSrchMode == RAD_SRCH_NORM; + } +#endif + + /* -- Always -- + Vertex_s = FIRST_INDX; + Vertex_t = Vertex_s+1; + */ + QSize = k = 0; /* put s on ScanQ = set S */ + ScanQ[QSize] = Vertex_s; + BasePtr[Vertex_t] = Vertex_s; + BasePtr[Vertex_s] = BLOSSOM_BASE; /* create initial blossom C(Vertex_s) with base s */ + Tree[Vertex_s] = TREE_IN_1; + + do + { + u = ScanQ[k]; /* select u from the head of ScanQ */ + /* since u is on the queue, it has a blossom C(U) with base b_u */ + b_u = FindBase( u, BasePtr ); + degree = GetVertexDegree( pBNS, u ); +#if ( BNS_RAD_SEARCH == 1 ) + n = 0; +#endif + for (i = 0; i < degree; i++) + { + /* v = vert[u].neighbor[i]; */ + v = GetVertexNeighbor( pBNS, u, i, &iuv ); + if (v == NO_VERTEX) + { + continue; /* the atom has only single bonds, ignore it */ + } +#if ( BNS_RAD_SEARCH == 1 ) + if (!k && bRadSrchMode == RAD_SRCH_FROM_FICT && v / 2 <= pBNS->num_atoms) + { + continue; /* start from fict. vertices only */ + } + if (bRadSearchPrelim && v / 2 > pBNS->num_atoms) + { + continue; /* during initial add/remove H allow radical movement only through real atoms */ + } +#endif + if ( /* PrevPt[u] != v ** avoid edges of T */ + ( SwitchEdge_Vert1( u ) != v || SwitchEdge_Vert2( u ) != u ) /* avoid edges of T */ + && ( ret = rescap( pBNS, u, v, iuv ) ) > 0) + { + /* Special treatment to prevent H<->(-) replacement on non-acidic atoms */ + /*----------------------------------------------------------------------*/ + if (pBNS->type_TACN) + { + if (bIgnoreVertexNonTACN_atom( pBNS, u, v )) + { + continue; + } + if (bIgnoreVertexNonTACN_group( pBNS, u, v, SwitchEdge )) + { + continue; + } +#if ( FIX_KEEP_H_ON_NH_ANION == 1 ) + if (bIsRemovedHfromNHaion( pBNS, u, v )) + { + continue; + } +#endif +#if ( FIX_AVOID_ADP == 1 ) + if (bIsAggressiveDeprotonation( pBNS, u, v, SwitchEdge )) + { + continue; + } +#endif + } + /*----------------------------------------------------------------------*/ + b_v = FindBase( v, BasePtr ); /* Notation: b_x is a base of x */ + + if (b_v == NO_VERTEX) + { + /* Originally 0 instead of NO_VERTEX */ + + /* Important note: following "A. Note of Implementing the Algorithm" from the + article by Kocay and Stone, all references to PrevPt[a] have been + replaced with SwitchEdge[a][0]=SwitchEdge_Vert1(a); to be on a safe side + the check whether (SwitchEdge_Vert2(a)==a) has been added. + */ + + /* v is not yet in T or T' -- add it to T and M */ + /*PrevPt[v] = u; ** this effectively adds v to T and v' to T' */ + + QSize++; + ScanQ[QSize] = v; + TREE_MARK( v, TREE_IN_1 ); /* mark v s-reachable (in T) */ + TREE_MARK( prim( v ), TREE_IN_2 ); /* mark v' in T' */ + + /* Switch Edges: If u in T then Pu (a valid su-path) can be constructed + by successfully executing u=PrevPt[u] until u=s. + For vertices in T' the situation is different. + Suppose uv and v'u' are added to a mirror network M creating a blossom: + + s T (Note: in the code v' is prim(v), + T / \ u' is prim(u), etc.) + / ... + w=x1 + / \ u in T, v in T' + u=y2 v'=y3 + \ / <--- two added edges uv and (uv)'=v'u' + -------- X ------------intersection of the edges ------------------------ + / \ <--- (the edges intersection in the picture is shown as X) + u'=x2 v=x3 u' it T', v' in T + \ / + T' w'=y1 + \ ... + \ / + t T' + + Vertices v and u' now become s-reachable; + The valid paths to v and u' must use the edges uv and v'u' respectively. + + For each vertex z in S we define a switch-edge that allows a valid sz-path + to be constructed, SwitchEdge[v]=uv and SwitchEdge[u']=v'u'. (We don't + know the direction of the edge uv, it may be (u,v) or (v,u). In either case, + the complementary edge is indicated by v'u'). + + Vertex w' also becomes s-reachable when uv is added to M, and a valid sw'-path + must use one of uv and v'u'. Therefore we choose one of them, say uv (see below + the rule of choosing the switch-edge), and define SwitchEdge[w'] = uv. + + When the addition of an edge uv to M causes a vertex z to become s-reachable + (where z was previously non-reachable), z is placed on the ScanQ, that is, into S. + The edge uv is said to be a switch-edge for z. + + Rule: We choose the the order of the vertices uv to be such that the valid sz-path + consists of a valid su-path, followed by edge uv, followed by a valid vz-path. + + For vertices z in T we can take SwitchEdge[z]=yz where y=PrevPt[z] since + it is the edge yz that allows z to be s-reachable. + For vertices z not in S we take SwitchEdge[z]=NONE. + + */ + + /* v is not yet in T or T' -- add it to T and M */ + SwitchEdge_Vert1( v ) = u; /* this effectively adds uv and v'u' to M */ + SwitchEdge_IEdge( v ) = iuv; + + BasePtr[prim( v )] = v; + BasePtr[v] = BLOSSOM_BASE; /* create a trivial blossom C(v) with base v */ +#if ( BNS_RAD_SEARCH == 1 ) + n++; +#endif + } + + else if (TREE_IS_S_REACHABLE( prim( v ) ) /*Is_s_Reachable(prim(v)*/ + /* if v' is reachable, an st-path is given by P(u)-uv-P'(v') */ + /*&& PrevPt[prim(u)] != prim(v) ** avoid edges of T' */ + && ( SwitchEdge_Vert1( prim( u ) ) != prim( v ) || SwitchEdge_Vert2( prim( u ) ) != prim( u ) ) /* avoid edges of T' */ + && b_u != b_v + && !( pBNS->type_TACN && bIgnoreVertexNonTACN_group( pBNS, prim( v ), u, SwitchEdge ) ) +#if ( FIX_KEEP_H_ON_NH_ANION == 1 ) + && !( pBNS->type_TACN && bIsRemovedHfromNHaion( pBNS, prim( v ), u ) ) +#endif + ) + { +#if ( BNS_RAD_SEARCH == 1 ) + n++; +#endif + /* There is now a valid sv-path via u avoiding b_v (unless v==b_v) + => u, v, u', and v' now all become part of the same connected component of M[C] */ + + if (b_u < 0) /* djb-rwth: fixing coverity CID #499578 */ + { + return BNS_WRONG_PARMS; + } + + w = MakeBlossom( pBNS, ScanQ, &QSize, Pu, Pv, max_len_Pu_Pv, SwitchEdge, BasePtr, u, v, iuv, b_u, b_v, Tree ); + /* this constructed the new blossom and returned its base */ + + if (IS_BNS_ERROR( w )) + { + pBD->QSize = QSize; + return w; /* error */ + } + + b_u = w; /* the new base of C(u) */ + if (prim( w ) == Vertex_t) + { + /* t is now s-reachable, a valid augmenting path P exists in M */ + delta = FindPathCap( pBNS, SwitchEdge, Vertex_s, Vertex_t, 10000 ); /* compute the residual capacity of P + P' */ + if (IS_BNS_ERROR( delta )) + { + pBD->QSize = QSize; + return delta; /* error */ + } +#if ( ALLOW_ONLY_SIMPLE_ALT_PATH == 1 ) + if (pBNS->bNotASimplePath || abs( delta ) > 1) + { + delta = 0; + } +#endif + if (delta) + { + pBNS->bChangeFlow |= ( bChangeFlow & BNS_EF_CHNG_FLOW ); + } + ret = PullFlow( pBNS, SwitchEdge, Vertex_s, Vertex_t, delta, 0, bChangeFlow ); /* augment on a pair of valid st-paths */ + pBD->QSize = QSize; + return + ( IS_BNS_ERROR( ret ) ? ret : delta ); + } + } + } + + else if (IS_BNS_ERROR( ret )) + { + pBD->QSize = QSize; + return ret; /* error */ + } + } + +#if ( BNS_RAD_SEARCH == 1 ) + if (bRadSearch && !n) + { + /* The BNS stopped at u */ + n = RegisterRadEndpoint( pBNS, pBD, u ); + if (IS_BNS_ERROR( n )) + { + pBD->QSize = QSize; + return n; + } + } +#endif + + k++; /* advance ScanQ */ + } while (k <= QSize); + + + /* if this point is reached, no valid augmenting path exists, ScanQ contains + the set S of all s-reachable vertices and K=[S,S-] is a minimum balanced edge-cut */ + /* ClearFlowMarks( vert, num_vert); */ + + pBD->QSize = QSize; + + return 0; +} + + +/* +Blossoms. + +The vertices of a mirror network M consist T U T'. Intersection T ^ T' is empty. + +The edges of M consist of switch-edges and their complements because edges +are added in complementary pairs, one of which is always a switch-edge. + +The base of every blossom is in T. +Let C(i) be a blossom with base b_i. Since C(i)=C(i)', C(i) contains vertices of T and T'. +Since every valid sv-path to v in C(i) contains b_i, b_i is the first s-reachable vertex of C(i). + +Suppose the mirror network M contains a valid sz-path P(z) to all vertices z in ScanQ. +Every vertex of P(z) is s-reachable therefore its vertices are all in blossoms or +trivial blossoms. + +Let z be an s-reachable vertex and P(z) be a valid path in M. +Then every valid sz-path in M contains exactly the same sequence of blossom bases as P(z). + +*/ + + + +/*********************************************************************** +BasePtr[u] = -2 NO_VERTEX u is not a blossom +-1 BLOSSOM_BASE u is the base of its blossom +v a vertex closer to the base +************************************************************************/ +Vertex FindBase( Vertex u, Vertex *BasePtr ) +{ + if (BasePtr[u] == NO_VERTEX) + { + return NO_VERTEX; + } + else if (BasePtr[u] == BLOSSOM_BASE) + { + return u; + } + else + { + Vertex b; + b = FindBase( BasePtr[u], BasePtr ); + BasePtr[u] = b; /* path compression */ + return b; + } + +} + + +/**************************************************************************** +Returns index of the last path element and the path +****************************************************************************/ +int FindPathToVertex_s( Vertex x, + Edge *SwitchEdge, + Vertex *BasePtr, + Vertex *Path, + int MaxPathLen ) +{ + /* x is the base of a blossom, construct a valid Path of blossom bases to s */ + int i = 0; + Path[i] = x; + while (x != Vertex_s) + { + x = FindBase( SwitchEdge_Vert1( x ), BasePtr ); + if (++i < MaxPathLen) + { + Path[i] = x; + } + else + { + return BNS_WRONG_PARMS; + } + } + + return i; +} + + + +/**************************************************************************** +Make a blossom +****************************************************************************/ +Vertex MakeBlossom( BN_STRUCT* pBNS, + Vertex *ScanQ, + int *pQSize, + Vertex *Pu, + Vertex *Pv, + int max_len_Pu_Pv, + Edge *SwitchEdge, + Vertex *BasePtr, + Vertex u, + Vertex v, + EdgeIndex iuv, + Vertex b_u, + Vertex b_v, + S_CHAR *Tree ) +{ + /* In order to find the base of the new blossom, the paths + P(u) and P(v') are constructed and compared in order to + find the last blossom base they have in common which + is reachable on a valid path. + + Edge uv connects two blossoms, their bases are b_u and b_v. + */ + Vertex w, z; + int len_Pu, len_Pv; + int i, j, k; + EdgeIndex izw; + + len_Pu = FindPathToVertex_s( b_u, SwitchEdge, BasePtr, Pu, max_len_Pu_Pv ); + if (IS_BNS_ERROR( len_Pu )) + { + return len_Pu; + } + len_Pv = FindPathToVertex_s( b_v, SwitchEdge, BasePtr, Pv, max_len_Pu_Pv ); + if (IS_BNS_ERROR( len_Pv )) + { + return len_Pv; + } + i = len_Pu; + j = len_Pv; + /* Initially Pu[i] and Pv[j] both equal to s, but their first elements are different */ + /* Find the last blossom base common to Pu and Pv */ + while (i >= 0 && j >= 0 && Pu[i] == Pv[j]) + { + /* Was (Pu[i]==Pv[j] && i>=0 && j>=0) => tested Pu[-1], Pv[-1] <- pointed by W.Ihlenfeldt 08-26-2004*/ + i--; + j--; + } + i++; + w = Pu[i]; /* w is the last common vertex */ + z = SwitchEdge_Vert1( w ); + izw = SwitchEdge_IEdge( w ); + /* now extend the blossom if rescap(zw) >= 2 */ + while (w != Vertex_s && rescap( pBNS, z, w, izw ) >= 2) + { + i++; + w = Pu[i]; + z = SwitchEdge_Vert1( w ); + izw = SwitchEdge_IEdge( w ); + } + /* w is the base of the new blossom */ + /* first follow the path Pu from w to b_u */ + for (k = i - 1; k >= 0; k--) + { + z = Pu[k]; /* z is the base of the blossom */ + BasePtr[z] = w; + BasePtr[prim( z )] = w; /* w is the new base of the blossom */ + /* z and z' may already be part of a blossom that is being + swallowed into a larger blossom. + We don't want to change the switch edge in that case. + */ + + if (!TREE_IS_ON_SCANQ( prim( z ) ) /*!IsInScanQ(prim(z)) */) + { + SwitchEdge_Vert1( prim( z ) ) = prim( v ); /* set the switch edge of z' */ + /* SwitchEdge[prim(z)][1] = prim(u); */ + SwitchEdge_IEdge( prim( z ) ) = iuv; + ( *pQSize )++; + ScanQ[*pQSize] = prim( z ); /* add z' to ScanQ */ + TREE_MARK( prim( z ), TREE_IN_2BLOSS ); /* mark z' s-reachable */ + } + } + /* Now follow the path Pv */ + for (k = j; k >= 0; k--) /* djb-rwth: converting for loop into while loop to avoid LLVM warning */ + { + z = Pv[k]; /* z is the base of the blossom */ + BasePtr[z] = w; + BasePtr[prim( z )] = w; /* w is the new base of the blossom */ + /* z and z' may already be part of a blossom that is being + swallowed into a larger blossom. + We don't want to change the switch edge in that case. + */ + + if (!TREE_IS_ON_SCANQ( prim( z ) ) /*!IsInScanQ(prim(z)) */) + { + SwitchEdge_Vert1( prim( z ) ) = u; /* set the switch edge of z' */ + /* SwitchEdge[prim(z)][1] = v; */ + SwitchEdge_IEdge( prim( z ) ) = iuv; + ( *pQSize )++; + ScanQ[*pQSize] = prim( z ); /* add z' to ScanQ */ + TREE_MARK( prim( z ), TREE_IN_2BLOSS ); /* mark z' s-reachable */ + } + } + + if (!TREE_IS_ON_SCANQ( prim( w ) ) /* !IsInScanQ(prim(w))*/) + { /* add w' to the blossom */ + SwitchEdge_Vert1( prim( w ) ) = u; /* set the switch edge of w' */ + /* SwitchEdge[prim(w)][1] = v; */ + SwitchEdge_IEdge( prim( w ) ) = iuv; + ( *pQSize )++; + ScanQ[*pQSize] = prim( w ); /* add w' to ScanQ */ + TREE_MARK( prim( w ), TREE_IN_2BLOSS ); /* mark w' s-reachable */ + } + + return w; +} + + +/**************************************************************************** +When t is found to be s-reachable, a valid st-path P is known to exist. +Its complementary path P' is also valid. Once the residual capacity +delta(P) is known, the flow is augmented by calling PullFlow(s,t,delta). +It constructs the path P by using the switch-edges. +Let uv=SwitchEdge[t]. +Then P is given by a valid su-path, followed by the edge uv, followed by +a valid vt-path. +PullFlow is a recursive procedure that constructs the path and its complement. + +Let wz=SwitchEdge[y]. PullFlow(x, y, delta) uses the xw- and zy-portions of P +(see below). Since it must also augment on P' simultaneously, the zy-portion +is replaced by the y'z'-portion. + +x y' +| | P: x--w--z--y +P | | P' P': y'-z'-w'-x' +| o +o \ +/ w' z \ +/ o----\ /----o / +\ / \ / \ / +\/ X \/ +/\ / \ /\ +/ \ w / \ z' / \ +\ o---- ----o / Using a switch-edge wz and w'z' +\ / to construct P and P' +o o +| | +| | +x' y + + +****************************************************************************/ + + + +/* PullFlow( ... ) + +Augment the flow by delta on all edges on a path P +between x and y in the order of the path; +AugmentEdge( pBNS, w, z, iwz, delta, 0 ) means the path is in w->z direction +AugmentEdge( pBNS, w, z, iwz, delta, 1 ) means the path is in w<-z direction + +Unlike PullFlow in the paper by Kocay & Stone, here the augmentation +starts at "s", proceeds sequentially through the path end terminates at "t". +Since we do not really need the complement path, PullFlow ignores it. +*/ + + +/****************************************************************************/ +int PullFlow( BN_STRUCT *pBNS, + Edge *SwitchEdge, + Vertex x, + Vertex y, + int delta, + S_CHAR bReverse, + int bChangeFlow ) +{ + Vertex w, z; + EdgeIndex iwz; + int ret = 0; + + w = SwitchEdge_Vert1( y ); + z = SwitchEdge_Vert2( y ); + iwz = SwitchEdge_IEdge( y ); + if (bReverse) + { + /* P consists of a path from x to w, then wz, then a path from z to y. */ + /* z may equal y, in which case z is just PrevPt[y] */ + if (z != y) + { + ret = PullFlow( pBNS, SwitchEdge, prim( y ), prim( z ), delta, (S_CHAR) ( 1 - bReverse ), bChangeFlow ); /* augment between z and y */ + } + if (!IS_BNS_ERROR( ret )) + { + ret = AugmentEdge( pBNS, w, z, iwz, delta, bReverse, bChangeFlow ); + } + /* Do not augment the complementary path: AugmentEdge( prim(z), prim(w), vert, delta); */ + /* w may equal x, in which case there is no need to call PullFlow(x, w) */ + if (w != x && !IS_BNS_ERROR( ret )) + { + ret = PullFlow( pBNS, SwitchEdge, x, w, delta, bReverse, bChangeFlow ); /* augment between x and w */ + } + } + else + { + /* P consists of a path from x to w, then wz, then a path from z to y. */ + /* w may equal x, in which case there is no need to call PullFlow(x, w) */ + if (w != x && !IS_BNS_ERROR( ret )) + { + ret = PullFlow( pBNS, SwitchEdge, x, w, delta, bReverse, bChangeFlow ); /* augment between x and w */ + } + if (!IS_BNS_ERROR( ret )) + { + ret = AugmentEdge( pBNS, w, z, iwz, delta, bReverse, bChangeFlow ); + } + /* z may equal y, in which case z is just PrevPt[y] */ + if (z != y && !IS_BNS_ERROR( ret )) + { + ret = PullFlow( pBNS, SwitchEdge, prim( y ), prim( z ), delta, (S_CHAR) ( 1 - bReverse ), bChangeFlow ); /* augment between z and y */ + } + } + + return ret; +} + + +/**************************************************************************** +Before augmenting on the two paths, it is necessary to find delta(P). +This can be done by following the paths and computing the minimum +residual capacity of all edges on P. An edge on both P and P' counts +for only half of its actual residual capacity, since augmentng on P by +delta will simutaneously reduce its capacity on P' by delta. +The path P can only be followed by using the switch-edges, as in PullFlow(...). +FindPathCap( x, y, delta ) is a recursive procedure that finds the residual +capacity on the portion of P between x and y. delta is the minimum capacity +found so far along the path. +****************************************************************************/ + + +/**************************************************************************** +Find the minimum residual capacity of all edges +between x and y in a valid st-path P. +delta is the minimum found so far +the vertices occur in order s,...,x,...,y,...,t along P +the vertices occur in order s,...,y',...,x',...,t along P' +****************************************************************************/ +int FindPathCap( BN_STRUCT* pBNS, Edge *SwitchEdge, Vertex x, Vertex y, int delta ) +{ + + Vertex w, z, iwz; + int cap, delta2; + + /* static int level; + if ( level ++ > 50 ) + { + #ifdef _DEBUG + int stop = 1; + #else + ; + #endif + } + */ + + w = SwitchEdge_Vert1( y ); + z = SwitchEdge_Vert2( y ); /* wz is on the path P */ + iwz = SwitchEdge_IEdge( y ); /* edge index */ + + /* Rescap_mark() detects edges passed 2 times and reduces rescap */ + cap = rescap_mark( pBNS, w, z, iwz ); + + if (IS_BNS_ERROR( cap )) + { + /* level --; */ + return cap; + } + if (cap < delta) + { + delta = cap; + } + /* P consists of a path from x to w, then wz, then a path from z to y */ + if (w != x) + { + delta2 = FindPathCap( pBNS, SwitchEdge, x, w, delta ); + delta = inchi_min( delta2, delta ); + } + if (z != y) + { + delta2 = FindPathCap( pBNS, SwitchEdge, prim( y ), prim( z ), delta ); + delta = inchi_min( delta2, delta ); + } + /* level --; */ + + return delta; +} + + +/* +BT = bond types +*/ + + +#define BT_ALTERN_BOND 1 /* 1-2, possibly stereo */ +#define BT_OTHER_ALTERN_BOND 2 /* 1-3, 2-3, 1-2-3 alternating non-stereo non-taut bonds */ + +#define BT_ALTERN_NS_BOND 4 + +#define BT_TAUTOM_BOND 8 + +#define BT_ALTERN_UNKN_BOND 16 + +#define BT_IGNORE_BOND 0 + +#define BT_NONSTEREO_MASK (BT_TAUTOM_BOND|BT_ALTERN_NS_BOND) + +#define BT_ALT_BOND_MASK (BT_ALTERN_BOND|BT_OTHER_ALTERN_BOND) + +#define BT_NONTAUT_BOND_MASK (BT_ALTERN_BOND|BT_OTHER_ALTERN_BOND|BT_ALTERN_NS_BOND) + +/* BNS members redefinitions for finding non-stereo bonds */ +/* BNS_EDGE */ +#define nBlockNumberAltBns flow /* internal variable of the DFS traversal: mark traversed bonds */ +#define nNumAtInBlockAltBns cap +#define nBondTypeInpAltBns pass /* 0=>cannot be stereo at all, 1=>alt or taut non-stereo, 2=>can be stereo */ +#define nBondNonStereoAltBns cap /* 1=>found to be non-stereogenic although BondTypeInp=2; 0=>as in BondTypeInp */ + +#if ( BNS_MARK_ONLY_BLOCKS == 1 ) /* { */ +/* BNS_VERTEX */ +#define bCutVertexAltBns st_edge.cap0 /* cut-vertex flag */ +#define nRingSystemAltBns st_edge.cap /* ordering number of a ring system */ +#define nNumAtInRingSystemAltBns st_edge.flow0 /* number of vertices in a ring system */ +#define nBlockSystemAltBns st_edge.flow /* result of the DFS traversal: even cirquit must be within one block */ + +#endif /* } */ + +#define valenceAltBns num_adj_edges + + +/****************************************************************************/ +int MarkRingSystemsAltBns( BN_STRUCT* pBNS, int bUnknAltAsNoStereo ) +{ + AT_NUMB *nStackAtom = NULL; + int nTopStackAtom; + AT_NUMB *nRingStack = NULL; + int nTopRingStack; /* was AT_NUMB */ + AT_NUMB *nBondStack = NULL; + int nTopBondStack; + AT_NUMB *nDfsNumber = NULL; + AT_NUMB *nLowNumber = NULL; + S_CHAR *cNeighNumb = NULL; + AT_NUMB nDfs; + AT_NUMB nNumAtInRingSystem; + int i, j, u, w, start, nNumRingSystems; /* djb-rwth: removing redundant variables */ + BNS_VERTEX *at = pBNS->vert; + BNS_EDGE *bond = pBNS->edge; + int num_atoms = pBNS->num_atoms; + int num_edges = pBNS->num_bonds; + + /* Allocate arrays */ + nStackAtom = (AT_NUMB *) inchi_malloc( num_atoms * sizeof( nStackAtom[0] ) ); + nRingStack = (AT_NUMB *) inchi_malloc( num_atoms * sizeof( nRingStack[0] ) ); + nDfsNumber = (AT_NUMB *) inchi_malloc( num_atoms * sizeof( nDfsNumber[0] ) ); + nLowNumber = (AT_NUMB *) inchi_malloc( num_atoms * sizeof( nLowNumber[0] ) ); + nBondStack = num_edges ? ( (AT_NUMB *) inchi_malloc( num_edges * sizeof( nBondStack[0] ) ) ) : (AT_NUMB *) ( NULL ); /* special case: no bonds 2006-03 */ + cNeighNumb = (S_CHAR *) inchi_malloc( num_atoms * sizeof( cNeighNumb[0] ) ); + + /* Check allocation */ + if (!nStackAtom || !nRingStack || !nDfsNumber || !nLowNumber || (!nBondStack && num_edges) || !cNeighNumb + ) /* djb-rwth: addressing LLVM warning */ + { + nNumRingSystems = CT_OUT_OF_RAM; /* program error */ /* */ + goto exit_function; + } + + /******************************************** + * + * Find Cut-vertices & Blocks + * + * 1\ /5 has 3 blocks (maximal subgraphs that + * Example: | >3--4< | are nonseparable by deleting a single vertex): + * 2/ \6 (1,2,3, has 3 bonds), (3,4, has 1 bond), and (4,5,6, has 3 bonds) + * + * Cut-vertices or articulation points are + * intersections of the blocks: points 3 and 4. + ********************************************/ + + /******************************************************** + + RingSystemAlt are atoms connected by alternating bonds + (as must be indicated in bIsAltBond()): + + BOND_ALTERN + BOND_ALT_123 + BOND_ALT_13 + BOND_ALT_23 + + Since other bonds may be present, we possibly need + to restart to move to another component + *********************************************************/ + + nNumRingSystems = 0; + memset( nDfsNumber, 0, num_atoms * sizeof( nDfsNumber[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + + for (start = 0; start < num_atoms; start++) + { + if (nDfsNumber[start]) + { + continue; + } + for (i = 0; i < at[start].valenceAltBns; i++) + { + if (bond[at[start].iedge[i]].nBondTypeInpAltBns & BT_ALTERN_BOND) + goto found_alt; + } + continue; + + found_alt: + + /* Initiation */ + u = start; /* start atom */ + nDfs = 0; + nTopStackAtom = -1; + nTopRingStack = -1; + nTopBondStack = -1; + memset( cNeighNumb, 0, num_atoms * sizeof( cNeighNumb[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ + /* Push the start atom on the stack */ + nLowNumber[u] = nDfsNumber[u] = ++nDfs; + nStackAtom[++nTopStackAtom] = (AT_NUMB) u; + nRingStack[++nTopRingStack] = (AT_NUMB) u; + + /* djb-rwth: removing redundant code */ + + do + { + /* advance */ + /*while ( (int)at[i=nStackAtom[nTopStackAtom]].valenceAltBns > (j = (int)cNeighNumb[i]) )*/ + /* replaced due to missing sequence point */ + while (i = (int) nStackAtom[nTopStackAtom], j = (int) cNeighNumb[i], (int) at[i].valenceAltBns > j) + { + cNeighNumb[i] ++; + if (!( bond[w = at[i].iedge[j]].nBondTypeInpAltBns & BT_ALT_BOND_MASK )) + { + continue; + } + u = (int) ( bond[at[i].iedge[j]].neighbor12 ^ i ); + if (!nDfsNumber[u] && nBondStack) /* djb-rwth: fixing a NULL pointer dereference */ + { + /* tree edge, 1st visit -- advance */ + nStackAtom[++nTopStackAtom] = (AT_NUMB) u; + nRingStack[++nTopRingStack] = (AT_NUMB) u; + nBondStack[++nTopBondStack] = (AT_NUMB) w; + nLowNumber[u] = nDfsNumber[u] = ++nDfs; + /* djb-rwth: removing redundant code */ + } + else + { + if (!nTopStackAtom || u != (int) nStackAtom[nTopStackAtom - 1]) + { /* may comment out ? */ + /* back edge: u is not a predecessor of i */ + if ((nDfsNumber[u] < nDfsNumber[i]) && nBondStack) /* djb-rwth: fixing a NULL pointer dereference */ + { + /* Back edge, 1st visit: u is ancestor of i. Save and compare */ + nBondStack[++nTopBondStack] = (AT_NUMB) w; + if (nLowNumber[i] > nDfsNumber[u]) + { + nLowNumber[i] = nDfsNumber[u]; + } + } + } + } + } + cNeighNumb[i] = 0; + + /* Back up */ + if (i != start) + { + u = (int) nStackAtom[nTopStackAtom - 1]; /* predecessor of i */ + if (nLowNumber[i] >= nDfsNumber[u]) + { + /* Output the block; the block was entered through its first bond u->i */ + nNumRingSystems++; + /*at[u].nBlockSystemAltBns = nNumRingSystems;*/ /* mark the atom */ + nNumAtInRingSystem = 1; + /* + if ( u != start || nNumStartChildren > 1 ) { + at[u].bCutVertexAltBns += 1; // mark cut-vertex (articulation point) + } + */ + while (nTopRingStack >= 0) + { + j = nRingStack[nTopRingStack--]; + /*at[j].nBlockSystemAltBns = nNumRingSystems;*/ /* mark the atom */ + nNumAtInRingSystem++; + if (i == j) + { + break; + } + } + while (nTopBondStack >= 0) + { + w = nBondStack[nTopBondStack--]; + bond[w].nBlockNumberAltBns = nNumRingSystems; /* mark the bond */ + bond[w].nNumAtInBlockAltBns = nNumAtInRingSystem; + if ((i == bond[w].neighbor1 && u == ( i ^ bond[w].neighbor12 )) || + (u == bond[w].neighbor1 && i == ( u ^ bond[w].neighbor12 ))) /* djb-rwth: addressing LLVM warning */ + { + break; + } + } + } + else + { + if (nLowNumber[u] > nLowNumber[i]) + { + /* inherit */ + nLowNumber[u] = nLowNumber[i]; + } + } + } + } while (--nTopStackAtom >= 0); + } + +#if ( BNS_MARK_ONLY_BLOCKS != 1 ) /* { */ + + /******************************************** + * + * Find Ring Systems + * Including chain atoms X: A-X-B, where the bonds (of any kind) are bridges. + * + ********************************************/ + + /* Initiation */ + nNumRingSystems = 0; + for (start = 0; start < num_atoms; start++) + { + if (at[start].nRingSystemAltBns) + { + continue; + } + for (i = 0; i < at[start].valenceAltBns; i++) + { + if (bond[at[start].iedge[i]].nBondTypeInpAltBns & BT_ALT_BOND_MASK) + { + goto found_alt2; + } + } + continue; + + found_alt2: + u = start; /* start atom */ + nDfs = 0; + nTopStackAtom = -1; + nTopRingStack = -1; + memset( nDfsNumber, 0, num_atoms * sizeof( nDfsNumber[0] ) ); + memset( cNeighNumb, 0, num_atoms * sizeof( cNeighNumb[0] ) ); + /* push the start atom on the stack */ + nLowNumber[u] = nDfsNumber[u] = ++nDfs; + nStackAtom[++nTopStackAtom] = (AT_NUMB) u; + nRingStack[++nTopRingStack] = (AT_NUMB) u; + + do + { + /* advance */ + advance_ring: + /*if ( (int)at[i=nStackAtom[nTopStackAtom]].valenceAltBns > (j = (int)cNeighNumb[i]) )*/ + /* replaced due to missing sequence point */ + if (i = (int) nStackAtom[nTopStackAtom], j = (int) cNeighNumb[i], (int) at[i].valenceAltBns > j) + { + cNeighNumb[i] ++; + if (!( bond[at[i].iedge[j]].nBondTypeInpAltBns & BT_ALTERN_BOND )) + { + goto advance_ring; + } + u = (int) ( bond[at[i].iedge[j]].neighbor12 ^ i ); + if (!nDfsNumber[u]) + { + /* tree edge, 1st visit -- advance */ + nStackAtom[++nTopStackAtom] = (AT_NUMB) u; + nRingStack[++nTopRingStack] = (AT_NUMB) u; + nLowNumber[u] = nDfsNumber[u] = ++nDfs; + } + else + { + if (!nTopStackAtom || u != (int) nStackAtom[nTopStackAtom - 1]) + { + /* back edge: u is not a predecessor of i */ + if (nDfsNumber[u] < nDfsNumber[i]) + { + /* Back edge, 1st visit: u is ancestor of i. Compare */ + if (nLowNumber[i] > nDfsNumber[u]) + { + nLowNumber[i] = nDfsNumber[u]; + } + } + } + } + goto advance_ring; + } + else + { + cNeighNumb[i] = 0; + } + + /* Back up */ + if (nDfsNumber[i] == nLowNumber[i]) + { + /* Found a ring system */ + nNumRingSystems++; + + /* Unwind nRingStack[] down to i */ + + /* Count atoms in a ring system */ + for (nNumAtInRingSystem = 0, j = nTopRingStack; 0 <= j; j--) + { + nNumAtInRingSystem++; + if (i == (int) nRingStack[j]) + { + break; + } + } + while (nTopRingStack >= 0) + { + j = (int) nRingStack[nTopRingStack--]; + at[j].nRingSystemAltBns = (AT_NUMB) nNumRingSystems; /* ring system id */ + at[j].nNumAtInRingSystemAltBns = nNumAtInRingSystem; + if (i == j) + { + /* Reached atom on the top of nStackAtom[] stack */ + break; + } + } + } + else + { + if (nTopStackAtom > 0) + { + j = (int) nStackAtom[nTopStackAtom - 1]; + /* inherit nLowNumber */ + if (nLowNumber[j] > nLowNumber[i]) + { + nLowNumber[j] = nLowNumber[i]; + } + } + } + } while (--nTopStackAtom >= 0); + } + +#endif /* } BNS_MARK_ONLY_BLOCKS != 1 */ + +exit_function: + if (nStackAtom) + { + inchi_free( nStackAtom ); + } + if (nRingStack) + { + inchi_free( nRingStack ); + } + if (nDfsNumber) + { + inchi_free( nDfsNumber ); + } + if (nLowNumber) + { + inchi_free( nLowNumber ); + } + if (nBondStack) + { + inchi_free( nBondStack ); + } + if (cNeighNumb) + { + inchi_free( cNeighNumb ); + } + + return nNumRingSystems; +} + + +/****************************************************************************/ +int ReInitBnStructForAltBns( BN_STRUCT *pBNS, + inp_ATOM *at, + int num_atoms, + int bUnknAltAsNoStereo ) +{ + Vertex v, v2; + int ret, bond_type, num_to_test, j; + BNS_EDGE *pBond; + BNS_VERTEX *pAtom; + + /* Strip all t-groups and c-groups */ + num_to_test = 0; + if (bUnknAltAsNoStereo) + { + for (j = 0; j < pBNS->num_edges; j++) + { + pBNS->edge[j].pass = 0; + } + } + + ret = ReInitBnStruct( pBNS, at, num_atoms, 0 ); + + if (ret || pBNS->num_atoms != num_atoms || pBNS->num_vertices != num_atoms || pBNS->num_bonds != pBNS->num_edges) + { + ret = BNS_REINIT_ERR; + goto exit_function; + } + + /* Eliminate bonds and fix st-caps */ + for (v = 0; v < num_atoms; v++) + { + pAtom = pBNS->vert + v; + for (j = 0; j < pAtom->valenceAltBns; j++) + { + pBond = pBNS->edge + pAtom->iedge[j]; + if (pBond->neighbor1 == v) + { + bond_type = ( at[v].bond_type[j] & BOND_TYPE_MASK ); + v2 = pBond->neighbor12 ^ v; + if (at[v].endpoint || at[v2].endpoint) + { + bond_type = 0; /* any bond to an endpoint considered non-stereogenic */ + } +#if ( FIX_EITHER_DB_AS_NONSTEREO == 1 ) + if (bUnknAltAsNoStereo) + { + if (bond_type == BOND_ALTERN && at[v].bond_stereo[j] == STEREO_DBLE_EITHER) + { + bond_type = 0; /* treat unknown (Either) ALT bond as non-stereo */ + } + } +#endif + switch (bond_type) + { + + case BOND_ALTERN: + pBond->nBondTypeInpAltBns = BT_ALTERN_BOND; + num_to_test++; + break; + + case BOND_ALT_123: + case BOND_ALT_13: + case BOND_ALT_23: + pBond->nBondTypeInpAltBns = BT_OTHER_ALTERN_BOND; + break; + + case BOND_TAUTOM: + pBond->nBondTypeInpAltBns = BT_TAUTOM_BOND; + break; + + case BOND_ALT12NS: + pBond->nBondTypeInpAltBns = BT_ALTERN_NS_BOND; + break; + + case 0: + case BOND_SINGLE: + case BOND_DOUBLE: + case BOND_TRIPLE: + pBond->nBondTypeInpAltBns = BT_IGNORE_BOND; + break; + + default: + pBond->nBondTypeInpAltBns = BT_IGNORE_BOND; + break; + } + pBond->nBondNonStereoAltBns = 0; /* djb-rwth: addressing GCC warning -- operations on pBond->cap might be undefined */ + pBond->nBlockNumberAltBns = 0; + pBond->nNumAtInBlockAltBns = 0; + +#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) + pBond->forbidden &= pBNS->edge_forbidden_mask; +#endif + } + } + pAtom->bCutVertexAltBns = + pAtom->nRingSystemAltBns = + pAtom->nNumAtInRingSystemAltBns = + pAtom->nBlockSystemAltBns = 0; + } + + return num_to_test; + +exit_function: + + return ret; +} + + +/****************************************************************************/ +int MarkNonStereoAltBns( BN_STRUCT *pBNS, + inp_ATOM *at, + int num_atoms, + int bUnknAltAsNoStereo ) +{ + int num_bonds = pBNS->num_bonds; + int ret; + int ibond, ib1, ib2; + BNS_EDGE *pBond; + Vertex iat1, iat2; + + ret = 0; + + if (pBNS->num_atoms != num_atoms || pBNS->num_vertices != num_atoms || pBNS->num_bonds != pBNS->num_edges) + { + ret = BNS_REINIT_ERR; + goto exit_function; + } + if (bUnknAltAsNoStereo) + { + for (ibond = 0; ibond < num_bonds; ibond++) + { + pBond = pBNS->edge + ibond; + if (pBond->nBondTypeInpAltBns != BT_ALTERN_BOND && pBond->nBondTypeInpAltBns != BT_IGNORE_BOND) + { + continue; + } + iat1 = pBond->neighbor1; + iat2 = pBond->neighbor12 ^ iat1; + ib1 = pBond->neigh_ord[0]; + ib2 = pBond->neigh_ord[1]; + if ( /* alt bond non-adjacent to a taut. endpoint: */ + ( pBond->nBondTypeInpAltBns == BT_ALTERN_BOND && + pBond->nNumAtInBlockAltBns <= 3 ) /* non-ring bond */ || + /* alt bond adjacent to a taut. endpoint: */ + ( pBond->nBondTypeInpAltBns == BT_IGNORE_BOND && + ( at[iat1].bond_type[ib1] & BOND_TYPE_MASK ) == BOND_ALTERN ) + ) + { + if (( at[iat1].bond_type[ib1] & BOND_TYPE_MASK ) == BOND_ALTERN) + { + /* bond_type = BOND_ALT12NS; */ + at[iat1].bond_stereo[ib1] = + at[iat2].bond_stereo[ib2] = STEREO_DBLE_EITHER; + ret++; + } + } + } + } + else + { + for (ibond = 0; ibond < num_bonds; ibond++) + { + pBond = pBNS->edge + ibond; + if (pBond->nBondTypeInpAltBns != BT_ALTERN_BOND && pBond->nBondTypeInpAltBns != BT_IGNORE_BOND) + { + continue; + } + iat1 = pBond->neighbor1; + iat2 = pBond->neighbor12 ^ iat1; + ib1 = pBond->neigh_ord[0]; + ib2 = pBond->neigh_ord[1]; + if ( /* alt bond non-adjacent to a taut. endpoint: */ + ( pBond->nBondTypeInpAltBns == BT_ALTERN_BOND && + pBond->nNumAtInBlockAltBns <= 3 ) /* non-ring bond */ || + /* alt bond adjacent to a taut. endpoint: */ + ( pBond->nBondTypeInpAltBns == BT_IGNORE_BOND && + ( at[iat1].bond_type[ib1] & BOND_TYPE_MASK ) == BOND_ALTERN ) + ) + { + at[iat1].bond_type[ib1] = + at[iat2].bond_type[ib2] = BOND_ALT12NS; + ret++; + } + } + } + +exit_function: + + return ret; +} + + +#if ( READ_INCHI_STRING == 1 ) +/*****************************************************************************/ +#ifndef RI_ERR_ALLOC +/* from ichirvrs.h */ +#define RI_ERR_ALLOC (-1) +#define RI_ERR_SYNTAX (-2) +#define RI_ERR_PROGR (-3) +#endif + + +/**************************************************************************** +Check if atom bonded to charged atom +****************************************************************************/ +int bHasChargedNeighbor( inp_ATOM *at, int iat ) +{ + int i; + for (i = 0; i < at[iat].valence; i++) + { + if (at[(int) at[iat].neighbor[i]].charge) + { + return 1; + } + } + + return 0; +} + + +/**************************************************************************** +Add or remove protons + +*num_protons_to_add = nToBeRemovedByNormFromRevrs + +nToBeRemovedByNormFromRevrs > 0: less protons should be allowed to be +added by the Normalization of the Reconstructed Structure +nToBeRemovedByNormFromRevrs < 0: prepare more H(+) to be removed by +the InChI Normalization of the Reconstructed Structure + +OrigStruct -> NormOrig + n(orig)*H(+) +RevrStruct -> NormRevr + n(revr)*H(+) +nToBeRemovedByNormFromRevrs = n(orig) - n(revr) [each may be negative] + +n(orig) > n(revr) or nToBeRemovedByNormFromRevrs > 0 means: +----------------------------------------------------------- +- Too many protons were added by the Normalization to the Reconstructed Structure +(a) n(revr) < 0 => protons were added while they should not have been added; +Solution: "neutralize" (-) charged proton acceptors by moving charges to other atoms +on the condition ADP cannot add in another way; +(b) n(orig) > n(revr) => 0 => too few protons were removed +Solution: (the easiest) attach H(+) to =O or -N< or -N= +Solution: move (+) from N or OH to an atom adjacent to (-) charge or to +an atom that is not N. + +n(orig) < n(revr) or nToBeRemovedByNormFromRevrs < 0 means: +----------------------------------------------------------- +- Too few protons were added by the Normalization to the Reconstructed Stucture +(a) n(orig) < 0 => protons were not added while they should have been added; +Solution: move (-) to O by replacing =O with -O(-) +(b) 0 <= n(orig) < n(revr) => too many protons were removed + +Note: it is critically important to takr into account cumbersome Normalization +Total Charge: if it is >= 0 then no H(+) may be removed from -OH or by ADP +However, if N(+) is present then ADP will always try to remove a proton +****************************************************************************/ +int AddRemoveProtonsRestr( inp_ATOM *at, + int num_atoms, + int *num_protons_to_add, + int nNumProtAddedByRestr, + INCHI_MODE bNormalizationFlags, + int num_tg, + int nChargeRevrs, + int nChargeInChI ) +{ + int i, j, ret = 0; + int nAtTypeTotals[ATTOT_ARRAY_LEN]; + int num_prot = *num_protons_to_add; + int type, mask, bSuccess, nTotCharge, nNumSuccess = 0; + int max_j_Aa = -1, max_j_Ar = -1; + + /* for the reference: + + #define FLAG_NORM_CONSIDER_TAUT ( FLAG_PROTON_NPO_SIMPLE_REMOVED | \ + FLAG_PROTON_NP_HARD_REMOVED | \ + FLAG_PROTON_AC_SIMPLE_ADDED | \ + FLAG_PROTON_AC_SIMPLE_REMOVED | \ + FLAG_PROTON_AC_HARD_REMOVED | \ + FLAG_PROTON_AC_HARD_ADDED | \ + FLAG_PROTON_SINGLE_REMOVED | \ + FLAG_PROTON_CHARGE_CANCEL ) + + #define FLAG_FORCE_SALT_TAUT ( FLAG_PROTON_NP_HARD_REMOVED | \ + FLAG_PROTON_AC_HARD_REMOVED | \ + FLAG_PROTON_AC_HARD_ADDED ) + + */ + + /* if ChargeRevrs > nChargeInChI then we should prevent proton addition or facilitate proton removal + a typical case is (=) on N or O instead of C(-) + + if ChargeRevrs < nChargeInChI then we should prevent proton removal or facilitate proton addition + */ + + mark_at_type( at, num_atoms, nAtTypeTotals ); + for (i = nTotCharge = 0; i < num_atoms; i++) + { + nTotCharge += at[i].charge; + } + /* Size for SimpleAddAcidicProtons() */ + for (max_j_Aa = 0; AaTypMask[2 * max_j_Aa]; max_j_Aa++) + { + ; + } + /* Size for SimpleRemoveAcidicProtons */ + for (max_j_Ar = 0; ArTypMask[2 * max_j_Ar]; max_j_Ar++) + { + ; + } + if (num_prot < 0 && nAtTypeTotals[ATTOT_TOT_CHARGE] - nNumProtAddedByRestr <= 0) + { + /* Remove proton(s) */ + /* use test from SimpleAddAcidicProtons() to test whether removal of H(+) from =C-OH, etc. is correct */ + for (i = 0; i < num_atoms && num_prot; i++) + { + /* Choose an atom */ + if (at[i].sb_parity[0] || at[i].p_parity || at[i].charge || + !at[i].num_H || at[i].radical || bHasChargedNeighbor( at, i )) + { + continue; + } + /* try to remove a proton and check whether InChI would add it back */ + at[i].charge--; + at[i].num_H--; + type = GetAtomChargeType( at, i, NULL, &mask, 0 ); + at[i].charge++; + at[i].num_H++; + + if (type) + { + for (bSuccess = 0, j = 0; j < max_j_Aa; j++) + { + if ((bSuccess = ( type & AaTypMask[2 * j] ) && ( mask && AaTypMask[2 * j + 1] ))) /* djb-rwth: addressing LLVM warning */ + { + break; /* the proton may be added to this atom */ + } + } + if (bSuccess) + { + /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 1 ); /* subtract at[i] */ + at[i].charge--; + at[i].num_H--; + type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); /* add changed at[i] */ + num_prot++; /* success */ + nNumSuccess++; + } + } + } + } + + if (num_prot < 0 && num_tg && nAtTypeTotals[ATTOT_TOT_CHARGE] - nNumProtAddedByRestr <= 0) + { + /* Alternative proton removal: O=C-NH => (-)O-C=N, O and N are taut. endpoints */ + int endp2, centp, k, i0, k0; + for (i = 0; i < num_atoms; i++) + { + /* Choose an atom */ + if (!at[i].endpoint || at[i].sb_parity[0] || at[i].p_parity || + at[i].radical || at[i].charge || bHasChargedNeighbor( at, i )) + { + continue; + } + /* Looking for tautomeric =O */ + if (1 != at[i].valence || BOND_TYPE_DOUBLE != at[i].bond_type[0] || at[i].num_H || + 2 != get_endpoint_valence( at[i].el_number )) + { + continue; + } + centp = at[i].neighbor[0]; + if (at[centp].sb_parity[0] || at[centp].p_parity || !is_centerpoint_elem( at[centp].el_number )) + { + continue; + } + /* Found a possible centerpoint, looking for -NH endpoint */ + for (k = 0; k < at[centp].valence; k++) + { + if (at[centp].bond_type[k] != BOND_TYPE_SINGLE) + { + continue; + } + endp2 = at[centp].neighbor[k]; + if (at[endp2].endpoint != at[i].endpoint || + !at[endp2].num_H || at[endp2].charge || + at[endp2].sb_parity[0] || at[endp2].p_parity || + at[endp2].valence != at[endp2].chem_bonds_valence || + 3 != at[endp2].chem_bonds_valence + at[endp2].num_H || + 3 != get_endpoint_valence( at[endp2].el_number )) + { + continue; + } + /* Find bonds in reciprocal ajacency lists */ + for (i0 = 0; i0 < at[centp].valence && i != at[centp].neighbor[i0]; i0++) + { + ; + } + for (k0 = 0; k0 < at[endp2].valence && centp != at[endp2].neighbor[k0]; k0++) + { + ; + } + if (i0 == at[centp].valence || k0 == at[endp2].valence) + { + return RI_ERR_PROGR; + } + /* -NH has been found */ + /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 1 ); /* subtract at[i] */ + type = GetAtomChargeType( at, endp2, nAtTypeTotals, &mask, 1 ); /* subtract at[endp2] */ + + at[i].bond_type[0] --; + at[centp].bond_type[i0] --; + at[i].chem_bonds_valence--; + at[i].charge--; + + at[endp2].bond_type[k0] ++; + at[centp].bond_type[k] ++; + at[endp2].chem_bonds_valence++; + at[endp2].num_H--; + + num_prot++; + nNumSuccess++; + + /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); /* add at[i] */ + type = GetAtomChargeType( at, endp2, nAtTypeTotals, &mask, 0 ); /* add at[endp2] */ + } + } + } + + if (num_prot > 0) + { + /* Add protons */ + /* 1. Use test from SimpleRemoveAcidicProtons() to test whether addition of H(+) to =C-O(-), etc. is correct */ + for (i = 0; i < num_atoms && num_prot && nAtTypeTotals[ATTOT_TOT_CHARGE] - nNumProtAddedByRestr >= 0; i++) + { + /* Choose an atom */ + if (at[i].sb_parity[0] || at[i].p_parity || at[i].num_H || + at[i].charge != -1 || at[i].radical || bHasChargedNeighbor( at, i )) + { + continue; + } + /* Try to add a proton and check whether InChI would remove it back */ + at[i].charge++; + at[i].num_H++; + type = GetAtomChargeType( at, i, NULL, &mask, 0 ); + at[i].charge--; + at[i].num_H--; + if (type) + { + for (bSuccess = 0, j = 0; j < max_j_Ar; j++) + { + if ((bSuccess = ( type & ArTypMask[2 * j] ) && ( mask && ArTypMask[2 * j + 1] ))) /* djb-rwth: addressing LLVM warning */ + { + break; + } + } + if (bSuccess) + { + /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 1 ); /* subtract at[i] */ + at[i].charge++; + at[i].num_H++; + type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); /* add changed at[i] */ + num_prot--; /* success */ + nNumSuccess++; + } + } + } + /* 2. Use test from SimpleRemoveHplusNPO() */ + for (i = 0; i < num_atoms && num_prot; i++) + { + /* Choose an atom */ + if (at[i].sb_parity[0] || at[i].p_parity || + at[i].charge || at[i].radical || bHasChargedNeighbor( at, i )) + { + continue; + } + /* Try to add a proton and check whether InChI would remove it back */ + at[i].num_H++; + at[i].charge++; + bSuccess = ( PR_SIMPLE_TYP & ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) ) ) && + ( PR_SIMPLE_MSK & mask ); /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + at[i].num_H--; /* failed */ + at[i].charge--; + if (bSuccess) + { + /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 1 ); /* subtract at[i] */ + at[i].num_H++; + at[i].charge++; + type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); /* add changed at[i] */ + num_prot--; /* succeeded */ + nNumSuccess++; + } + } + } + + if (num_prot < 0 && ( bNormalizationFlags & FLAG_PROTON_AC_HARD_ADDED ) && 1 == num_tg && + nAtTypeTotals[ATTOT_TOT_CHARGE] - nNumProtAddedByRestr <= 0) + { + /* Try to remove protons from tautomeric N (specific ADP must be present) */ + int nNumAcceptors_DB_O = 0, nNumDonors_SB_NH = 0, num_max, num_success; + for (i = 0; i < num_atoms; i++) + { + /* Choose an atom */ + if (!at[i].endpoint || at[i].radical || + at[i].sb_parity[0] || at[i].p_parity || bHasChargedNeighbor( at, i )) + { + continue; + } + type = GetAtomChargeType( at, i, NULL, &mask, 0 ); + if (( type & AA_HARD_TYP_CO ) && ( mask & AA_HARD_MSK_CO )) + { + nNumAcceptors_DB_O++; + } + else + { + if (( type == ATT_ATOM_N ) && ( mask == ATBIT_NP_H ) && !at[i].charge && + at[i].valence == at[i].chem_bonds_valence) + { + nNumDonors_SB_NH++; + } + } + } + num_max = inchi_min( nNumAcceptors_DB_O, nNumDonors_SB_NH ); + for (i = 0, num_success = 0; i < num_atoms && num_success < num_max && num_prot < 0; i++) + { + /* Choose an atom */ + if (!at[i].endpoint || at[i].radical || at[i].sb_parity[0] || + at[i].p_parity || bHasChargedNeighbor( at, i )) + { + continue; + } + type = GetAtomChargeType( at, i, NULL, &mask, 0 ); + if (( type == ATT_ATOM_N ) && ( mask == ATBIT_NP_H ) && !at[i].charge && + at[i].valence == at[i].chem_bonds_valence) + { + /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 1 ); /* subtract at[i] */ + at[i].num_H--; + at[i].charge--; + type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); /* add changed at[i] */ + num_prot++; + num_success++; + nNumSuccess++; + } + } + } + + /*exit_function:*/ + + *num_protons_to_add = num_prot; + + return ret < 0 ? ret : nNumSuccess; +} + + +/**************************************************************************** +Add or remove isotopic protons +****************************************************************************/ +int AddRemoveIsoProtonsRestr( inp_ATOM *at, + int num_atoms, + NUM_H num_protons_to_add[], + int num_tg ) +{ + int i, j, k, n, ret = 0; + int nNumSuccess = 0, min_at, max_at, num_H, num_iso_H, num_expl_H, num_expl_iso_H; /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ + int iCurIso; /* 0=> 1H, 1=> D, 2=> T */ + int iCurMode, iCurMode1, iCurMode2; /* 0=> Not Endpoints, 1=> Endpoints */ + + /* Distribute isotopes from heaviest to lightest; pick up atoms in order 1. Not endpoints; 2. Endpoints */ + iCurMode1 = 0; + iCurMode2 = num_tg ? 1 : 0; + for (iCurMode = iCurMode1; iCurMode <= iCurMode2; iCurMode++) + { + for (iCurIso = 2; 0 <= iCurIso; iCurIso--) + { + /* check for isotopic H to add */ + if (!num_protons_to_add[iCurIso]) + { + continue; + } + if (0 > num_protons_to_add[iCurIso]) + { + ret = RI_ERR_PROGR; + goto exit_function; + } + + /* Limits for atom scanning */ + min_at = 0; + max_at = num_atoms; + + /* Cycle withio the limits */ + for (i = min_at; i < max_at && 0 < num_protons_to_add[iCurIso]; i++) + { + /* Pick an atom */ + if (iCurMode) + { + if (at[i].endpoint) + { + j = i; /* atom number */ + } + else + { + continue; + } + } + else + { + if (!at[i].endpoint && 1 == bHeteroAtomMayHaveXchgIsoH( at, i )) + { /* atom number */ + j = i; + } + else + { + if (at[i].el_number == EL_NUMBER_H && at[i].charge == 1 && + !at[i].valence && !at[i].radical && !at[i].iso_atw_diff) + { + /* proton, not isotopic; make it isotopic */ + at[i].iso_atw_diff = 1 + iCurIso; + num_protons_to_add[iCurIso] --; + nNumSuccess++; + continue; + } + else + { + continue; + } + } + } + + /* j is the atom number */ + /* count implicit H */ + num_H = at[j].num_H; + num_iso_H = NUM_ISO_H(at, j); /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ + + while (num_H > 0 && num_protons_to_add[iCurIso] > 0) + { + /* Substitute one implicit H with an isotopic atom H */ + at[j].num_iso_H[iCurIso] ++; + at[j].num_H--; + num_protons_to_add[iCurIso] --; + num_H--; + num_iso_H++; + nNumSuccess++; + } + /* Count explicit H */ + num_expl_H = num_expl_iso_H = 0; + for (k = 0; k < at[j].valence && num_atoms <= ( n = at[j].neighbor[k] ); k++) + { + num_expl_H += ( 0 == at[n].iso_atw_diff ); + num_expl_iso_H += ( 0 != at[n].iso_atw_diff ); + } + while (num_expl_H > 0 && num_protons_to_add[iCurIso] > 0) + { + /* Substitute one explicit H with an isotopic atom H */ + n = at[j].neighbor[num_expl_H]; + if (at[n].iso_atw_diff) + { + ret = RI_ERR_PROGR; + goto exit_function; + } + at[n].iso_atw_diff = 1 + iCurIso; + num_expl_H--; + num_expl_iso_H++; + num_protons_to_add[iCurIso] --; + nNumSuccess++; + } + } + } + } + +exit_function: + + return ret < 0 ? ret : nNumSuccess; +} + +#endif diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichi_io.c b/INCHI-1-SRC/INCHI_BASE/src/ichi_io.c index 0575eace..4c14a938 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichi_io.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichi_io.c @@ -1335,7 +1335,7 @@ char* inchi_sgets(char* s, int n, INCHI_IOSTREAM* ios) if (NULL == inp) { /* like EOF */ - return NULL; + return NULL; /* djb-rwth: addressing coverity ID #499480 -- inp can be NULL */ } p = s; diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichicano.c b/INCHI-1-SRC/INCHI_BASE/src/ichicano.c index d92deb84..1ce91329 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichicano.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichicano.c @@ -2693,7 +2693,7 @@ VII. Optimize isotopic stereo descriptors (optimized) } } - inchi_free(pRankStack2); /* djb-rwth: fixing coverity CID #499631 */ + inchi_free(pRankStack2); /* djb-rwth: fixing coverity ID #499631 */ pCS->NeighList = NULL; /* keep the pointer in pBCN->ftcn[bTaut].NeighList for further deallocation */ qfree( nAtomNumber ); diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichimak2.c b/INCHI-1-SRC/INCHI_BASE/src/ichimak2.c index ee44c271..1fe90e85 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichimak2.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichimak2.c @@ -330,7 +330,7 @@ int MakeHillFormula( U_CHAR *nAtom, mult = 0; bOvfl = 0; nPrevAtom = (U_CHAR) -2; /* non-existent number */ - memset(szElement, '\0', sizeof(szElement)); /* djb-rwth: fixing coverity CID #499542 */ + memset(szElement, '\0', sizeof(szElement)); /* djb-rwth: fixing coverity ID #499542 */ if (num_C) { diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichimake.c b/INCHI-1-SRC/INCHI_BASE/src/ichimake.c index 80652e13..f4df89bc 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichimake.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichimake.c @@ -124,7 +124,7 @@ int inp2spATOM(inp_ATOM* inp_at, int num_inp_at, sp_ATOM* at) for (i = 0; i < num_inp_at; i++) { - elname_len = sizeof(at[0].elname) - 1; /* djb-rwth: fixing coverity CID #499609 */ + elname_len = sizeof(at[0].elname) - 1; /* djb-rwth: fixing coverity ID #499609 */ strncpy(at[i].elname, inp_at[i].elname, elname_len); at[i].elname[elname_len] = '\0'; at[i].el_number = (U_CHAR)get_periodic_table_number(at[i].elname); @@ -451,7 +451,7 @@ int CompINChITautVsNonTaut(const INCHI_SORT* p1, /* non-tautomeric "fixed H" specific */ - if ( /*TAUT_NON == bTaut &&*/ (i2 && i2->nNum_H_fixed)) + if ( /*TAUT_NON == bTaut && (i2 &&*/ i2->nNum_H_fixed) /* djb-rwth: fixing coverity ID #499493 */ { /* first, compare non-tautomeric chem. formulas -- they may be different */ /* secondly, compare fixed-H distribution */ @@ -2432,7 +2432,7 @@ AT_NUMB* GetDfsOrder4CT(CANON_GLOBALS* pCG, nOutputString[k + 2] = cDelim; } - if ((i >= 0) && (i < num_atoms)) /* djb-rwth: fixing coverity CID #499483 */ + if ((i >= 0) && (i < num_atoms)) /* djb-rwth: fixing coverity ID #499483 */ { cNeighNumb[i] = 0; } @@ -4048,7 +4048,7 @@ int Create_INChI(CANON_GLOBALS* pCG, { num_at_tg = num_taut_at + t_group_info->num_t_groups; /* ??? -not true- create t_group_info_orig for multiple calls with atom renumbering */ - make_a_copy_of_t_group_info(t_group_info_orig /* dest*/, t_group_info /* source*/); + make_a_copy_of_t_group_info(t_group_info_orig /* dest*/, t_group_info /* source*/); /* djb-rwth: addressing coverity ID #499544 -- properly used sequence of arguments according to the comment in previous line */ /* mark isotopic tautomer groups: calculate t_group->iWeight */ s[TAUT_YES].nLenLinearCTIsotopicTautomer = set_tautomer_iso_sort_keys(t_group_info); if (s[TAUT_YES].nLenLinearCTIsotopicTautomer < 0) diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichimap2.c b/INCHI-1-SRC/INCHI_BASE/src/ichimap2.c index 7405f2f9..86ed65d5 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichimap2.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichimap2.c @@ -1075,7 +1075,7 @@ int parity_of_mapped_half_bond( int from_at, } if (j != 2) { - return 0; /* program error: j can be only 0, 1, or 2 */ /* */ + return 0; /* program error: j can be only 0, 1, or 2 */ /* */ /* djb-rwth: addressing coverity ID #499526 -- refer to the first comment in this line */ } if (r_to[0] == r_to[1]) diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichimap4.c b/INCHI-1-SRC/INCHI_BASE/src/ichimap4.c index 6d6fc1f3..daf94bb0 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichimap4.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichimap4.c @@ -958,10 +958,7 @@ int map_stereo_bonds4( struct tagINCHI_CLOCK *ic, } if (RETURNED_ERROR( ret2 )) { - if (ret2 == CT_TIMEOUT_ERR) - return ret2; - else - return ret2; /* program error */ + return ret2; /* program error */ /* djb-rwth: fixing coverity ID #499569 */ } if (ret2 > 0) { @@ -1547,14 +1544,7 @@ int map_stereo_atoms4( struct tagINCHI_CLOCK *ic, if (RETURNED_ERROR( ret )) { - if (ret == CT_TIMEOUT_ERR) - { - return ret; - } - else - { - return ret; /* program error */ - } + return ret; /* program error */ /* djb-rwth: fixing coverity ID #499567 */ } if (ret > 0) diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichinorm.c b/INCHI-1-SRC/INCHI_BASE/src/ichinorm.c index 8cca74ef..4f9229bf 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichinorm.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichinorm.c @@ -3251,7 +3251,7 @@ int add_to_da( DERIV_AT *da, DERIV_AT *add ) { numDaHiPri += ( 0 != ( da->typ[len_da] & DERIV_UNEXPADABLE ) ); } - for (len_add = 0, numAddHiPri = 0; len_add < DERIV_AT_LEN && da->typ[len_add]; len_add++) + for (len_add = 0, numAddHiPri = 0; len_add < DERIV_AT_LEN && da->typ[len_add]; len_add++) /* djb-rwth: addressing coverity ID #499516 -- definitely not a copy-paste error */ { numAddHiPri += ( 0 != ( add->typ[len_add] & DERIV_UNEXPADABLE ) ); } @@ -3342,7 +3342,7 @@ int mark_atoms_deriv( inp_ATOM *at, DERIV_AT da2; /* moved from below 2024-09-01 DT */ da1.other_atom = 0; /* djb-rwth: initialisation needed for if conditons */ #if( defined(DERIV_RING_DMOX_DEOX_N) && defined(DERIV_RING_DMOX_DEOX_O) ) - /* djb-rwth: initialisation needed to avoid garbage values in add_to_da function call; fixing coverity CID #499492 */ + /* djb-rwth: initialisation needed to avoid garbage values in add_to_da function call; fixing coverity ID #499492 */ memset(da2.typ, 0, DERIV_AT_LEN * sizeof(da2.typ[0])); memset(da2.ord, '\0', DERIV_AT_LEN * sizeof(da2.ord[0])); memset(da2.num, '\0', DERIV_AT_LEN * sizeof(da2.num[0])); @@ -4773,6 +4773,7 @@ int is_deriv_chain2( inp_ATOM *at, n2 == 2 ? "C2F5" : n2 == 3 ? "C3F7" : "C?F?", 0 ); + /* djb-rwth: addressing coverity ID #499506 -- condition is correct for n1 != 1 */ underiv_list_add( szUnderiv2, lenUnderiv2, pszDerivName[ #if defined(UNDERIV_RN_AcMe) || defined(UNDERIV_RNH_AcMe) n1 == 1 ? DERIV_ID_Acetate : @@ -4934,7 +4935,7 @@ int is_deriv_chain2( inp_ATOM *at, if (num == 4 || num == 5) { underiv_list_add( szUnderiv, lenUnderiv, num == 4 ? "Pyrrolidide" : num == 5 ? "Piperidine" : "???", ' ' ); - underiv_list_add( szUnderiv2, lenUnderiv2, pszDerivName[num == 4 ? DERIV_ID_Pyrrolidide : num == 5 ? DERIV_ID_Piperidine : DERIV_ID_Unknown], ' ' ); + underiv_list_add( szUnderiv2, lenUnderiv2, pszDerivName[num == 4 ? DERIV_ID_Pyrrolidide : num == 5 ? DERIV_ID_Piperidine : DERIV_ID_Unknown], ' ' ); /* djb-rwth: addressing coverity ID #499491 -- working correctly for num == 5 */ *bitUnderiv |= num == 4 ? DERIV_BIT_Pyrrolidide : num == 5 ? DERIV_BIT_Piperidine : DERIV_BIT_Unknown; } else diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichiparm.c b/INCHI-1-SRC/INCHI_BASE/src/ichiparm.c index ffc6e1a9..bfa14414 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichiparm.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichiparm.c @@ -1344,7 +1344,7 @@ int ReadCommandLineParms(int argc, timeout_value = strtol(pArg + 2, (char**)&q, 10); if (timeout_value && q > pArg + 2 && *q == '\0') { - if (errno == ERANGE || timeout_value < 0.0 || timeout_value>LONG_MAX) + if (errno == ERANGE || timeout_value < 0.0 || timeout_value>LONG_MAX) /* djb-rwth: addressing coverity ID #499550 -- the condition takes into account all possible overflows/errors */ { timeout_value = 0; timeout_set_warning = 1; diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichiprt1.c b/INCHI-1-SRC/INCHI_BASE/src/ichiprt1.c index 38f7debe..331541be 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichiprt1.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichiprt1.c @@ -2112,7 +2112,7 @@ char *szGetTag( const INCHI_TAG *Tag, dstsz = max_3(stl1, stl2, 5); strcpy_s( szTag, dstsz, nTag == 1 ? Tag[j].szXmlLabel : nTag == 2 ? Tag[j].szPlainLabel : "???" ); /* djb-rwth: function replaced with its safe C11 variant */ #else - strcpy(szTag, nTag == 1 ? Tag[j].szXmlLabel : nTag == 2 ? Tag[j].szPlainLabel : "???"); + strcpy(szTag, nTag == 1 ? Tag[j].szXmlLabel : nTag == 2 ? Tag[j].szPlainLabel : "???"); /* djb-rwth: addressing coverity ID #499488 -- when nTag == 2, the "???" is avoided, which is correct */ #endif if (nTag != 2) { @@ -2315,7 +2315,7 @@ int CleanOrigCoord( MOL_COORD szCoord, int delim ) szBuf[len_buf++] = delim; #pragma warning (pop) } - if (len_buf >= (int)sizeof(MOL_COORD)) /* djb-rwth: fixing coverity CID #499520 */ + if (len_buf >= (int)sizeof(MOL_COORD)) /* djb-rwth: fixing coverity ID #499520 */ { len_buf = (int)sizeof(MOL_COORD) - 1; len = 0; @@ -4045,7 +4045,7 @@ static int OutputINCHI_PolymerLayer( CANON_GLOBALS *pCG, { /* For each unit u ... */ u = units2[unum[i]]; - + /* djb-rwth: addressing coverity ID #499574 -- all NULL checks already done above */ err = OutputINCHI_PolymerLayer_SingleUnit(u, io->bPolymers, pOrigStruct->polymer->n_pzz, diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichiprt2.c b/INCHI-1-SRC/INCHI_BASE/src/ichiprt2.c index 51ce948c..d9c37b6a 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichiprt2.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichiprt2.c @@ -96,7 +96,7 @@ int Eql_INChI_Stereo( INChI_Stereo *s1, else { if (( eql1 == EQL_SP3 || ( inv1 = ( eql1 == EQL_SP3_INV ) ) ) && - ( len = s1->nNumberOfStereoCenters ) > ( bRelRac ? 1 : 0 )) + ( len = s1->nNumberOfStereoCenters ) > ( bRelRac ? 1 : 0 )) /* djb-rwth: addressing coverity ID #499484 -- bRelRac does not have to be 0 */ { S_CHAR *t_parity1, *t_parity2; @@ -1367,12 +1367,12 @@ int MakeCRVString( ORIG_INFO *OrigInfo, { if (!OrigInfo[k].cCharge) { - if (len >= 2047) /* djb-rwth: fixing coverity CID #499515 */ + if (len >= 2047) /* djb-rwth: fixing coverity ID #499515 */ { len = 2047; goto early_break; } - else if (len < 0) /* djb-rwth: fixing coverity CID #500400 */ + else if (len < 0) /* djb-rwth: fixing coverity ID #500400 */ { len = 0; goto early_break; @@ -1383,12 +1383,12 @@ int MakeCRVString( ORIG_INFO *OrigInfo, len++; } } - if (len >= 2047) /* djb-rwth: fixing coverity CID #499515 */ + if (len >= 2047) /* djb-rwth: fixing coverity ID #499515 */ { len = 2047; goto early_break; } - else if (len < 0) /* djb-rwth: fixing coverity CID #500382 */ + else if (len < 0) /* djb-rwth: fixing coverity ID #500382 */ { len = 0; goto early_break; @@ -1398,7 +1398,7 @@ int MakeCRVString( ORIG_INFO *OrigInfo, switch (OrigInfo[k].cRadical) { case 1: - /* djb-rwth: fixing coverity CID #499515 -- false positive, len tested for overflow */ + /* djb-rwth: fixing coverity ID #499515 -- false positive, len tested for overflow */ szValue[len] = 'd'; len++; break; @@ -1418,12 +1418,12 @@ int MakeCRVString( ORIG_INFO *OrigInfo, { if (OrigInfo[k].cCharge && !OrigInfo[k].cRadical) { - if (len >= 2047) /* djb-rwth: fixing coverity CID #499515 */ + if (len >= 2047) /* djb-rwth: fixing coverity ID #499515 */ { len = 2047; goto early_break; } - else if (len < 0) /* djb-rwth: fixing coverity CID #500382 */ + else if (len < 0) /* djb-rwth: fixing coverity ID #500382 */ { len = 0; goto early_break; @@ -1465,12 +1465,12 @@ int MakeCRVString( ORIG_INFO *OrigInfo, /* radical */ if (OrigInfo[k].cRadical) { - if (len >= 2047) /* djb-rwth: fixing coverity CID #499515 */ + if (len >= 2047) /* djb-rwth: fixing coverity ID #499515 */ { len = 2047; goto early_break; } - else if (len < 0) /* djb-rwth: fixing coverity CID #500382 */ + else if (len < 0) /* djb-rwth: fixing coverity ID #500382 */ { len = 0; goto early_break; @@ -1499,12 +1499,12 @@ int MakeCRVString( ORIG_INFO *OrigInfo, { if (!OrigInfo[k].cRadical) { - if (len >= 2047) /* djb-rwth: fixing coverity CID #499515 */ + if (len >= 2047) /* djb-rwth: fixing coverity ID #499515 */ { len = 2047; goto early_break; } - else if (len < 0) /* djb-rwth: fixing coverity CID #500382 */ + else if (len < 0) /* djb-rwth: fixing coverity ID #500382 */ { len = 0; goto early_break; diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichiread.c b/INCHI-1-SRC/INCHI_BASE/src/ichiread.c index c3a6a0cf..96c748cc 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichiread.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichiread.c @@ -2965,7 +2965,7 @@ int InChILine2Data(INCHI_IOSTREAM* pInp, /* create two zero/NULL-initialized isotopic stereo if they do not exist */ if ((!pInChI->StereoIsotopic && 0 > (ret2 = CopySegment(pInChI, pAltInChI, CPY_SP3_M, 1, -1))) /* -- the following will be created later, in TAUT_YES part of the code -- */ - || (!pAltInChI->StereoIsotopic && 0 > (ret2 = CopySegment(pAltInChI, pAltInChI, CPY_SP3_M, 1, -1)))) /* djb-rwth: addressing LLVM warnings */ + || (!pAltInChI->StereoIsotopic && 0 > (ret2 = CopySegment(pAltInChI, pAltInChI, CPY_SP3_M, 1, -1)))) /* djb-rwth: addressing LLVM warnings */ /* djb-rwth: addressing coverity ID #499533 -- ui_rr */ { goto exit_function; } @@ -4036,7 +4036,7 @@ int ParseAuxSegmentNumbers(const char* str, /* AuxInfo string { for (k = 0; k < val; k++) { - CopyAtomNumbers(pInChI + k, bIso, pInChI_From + k, bIso_From); + CopyAtomNumbers(pInChI + k, bIso, pInChI_From + k, bIso_From); /* djb-rwth: addressing coverity ID #499525 -- return values handled properly */ } } mpy_component = val; @@ -4987,7 +4987,14 @@ int ReadInChICoord(INCHI_IOSTREAM* pInp, } } while (c >= 0); - ret = AddAuxSegmentCoord(ret, pXYZ, nLenXYZ, pInpInChI, nNumComponents); + if (pXYZ) /* djb-rwth: fixing coverity ID #499576 */ + { + ret = AddAuxSegmentCoord(ret, pXYZ, nLenXYZ, pInpInChI, nNumComponents); + } + else + { + ret = RI_ERR_ALLOC; + } exit_error: if (pXYZ) @@ -5805,7 +5812,7 @@ int ParseSegmentIsoAtoms(const char* str, { int i, mpy_component, val; int nNumComponents, iComponent, len = 0, iAtom; - AT_NUMB nAtom1; + int nAtom1; /* djb-rwth: fixing coverity ID #499573 */ const char* p, * q, * t, * pStart, * pEnd, * r; int ret = 0; INChI* pInChI = pInpInChI[bMobileH]; @@ -6433,7 +6440,7 @@ int ParseSegmentSp3m(const char* str, } } } - if (bMobileHFrom < 0 || bIsoFrom < 0) + if (bMobileHFrom < 0 || bIsoFrom < 0) /* djb-rwth: addressing coverity ID #499556 -- check necessary due to initialisation values */ { return RI_ERR_PROGR; } @@ -8234,7 +8241,7 @@ int ParseSegmentMobileH(const char* str, int num_H_component, num_H_formula, num_taut_H_component, num_H_InChI, ret2; int nNumComponents, iComponent, lenTautomer, tg_pos_Tautomer, iTGroup; /* djb-rwth: removing redundant variables */ const char* p, * q, * h, * t, * p1, * pTaut, * pStart, * pEnd; - AT_NUMB curAtom, nxtAtom; + int curAtom, nxtAtom; /* djb-rwth: fixing coverity ID #499563 */ int state, ret, nAltMobileH = ALT_TAUT(bMobileH); /* djb-rwth: removing redundant variables */ INChI* pInChI = pInpInChI[bMobileH]; INChI* pAltInChI = pInpInChI[nAltMobileH]; @@ -8913,7 +8920,7 @@ int ParseSegmentMobileH(const char* str, pInChI[iComponent].nTautomer[tg_pos_Tautomer + 2] = num_Minus; lenTautomer = tg_pos_Tautomer + 3; /* first atom number position */ /* djb-rwth: fixing GH issue #59.1 */ - if (num_H >= INT_MIN && num_H <= INT_MAX) + if (num_H >= INT_MIN && num_H <= INT_MAX) /* djb-rwth: addressing coverity ID #499582 -- boundary check is required */ { num_taut_H_component += num_H; } @@ -10662,7 +10669,7 @@ int AddInChIChar(INCHI_IOSTREAM* pInp, INCHI_HEAPCHK - return c; + return c; /* djb-rwth: addressing coverity ID #499500 -- c = getInChIChar(pInp) cannot be tainted */ } /****************************************************************************/ @@ -10790,6 +10797,7 @@ void PrepareSaveOptBits(INPUT_PARMS* ip, else { /* Analyze existing and prepare new SaveOpt appendix */ + /* djb-rwth: addressing coverity ID #499490 -- these are variable initialisers setting values to 0 */ int input_save_opt_has_recmet = input_save_opt_bits & SAVE_OPT_RECMET; int input_save_opt_has_fixedh = input_save_opt_bits & SAVE_OPT_FIXEDH; int input_save_opt_has_suu = input_save_opt_bits & SAVE_OPT_SUU; @@ -11671,6 +11679,10 @@ int DetectAndExposePolymerInternals(INCHI_IOSTREAM* is) /* Check formula */ p = strchr(p, '/'); + if (!p) /* djb-rwth: fixing coverity ID #499505 */ + { + goto endf; + } p++; pend = strchr(p, '/'); ntimes = 1; @@ -12302,7 +12314,7 @@ static int SegmentSp3ProcessAbbreviation(int* mpy_component, if (*q == 'e') { /* copy from mobile H to isotopic mobile H */ - pInChIFrom = pInChI; + pInChIFrom = pInChI; /* djb-rwth: addressing coverity ID #499498 -- definitely not a copy-paste error */ bIsoTo = 1; bIsoFrom = -1; /* empty */ } diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichirvr4.c b/INCHI-1-SRC/INCHI_BASE/src/ichirvr4.c index 5aff1c20..52066c5c 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichirvr4.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichirvr4.c @@ -2304,7 +2304,7 @@ int MakeSingleBondsMetal2ChargedHeteroat(BN_STRUCT* pBNS, if (nNumEdgesToFix != cur_num_edges) { ret = RI_ERR_PROGR; - goto pre_exit_function; /* djb-rwth: fixing coverity CID #499637 */ + goto pre_exit_function; /* djb-rwth: fixing coverity ID #499637 */ } /* change edge flow, fix the edges, and run BNS */ for (i = 0; i < nNumEdgesToFix; i++) @@ -2324,7 +2324,7 @@ int MakeSingleBondsMetal2ChargedHeteroat(BN_STRUCT* pBNS, (*pnNumRunBNS)++; if (ret < 0) { - goto pre_exit_function; /* djb-rwth: fixing coverity CID #499637 */ + goto pre_exit_function; /* djb-rwth: fixing coverity ID #499637 */ } else { @@ -2343,7 +2343,7 @@ int MakeSingleBondsMetal2ChargedHeteroat(BN_STRUCT* pBNS, (*pnNumRunBNS)++; if (ret < 0) { - goto pre_exit_function; /* djb-rwth: fixing coverity CID #499637 */ + goto pre_exit_function; /* djb-rwth: fixing coverity ID #499637 */ } else { diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichirvr6.c b/INCHI-1-SRC/INCHI_BASE/src/ichirvr6.c index fdbb368f..7ee136ee 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichirvr6.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichirvr6.c @@ -204,7 +204,7 @@ int FixRestoredStructureStereo( struct tagCANON_GLOBALS *pCG, if (( pe->forbidden & forbidden_stereo_edge_mask ) && ( ret = AddToEdgeList( &FixedStereoEdges, e, INC_ADD_EDGE ) )) /* djb-rwth: ignoring LLVM warning as there should be no memory leak */ { - /* djb-rwth: fixing coverity CID #499482 */ + /* djb-rwth: fixing coverity ID #499482 */ goto exit_function; } } diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichirvr7.c b/INCHI-1-SRC/INCHI_BASE/src/ichirvr7.c index e5207c63..49954c47 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichirvr7.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichirvr7.c @@ -509,7 +509,7 @@ int MergeStructureComponents(ICHICONST INPUT_PARMS* ip, pStruct1 = pStruct[iInchiRec][iMobileH][k].num_atoms ? pStruct[iInchiRec][iMobileH] + k : iAlternH >= 0 && pStruct[iInchiRec][iAlternH][k].num_atoms ? pStruct[iInchiRec][iAlternH] + k : NULL; - if ((len = nAtomOffs[k + 1] - nAtomOffs[k]) && pStruct1) /* djb-rwth: addressing LLVM warning; fixing coverity CID #499555 */ + if ((len = nAtomOffs[k + 1] - nAtomOffs[k]) && pStruct1) /* djb-rwth: addressing LLVM warning; fixing coverity ID #499555 */ { memcpy(at + nAtomOffs[k], pStruct1->at2, len * sizeof(at[0])); if ((len2 = nDelHOffs[k + 1] - nDelHOffs[k])) /* djb-rwth: addressing LLVM warning */ @@ -548,7 +548,7 @@ int MergeStructureComponents(ICHICONST INPUT_PARMS* ip, a->nBlockSystem = 0; a->nNumAtInRingSystem = 0; a->nRingSystem = 0; - /* djb-rwth: addressing coverity CID #499524 -- initialisation with at */ + /* djb-rwth: addressing coverity ID #499524 -- initialisation with at */ for (j = 0; j < a->valence; j++) { @@ -2249,7 +2249,7 @@ int CompareOneOrigInchiToRevInChI(StrFromINChI* pStruct, int ret, err = 0; INCHI_MODE cmp; - if (pStruct) /* djb-rwth: fixing coverity CID #499601 */ + if (pStruct) /* djb-rwth: fixing coverity ID #499601 */ { ret = pStruct->RevInChI.nRetVal; } diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichisort.c b/INCHI-1-SRC/INCHI_BASE/src/ichisort.c index e54d01e4..6b875356 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichisort.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichisort.c @@ -925,13 +925,13 @@ NEIGH_LIST *CreateNeighList( int num_atoms, } else { - inchi_free(pAtList); /* djb-rwth: fixing coverity CID #499598 */ + inchi_free(pAtList); /* djb-rwth: fixing coverity ID #499598 */ inchi_free( pp ); return NULL; } } /* djb-rwth: ignoring LLVM warning */ - /* djb-rwth: fixing coverity CID #499598 -- pp uses pAtList values */ + /* djb-rwth: fixing coverity ID #499598 -- pp uses pAtList values */ return pp; /* djb-rwth: ignoring LLVM warning: since a pointer is returned, memory should be freed in a function which calls *CreateNeighList */ } diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichister.c b/INCHI-1-SRC/INCHI_BASE/src/ichister.c index 01fb37ee..971eb025 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichister.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichister.c @@ -1015,7 +1015,7 @@ double triple_prod_and_min_abs_sine2( double at_coord[][3], ? ( max_edge_len_NoExplNeigh < MAX_EDGE_RATIO * min_edge_len_NoExplNeigh ) : ( max_edge_len < MAX_EDGE_RATIO * min_edge_len ); - if (sine_value > vMinSine && ( min_sine || bAmbiguous )) + if (sine_value > vMinSine && ( min_sine || bAmbiguous )) /* djb-rwth: fixing coverity ID #499548 -- ui_rr */ { if (min_sine) { @@ -1737,8 +1737,8 @@ int GetHalfStereobond0DParity( inp_ATOM *at, { icur2nxt = icur2neigh = -1; /* ordering number of neighbors in nSbNeighOrigAtNumb[] */ cur_parity = 0; /* parity for mth stereobond incident to the cur_at */ + nxt_at = at[cur_at].neighbor[(int)at[cur_at].sb_ord[m]]; /* djb-rwth: fixing coverity ID #499549 */ if (0 <= at[cur_at].sb_ord[m] && at[cur_at].sb_ord[m] < at[cur_at].valence && - 0 <= ( nxt_at = at[cur_at].neighbor[(int) at[cur_at].sb_ord[m]] ) && at[nxt_at].valence <= MAX_NUM_STEREO_BONDS && /* make sure it is a valid stereobond */ ( nNextSbAtOrigNumb = at[nxt_at].orig_at_number )) { @@ -4561,7 +4561,7 @@ int set_stereo_parity( CANON_GLOBALS *pCG, cSource = (S_CHAR *) inchi_calloc( num_at, sizeof( cSource[0] ) ); if (!q || !cSource || !nAtomLevel) { - q = QueueDelete(q); /* djb-rwth: fixing coverity CID #499562 */ + q = QueueDelete(q); /* djb-rwth: fixing coverity ID #499562 */ inchi_free(nAtomLevel); /* djb-rwth: avoiding memory leak */ inchi_free(cSource); /* djb-rwth: avoiding memory leak */ num_3D_stereo_atoms = CT_OUT_OF_RAM; diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichitaut.c b/INCHI-1-SRC/INCHI_BASE/src/ichitaut.c index 6f3f73f6..ca20c7b0 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichitaut.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichitaut.c @@ -1582,7 +1582,7 @@ int GetNeutralRepsIfNeeded( AT_NUMB *pri, cgi->num_c_groups > 0) { /* at[ri] and at[rj] belong to the same charge group, at least one is charged */ - for (k = 0; k < cgi->num_c_groups; k++) /* MS VC++ 2008 reports unreachable code here ??? */ + for (k = 0; k < cgi->num_c_groups; k++) /* MS VC++ 2008 reports unreachable code here ??? */ /* djb-rwth: addressing coverity ID #499559 -- read the previous comment; can cgi->num_c_groups only have values 0 and 1? */ { if (cgi->c_group[k].nGroupNumber == c_point) { diff --git a/INCHI-1-SRC/INCHI_BASE/src/mol2atom.c b/INCHI-1-SRC/INCHI_BASE/src/mol2atom.c index ca519c0a..29e2389e 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/mol2atom.c +++ b/INCHI-1-SRC/INCHI_BASE/src/mol2atom.c @@ -1346,6 +1346,7 @@ int SetExtOrigAtDataByMolfileExtInput(MOL_FMT_DATA *mfdata, OAD_V3000 *pv = NULL; int nsgroups = mfdata->ctab.sgroups.used; + /* djb-rwth: addressing coverity ID #499476 -- TREAT_ERR properly used in all cases */ /* Polymers */ if (nsgroups > 0) { diff --git a/INCHI-1-SRC/INCHI_BASE/src/mol_fmt1.c b/INCHI-1-SRC/INCHI_BASE/src/mol_fmt1.c index 1bda05fd..b275b0f8 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/mol_fmt1.c +++ b/INCHI-1-SRC/INCHI_BASE/src/mol_fmt1.c @@ -184,6 +184,7 @@ MOL_FMT_DATA * MolfileReadDataLines( INCHI_IOSTREAM *inp_file, } /* djb-rwth: removing redundant code */ + /* djb-rwth: addressing coverity ID #499502 -- TREAT_ERR_AND_FIN properly used in all cases */ *err = 0; if (should_read_all) @@ -574,6 +575,8 @@ int MolfileReadCountsLine( MOL_FMT_CTAB* ctab, const int line_len = sizeof( line ); int err = 0, len; /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ + /* djb-rwth: addressing coverity ID #499502 -- TREAT_ERR properly used in all cases */ + p = inchi_fgetsLf( line, line_len, inp_file ); if (!p) @@ -667,6 +670,7 @@ int MolfileReadAtomsBlock( MOL_FMT_CTAB* ctab, S_SHORT chg; static const S_SHORT charge_val[] = { 0, 3, 2, 1, 'R', -1, -2, -3 }; + /* djb-rwth: addressing coverity ID #499580 -- TREAT_ERR properly used in all cases */ for (i = 0; i < ctab->n_atoms; i++) { p = inchi_fgetsLf( line, line_len, inp_file ); @@ -831,7 +835,7 @@ int MolfileReadBondsBlock( MOL_FMT_CTAB* ctab, } #endif - + /* djb-rwth: addressing coverity ID #499538 -- TREAT_ERR properly used in all cases */ for (i = 0; i < ctab->n_bonds; i++) { p = inchi_fgetsLf( line, line_len, inp_file ); @@ -928,7 +932,7 @@ int MolfileReadSTextBlock( MOL_FMT_CTAB* ctab, { if (!err) { - TREAT_ERR_AND_FIN( err, 2, err_fin, "Cannot read STEXT block line" ); + TREAT_ERR_AND_FIN( err, 2, err_fin, "Cannot read STEXT block line" ); /* djb-rwth: addressing coverity ID #499517 -- TREAT_ERR_AND_FIN properly used */ } break; /* can't read the input file line */ @@ -998,7 +1002,7 @@ int MolfileReadPropBlock( MOL_FMT_CTAB* ctab, read until M END line was encountered */ p = inchi_fgetsLf( line, line_len, inp_file ); - + /* djb-rwth: addressing coverity ID #499577 -- TREAT_ERR properly used in all cases */ if (!p) { if (!err) @@ -1860,6 +1864,8 @@ static int MolfileTreatPseudoElementAtoms( MOL_FMT_CTAB* ctab, { int i, nzz = 0; + /* djb-rwth: addressing coverity ID #499499 -- TREAT_ERR properly used in all cases */ + for (i = 0; i < ctab->n_atoms; i++) { int is_zz = 0, is_star = 0; diff --git a/INCHI-1-SRC/INCHI_BASE/src/mol_fmt2.c b/INCHI-1-SRC/INCHI_BASE/src/mol_fmt2.c index c89b2984..c4ccad4e 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/mol_fmt2.c +++ b/INCHI-1-SRC/INCHI_BASE/src/mol_fmt2.c @@ -272,7 +272,7 @@ int MolfileReadField(void *data, else { /* should not come here */ - ret = -1; + ret = -1; /* djb-rwth: addressing coverity ID #499478 -- see the original comment above */ } switch (data_type) diff --git a/INCHI-1-SRC/INCHI_BASE/src/mol_fmt3.c b/INCHI-1-SRC/INCHI_BASE/src/mol_fmt3.c index 2369663a..ba9844ee 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/mol_fmt3.c +++ b/INCHI-1-SRC/INCHI_BASE/src/mol_fmt3.c @@ -311,7 +311,7 @@ int MolfileV3000ReadField(void *data, } else if (data_type == MOL_FMT_INT_DATA) { - if (INT_MIN <= ldata && ldata <= INT_MAX) + if (INT_MIN <= ldata && ldata <= INT_MAX) /* djb-rwth: addressing coverity ID #499496/499553 -- ldata check seems to be necessary */ { *(int *)data = (int)ldata; } @@ -391,7 +391,7 @@ int MolfileV3000ReadField(void *data, } else { - *(float *)data = (float)ddata; + *(float *)data = (float)ddata; /* djb-rwth: addressing coverity ID #499519 -- probably never reached */ } } break; /* REAL's */ @@ -833,7 +833,7 @@ int MolfileV3000ReadCollections(MOL_FMT_CTAB *ctab, if (failed) { err = 7; - TREAT_ERR(err, 7, "Cannot interpret V3000 collection line(s)"); + TREAT_ERR(err, 7, "Cannot interpret V3000 collection line(s)"); /* djb-rwth: addressing coverity ID #499531 -- TREAT_ERR properly used */ if (line) { dotify_non_printable_chars(line); @@ -985,7 +985,7 @@ int MolfileV3000ReadAtomsBlock(MOL_FMT_CTAB *ctab, { err = 4; - TREAT_ERR(err, 4, "Cannot interpret V3000 atom block line:"); + TREAT_ERR(err, 4, "Cannot interpret V3000 atom block line:"); /* djb-rwth: addressing coverity ID #499547 -- TREAT_ERR properly used */ dotify_non_printable_chars(line); AddErrorMessage(pStrErr, line); @@ -1320,7 +1320,7 @@ int MolfileV3000ReadBondsBlock(MOL_FMT_CTAB *ctab, { if (!err) { - TREAT_ERR(err, 2, "Cannot read V3000 bond block line"); + TREAT_ERR(err, 2, "Cannot read V3000 bond block line"); /* djb-rwth: addressing coverity ID #499565 -- TREAT_ERR properly used */ } break; } @@ -1493,7 +1493,7 @@ int MolfileV3000ReadBondsBlock(MOL_FMT_CTAB *ctab, } } } - /* djb-rwth: addressing coverity CID #499489 -- false positive as num_atoms allocated in MolfileV3000ReadHapticBond and returns a value in this block */ + /* djb-rwth: addressing coverity ID #499489 -- false positive as num_atoms allocated in MolfileV3000ReadHapticBond and returns a value in this block */ } else if (!strcmp(field, "DISP")) { diff --git a/INCHI-1-SRC/INCHI_BASE/src/mol_fmt4.c b/INCHI-1-SRC/INCHI_BASE/src/mol_fmt4.c index 7f658b6f..ba527667 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/mol_fmt4.c +++ b/INCHI-1-SRC/INCHI_BASE/src/mol_fmt4.c @@ -247,7 +247,7 @@ int SDFileSkipExtraData(INCHI_IOSTREAM *inp_file, } else if (!prev_err) { - TREAT_ERR(err, 3, "Unexpected SData header line:"); + TREAT_ERR(err, 3, "Unexpected SData header line:"); /* djb-rwth: addressing coverity ID #499557 -- TREAT_ERR properly used */ dotify_non_printable_chars(line); AddErrorMessage(pStrErr, line); /* unexpected contents of data header line */ diff --git a/INCHI-1-SRC/INCHI_BASE/src/readinch.c b/INCHI-1-SRC/INCHI_BASE/src/readinch.c index 9dc27370..1cd1faaa 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/readinch.c +++ b/INCHI-1-SRC/INCHI_BASE/src/readinch.c @@ -1703,12 +1703,12 @@ int InchiToInpAtom( INCHI_IOSTREAM *inp_file, FreeInchi_Stereo0D(&atom_stereo0D); } - if (atom) /* djb-rwth: fixing coverity CID #499615 */ + if (atom) /* djb-rwth: fixing coverity ID #499615 */ { inchi_free(atom); } - if (pszCoord) /* djb-rwth: fixing coverity CID #499571 */ + if (pszCoord) /* djb-rwth: fixing coverity ID #499571 */ { inchi_free(pszCoord); } diff --git a/INCHI-1-SRC/INCHI_BASE/src/runichi.c b/INCHI-1-SRC/INCHI_BASE/src/runichi.c index a5dc9e1c..0c34930f 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/runichi.c +++ b/INCHI-1-SRC/INCHI_BASE/src/runichi.c @@ -255,8 +255,13 @@ int ProcessOneStructure( INCHI_CLOCK *ic, /* 1. Preliminary work */ - int is_polymer = orig_inp_data - && orig_inp_data->valid_polymer + /* djb-rwth: fixing coverity ID #499508 */ + if (!orig_inp_data) + { + goto exit_function; + } + + int is_polymer = orig_inp_data->valid_polymer && orig_inp_data->polymer && orig_inp_data->polymer->n ; @@ -644,6 +649,7 @@ void PrepareSaveOptBits( unsigned char *save_opt_bits, INPUT_PARMS *ip ) { ( *save_opt_bits ) |= SAVE_OPT_15T; } + /* djb-rwth: addressing coverity ID #499536 -- despite different bit-sizes, works properly */ if (0 != (ip->bTautFlags & TG_FLAG_PT_22_00)) (*save_opt_bits) |= SAVE_OPT_PT_22_00; if (0 != (ip->bTautFlags & TG_FLAG_PT_16_00)) @@ -790,7 +796,7 @@ void SaveOkProcessedMolfile( int nRet, 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd) { - MolfileSaveCopy( inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file->f, 0 ); + MolfileSaveCopy( inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file->f, 0 ); /* djb-rwth: addressing coverity ID #499510 -- return values handled properly */ } return; @@ -2892,7 +2898,13 @@ int ValidateAndPreparePolymerAndPseudoatoms( struct tagINCHI_CLOCK *ic, int mind_pseudoelements = 0; - *mind_polymers = orig_inp_data && orig_inp_data->polymer && orig_inp_data->polymer->n > 0; + /* djb-rwth: fixing coverity ID #499512 */ + if (!orig_inp_data) + { + goto exit_function; + } + + *mind_polymers = orig_inp_data->polymer && orig_inp_data->polymer->n > 0; *mind_polymers = *mind_polymers && orig_inp_data->valid_polymer && (ip->nInputType == INPUT_MOLFILE || ip->nInputType == INPUT_SDFILE); mind_pseudoelements = (ip->bNPZz == 1) || (ip->bPolymers != POLYMERS_NO); @@ -2911,8 +2923,7 @@ int ValidateAndPreparePolymerAndPseudoatoms( struct tagINCHI_CLOCK *ic, sd->nErrorCode, sd->pStrErrStruct, num_inp, SDF_LBL_VAL( ip->pSdfLabel, ip->pSdfValue ) ); res = _IS_ERROR; - if (orig_inp_data) /* djb-rwth: fixing a NULL pointer dereference */ - orig_inp_data->num_inp_atoms = -1; + orig_inp_data->num_inp_atoms = -1; /* djb-rwth: fixing coverity ID #499522 */ goto exit_function; } diff --git a/INCHI-1-SRC/INCHI_BASE/src/runichi2.c b/INCHI-1-SRC/INCHI_BASE/src/runichi2.c index f788eec4..a3649a4d 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/runichi2.c +++ b/INCHI-1-SRC/INCHI_BASE/src/runichi2.c @@ -793,7 +793,7 @@ int TreatErrorsInReadTheStructure( STRUCT_DATA *sd, #if ( bRELEASE_VERSION == 1 || EXTR_FLAGS == 0 ) if (prb_file && prb_file->f && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd && !ip->bSaveAllGoodStructsAsProblem) { - MolfileSaveCopy( inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file->f, *num_inp ); + MolfileSaveCopy( inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file->f, *num_inp ); /* djb-rwth: addressing coverity ID #499477 -- return values handled properly */ } #endif } @@ -2040,7 +2040,7 @@ DiylFrag* DiylFrag_New(int na, int end1, int end2, char *s) if (err) { DiylFrag_Free(pfrag); - inchi_free(pfrag); /* djb-rwth: addressing coverity CID #499507 */ + inchi_free(pfrag); /* djb-rwth: addressing coverity ID #499507 */ return NULL; } return pfrag; @@ -2168,7 +2168,7 @@ int analyze_CRU_folding(ORIG_ATOM_DATA *orig_at_data, OAD_PolymerUnit *u = orig_at_data->polymer->units[iunit]; ITRACE_("\n\n%-s\t\t%-s:%-d", "analyze_CRU_folding()", __FILE__,__LINE__); - pStrErr[0] = '\0'; /* djb-rwth: fixing coverity CID #499611; pStrErr is a dummy parameter in this function and is never used */ + pStrErr[0] = '\0'; /* djb-rwth: fixing coverity ID #499611; pStrErr is a dummy parameter in this function and is never used */ /* Reserve space for frag-specific xclass counts */ frag_xc_counts = (int *)inchi_calloc((long long)nxclasses + 1, sizeof(int)); /* djb-rwth: cast operator added */ diff --git a/INCHI-1-SRC/INCHI_BASE/src/runichi3.c b/INCHI-1-SRC/INCHI_BASE/src/runichi3.c index b3c191c0..b326e28d 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/runichi3.c +++ b/INCHI-1-SRC/INCHI_BASE/src/runichi3.c @@ -292,7 +292,7 @@ int OrigAtData_Duplicate( ORIG_ATOM_DATA *new_orig_atom, newp->pzz = (int *) inchi_calloc( newp->n_pzz, sizeof( int ) ); if (!newp->pzz) { - inchi_free(newp->units); /* djb-rwth: fixing coverity CID #499546 */ + inchi_free(newp->units); /* djb-rwth: fixing coverity ID #499546 */ inchi_free(newp); /* djb-rwth: avoiding memory leak */ goto exit_function; } @@ -347,9 +347,9 @@ int OrigAtData_Duplicate( ORIG_ATOM_DATA *new_orig_atom, lst = new_v3000->lists_haptic_bonds[m] = (int *) inchi_calloc( nn, sizeof( int ) ); if (!lst) { - inchi_free(new_v3000->lists_haptic_bonds); /* djb-rwth: fixing coverity CID #499504 */ - inchi_free(new_v3000->atom_index_orig); /* djb-rwth: fixing coverity CID #499540 */ - inchi_free(new_v3000->atom_index_fin); /* djb-rwth: fixing coverity CID #499613 */ + inchi_free(new_v3000->lists_haptic_bonds); /* djb-rwth: fixing coverity ID #499504 */ + inchi_free(new_v3000->atom_index_orig); /* djb-rwth: fixing coverity ID #499540 */ + inchi_free(new_v3000->atom_index_fin); /* djb-rwth: fixing coverity ID #499613 */ inchi_free(new_v3000); /* djb-rwth: avoiding memory leak */ goto exit_function; } @@ -368,10 +368,10 @@ int OrigAtData_Duplicate( ORIG_ATOM_DATA *new_orig_atom, lst = new_v3000->lists_steabs[m] = (int *) inchi_calloc( nn, sizeof( int ) ); if (!lst) { - inchi_free(new_v3000->lists_haptic_bonds); /* djb-rwth: fixing coverity CID #499504 */ - inchi_free(new_v3000->lists_steabs); /* djb-rwth: fixing coverity CID #499543 */ - inchi_free(new_v3000->atom_index_orig); /* djb-rwth: fixing coverity CID #499540 */ - inchi_free(new_v3000->atom_index_fin); /* djb-rwth: fixing coverity CID #499613 */ + inchi_free(new_v3000->lists_haptic_bonds); /* djb-rwth: fixing coverity ID #499504 */ + inchi_free(new_v3000->lists_steabs); /* djb-rwth: fixing coverity ID #499543 */ + inchi_free(new_v3000->atom_index_orig); /* djb-rwth: fixing coverity ID #499540 */ + inchi_free(new_v3000->atom_index_fin); /* djb-rwth: fixing coverity ID #499613 */ inchi_free(new_v3000); /* djb-rwth: avoiding memory leak */ goto exit_function; } @@ -396,11 +396,11 @@ int OrigAtData_Duplicate( ORIG_ATOM_DATA *new_orig_atom, lst = new_v3000->lists_sterel[m] = (int *) inchi_calloc( nn, sizeof( int ) ); if (!lst) { - inchi_free(new_v3000->lists_haptic_bonds); /* djb-rwth: fixing coverity CID #499504 */ - inchi_free(new_v3000->lists_steabs); /* djb-rwth: fixing coverity CID #499543 */ - inchi_free(new_v3000->lists_sterel); /* djb-rwth: fixing coverity CID #499504 */ - inchi_free(new_v3000->atom_index_orig); /* djb-rwth: fixing coverity CID #499540 */ - inchi_free(new_v3000->atom_index_fin); /* djb-rwth: fixing coverity CID #499613 */ + inchi_free(new_v3000->lists_haptic_bonds); /* djb-rwth: fixing coverity ID #499504 */ + inchi_free(new_v3000->lists_steabs); /* djb-rwth: fixing coverity ID #499543 */ + inchi_free(new_v3000->lists_sterel); /* djb-rwth: fixing coverity ID #499504 */ + inchi_free(new_v3000->atom_index_orig); /* djb-rwth: fixing coverity ID #499540 */ + inchi_free(new_v3000->atom_index_fin); /* djb-rwth: fixing coverity ID #499613 */ inchi_free(new_v3000); /* djb-rwth: avoiding memory leak */ goto exit_function; } @@ -421,12 +421,12 @@ int OrigAtData_Duplicate( ORIG_ATOM_DATA *new_orig_atom, lst = new_v3000->lists_sterac[m] = (int*)inchi_calloc(nn, sizeof(int)); if (!lst) { - inchi_free(new_v3000->lists_haptic_bonds); /* djb-rwth: fixing coverity CID #499504 */ - inchi_free(new_v3000->lists_steabs); /* djb-rwth: fixing coverity CID #499543 */ - inchi_free(new_v3000->lists_sterel); /* djb-rwth: fixing coverity CID #499504 */ - inchi_free(new_v3000->lists_sterac); /* djb-rwth: fixing coverity CID #499575 */ - inchi_free(new_v3000->atom_index_orig); /* djb-rwth: fixing coverity CID #499540 */ - inchi_free(new_v3000->atom_index_fin); /* djb-rwth: fixing coverity CID #499613 */ + inchi_free(new_v3000->lists_haptic_bonds); /* djb-rwth: fixing coverity ID #499504 */ + inchi_free(new_v3000->lists_steabs); /* djb-rwth: fixing coverity ID #499543 */ + inchi_free(new_v3000->lists_sterel); /* djb-rwth: fixing coverity ID #499504 */ + inchi_free(new_v3000->lists_sterac); /* djb-rwth: fixing coverity ID #499575 */ + inchi_free(new_v3000->atom_index_orig); /* djb-rwth: fixing coverity ID #499540 */ + inchi_free(new_v3000->atom_index_fin); /* djb-rwth: fixing coverity ID #499613 */ inchi_free(new_v3000); /* djb-rwth: avoiding memory leak */ goto exit_function; } @@ -1527,6 +1527,7 @@ int OAD_ValidatePolymerAndPseudoElementData( ORIG_ATOM_DATA *orig_at_data, /* Assign polymer type and subunits type and check polymer data for consistency */ + /* djb-rwth: addressing coverity ID #499497 -- TREAT_ERR properly used in all cases */ orig_at_data->valid_polymer = 0; if (treat_polymers && pd) @@ -2962,6 +2963,7 @@ void OAD_CollectBackboneAtoms(ORIG_ATOM_DATA *at_data, *nbkatoms = 0; maxbkbonds = at_data->num_inp_bonds + 2; *err = imat_new(maxbkbonds, 2, &(bkbonds)); + /* djb-rwth: addressing coverity ID #499570 -- TREAT_ERR properly used in all cases */ if (*err) { TREAT_ERR(*err, 9034, "Not enough memory (polymers)"); @@ -3139,7 +3141,7 @@ void OAD_CollectBackboneBonds(ORIG_ATOM_DATA *at_data, spf = subgraf_pathfinder_new( sg, at_data, start, end ); if (!spf) { - TREAT_ERR( *err, 9039, "Not enough memory (polymers)" ); + TREAT_ERR( *err, 9039, "Not enough memory (polymers)" ); /* djb-rwth: addressing coverity ID #499539 -- TREAT_ERR properly used */ /*unit->cyclizable = CLOSING_SRU_NOT_APPLICABLE;*/ return; } diff --git a/INCHI-1-SRC/INCHI_BASE/src/runichi4.c b/INCHI-1-SRC/INCHI_BASE/src/runichi4.c index a092e808..fc2c88e6 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/runichi4.c +++ b/INCHI-1-SRC/INCHI_BASE/src/runichi4.c @@ -1495,7 +1495,7 @@ int TreatCreateINChIWarning( STRUCT_DATA *sd, /* save the structure as a problem structure if requested */ if (ip->bSaveWarningStructsAsProblem && !ip->bSaveAllGoodStructsAsProblem && prb_file->f && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd) - { + { /* djb-rwth: addressing coverity ID #499545 -- return values handled properly */ MolfileSaveCopy( inp_file, sd->fPtrStart, sd->fPtrEnd, diff --git a/INCHI-1-SRC/INCHI_BASE/src/strutil.c b/INCHI-1-SRC/INCHI_BASE/src/strutil.c index 89f8d7d1..8e0d20e0 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/strutil.c +++ b/INCHI-1-SRC/INCHI_BASE/src/strutil.c @@ -759,7 +759,7 @@ int fix_odd_things( int num_atoms, /* found both X(-) and X(+); change bonds and remove charges */ for (k1 = 0; k1 < at[c].valence && i1 != at[c].neighbor[k1]; k1++) ; - if ((i1_c >= 0) && (i2_c >= 0)) /* djb-rwth: fixing coverity CID #499537 */ + if ((i1_c >= 0) && (i2_c >= 0)) /* djb-rwth: fixing coverity ID #499537 */ { at[i1].charge = at[i2].charge = 0; at[i1].bond_type[i1_c] = at[c].bond_type[k1] = BOND_TYPE_SINGLE; @@ -2747,7 +2747,7 @@ int bIsMetalToDisconnect( inp_ATOM *at, int i, int bCheckMetalValence ) for (i = 0; i < 2 && ( i & type ); i++) { - if (at_valence == get_el_valence( at[i].el_number, at[i].charge, i )) + if (at_valence == get_el_valence( at[i].el_number, at[i].charge, i )) /* djb-rwth: fixing coverity ID #499532 -- ui_rr */ { return 2; /* atom has normal valence */ } From ad4d65847b93c6805060cc79899013769a77f257 Mon Sep 17 00:00:00 2001 From: Djordje Baljozovic <121813753+djb-rwth@users.noreply.github.com> Date: Sat, 31 Jan 2026 20:14:04 +0100 Subject: [PATCH 2/9] Delete INCHI-1-SRC/INCHI_BASE/src/ichi_bns1.c --- INCHI-1-SRC/INCHI_BASE/src/ichi_bns1.c | 12490 ----------------------- 1 file changed, 12490 deletions(-) delete mode 100644 INCHI-1-SRC/INCHI_BASE/src/ichi_bns1.c diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichi_bns1.c b/INCHI-1-SRC/INCHI_BASE/src/ichi_bns1.c deleted file mode 100644 index b7244c1f..00000000 --- a/INCHI-1-SRC/INCHI_BASE/src/ichi_bns1.c +++ /dev/null @@ -1,12490 +0,0 @@ -/* - * International Chemical Identifier (InChI) - * Version 1 - * Software version 1.07 - * April 30, 2024 - * - * MIT License - * - * Copyright (c) 2024 IUPAC and InChI Trust - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -* -* The InChI library and programs are free software developed under the - * auspices of the International Union of Pure and Applied Chemistry (IUPAC). - * Originally developed at NIST. - * Modifications and additions by IUPAC and the InChI Trust. - * Some portions of code were developed/changed by external contributors - * (either contractor or volunteer) which are listed in the file - * 'External-contributors' included in this distribution. - * - * info@inchi-trust.org - * -*/ - - -/* -Balanced Network Search - -Normalization related procedures -*/ - -#include -#include -#include - -#include "mode.h" -#include "ichitime.h" -#include "ichicant.h" -#include "ichierr.h" -#include "ichitaut.h" -#include "ichinorm.h" -#include "util.h" -#include "ichister.h" -#include "ichi_bns.h" - -#include "bcf_s.h" - -#include -#include "logging.h" /*(@nnuk : Nauman Ullah Khan) :: Needed for logging functionality*/ - -#define BNS_MARK_ONLY_BLOCKS 1 /* 1 => find only blocks, do not search for ring systems */ -#define ALLOW_ONLY_SIMPLE_ALT_PATH 0 /* 0 => allow alt. path to contain same bond 2 times (in opposite directions) */ -#define CHECK_TG_ALT_PATH 0 /* 1=> when chacking alt path of a tautomeric atom modify -t-group, not the atom */ -/* 0=> old mode */ - -#define FIX_CPOINT_BOND_CAP 1 /* 1=> fix bug in case of double bond from neutral cpoint */ -#define RESET_EDGE_FORBIDDEN_MASK 1 /* 1: previous; 0: do not apply "edge->forbidden &= pBNS->edge_forbidden_mask" */ -#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) -#define IS_FORBIDDEN(EDGE_FORBIDDEN, PBNS) (EDGE_FORBIDDEN) -#else -#define IS_FORBIDDEN(EDGE_FORBIDDEN, PBNS) (EDGE_FORBIDDEN & PBNS->edge_forbidden_mask) -#endif - - -typedef enum tagAtTypeTotals -{ - /* counts do not include: - charged atom adjacent to another charged atom - atom in an unusual valence state or adjacent to an atom in an unusual valence state - radicals different from singlet - */ - /*ATTOT_NUM_Plus. */ /* number of positive charges, +1, is (ATTOT_NUM_CHARGES + ATTOT_TOT_CHARGE)/2 */ - /*ATTOT_NUM_Minus.*/ /* number of negative charges, -1, is (ATTOT_NUM_CHARGES - ATTOT_TOT_CHARGE)/2 */ - ATTOT_NUM_NP_Plus, /* 0 no H: =N(+)=, #N(+)-, =N(+)<, does not include onium cations >P(+)<, >N(+)< */ - ATTOT_NUM_NP_Proton, /* 1 H(+): -NH3(+), =NH2(+), >NH2(+), =NH(+)-, >NH(+)-, #NH(+), N=N,P */ - ATTOT_NUM_NP_H, /* 2 H: -NH2, =NH, >NH -NH(-) */ - ATTOT_NUM_N_Minus, /* 3 (-): -NH(-), >N(-), =N(-) */ - ATTOT_NUM_NP, /* 4 no H: >N- =N-, #N */ - ATTOT_NUM_ON, /* 5 -N=O: do not allow -N=O => -NH-OH during H(+) add/removal */ - ATTOT_NUM_COH, /* 6 =C-OH, #C-OH; O=O,S,Se,Te */ - ATTOT_NUM_CSH, /* 7 -C-SH, -C-SeH -C-TeH */ - ATTOT_NUM_ZOH, /* 8 =Z-OH, #Z-OH; O=O,S,Se,Te; Z may have charge, Z != C */ - ATTOT_NUM_OOH, /* 9 -O-OH, O=O,S,Se,Te */ - ATTOT_NUM_ZOOH, /* 10 O=Z-OH, O=O,S,Se,Te */ - ATTOT_NUM_NOH, /* 11 =N-OH, -N(-)-OH */ - ATTOT_NUM_N_OH, /* 12 >N-OH, -NH-OH, >NH(+)-OH, -N(-)-OH */ - ATTOT_NUM_CO, /* 13 -C=O, =C=O; O=O,S,Se,Te */ - ATTOT_NUM_ZO, /* 14 -Z=O, =Z=O; O=O,S,Se,Te; Z may have charge */ - ATTOT_NUM_NO, /* 15 -N=O, =N(+)=O */ - ATTOT_NUM_N_O, /* 16 >N(+)=O, =N(+)=O */ - ATTOT_NUM_CO_Minus, /* 17 =C-O(-), #C-O(-); O=O,S,Se,Te */ - ATTOT_NUM_CS_Minus, /* 18 -C-S(-); S = S, Se, Te */ - ATTOT_NUM_ZO_Minus, /* 19 =Z-O(-), #Z-O(-); O = O, S, Se, Te */ - ATTOT_NUM_OO_Minus, /* 20 -O-O(-), O=O,S,Se,Te */ - ATTOT_NUM_ZOO_Minus, /* 21 O=Z-O(-), O=O,S,Se,Te */ - ATTOT_NUM_NO_Minus, /* 22 >N-O(-), -NH-O(-) */ - ATTOT_NUM_N_O_Minus, /* 23 -NH-O(-), >N-O(-); O = O, S, Se, Te */ - ATTOT_NUM_O_Minus, /* 24 -Z-O(-); O=O,S,Se,Te */ - ATTOT_NUM_OH_Plus, /* 25 any OH(+) */ - ATTOT_NUM_O_Plus, /* 26 any O(+) without H */ - ATTOT_NUM_Proton, /* 27 proton */ - ATTOT_NUM_HalAnion, /* 28 Halogen anion */ - ATTOT_NUM_HalAcid, /* 29 Halogen acid */ - ATTOT_NUM_Errors, /* 30 for debugging */ - ATTOT_TOT_CHARGE, /* 31 total of positive and negative single charges, +1 and -1 */ - ATTOT_NUM_CHARGES, /* 32 number of positive and negative single charges, +1 and -1 */ - ATTOT_ARRAY_LEN /* 33 array length */ -} AT_TYPE_TOTALS; - -#define ATBIT_NP_Plus (1 << ATTOT_NUM_NP_Plus) -#define ATBIT_NP_Proton (1 << ATTOT_NUM_NP_Proton) -#define ATBIT_NP_H (1 << ATTOT_NUM_NP_H) -#define ATBIT_N_Minus (1 << ATTOT_NUM_N_Minus) -#define ATBIT_NP (1 << ATTOT_NUM_NP) -#define ATBIT_ON (1 << ATTOT_NUM_ON) -#define ATBIT_COH (1 << ATTOT_NUM_COH) -#define ATBIT_CSH (1 << ATTOT_NUM_CSH) -#define ATBIT_ZOH (1 << ATTOT_NUM_ZOH) -#define ATBIT_OOH (1 << ATTOT_NUM_OOH) -#define ATBIT_ZOOH (1 << ATTOT_NUM_ZOOH) -#define ATBIT_NOH (1 << ATTOT_NUM_NOH) -#define ATBIT_N_OH (1 << ATTOT_NUM_N_OH) -#define ATBIT_CO (1 << ATTOT_NUM_CO) -#define ATBIT_ZO (1 << ATTOT_NUM_ZO) -#define ATBIT_NO (1 << ATTOT_NUM_NO) -#define ATBIT_N_O (1 << ATTOT_NUM_N_O) -#define ATBIT_CO_Minus (1 << ATTOT_NUM_CO_Minus) -#define ATBIT_CS_Minus (1 << ATTOT_NUM_CS_Minus) -#define ATBIT_ZO_Minus (1 << ATTOT_NUM_ZO_Minus) -#define ATBIT_OO_Minus (1 << ATTOT_NUM_OO_Minus) -#define ATBIT_ZOO_Minus (1 << ATTOT_NUM_ZOO_Minus) -#define ATBIT_NO_Minus (1 << ATTOT_NUM_NO_Minus) -#define ATBIT_N_O_Minus (1 << ATTOT_NUM_N_O_Minus) -#define ATBIT_O_Minus (1 << ATTOT_NUM_O_Minus) -#define ATBIT_OH_Plus (1 << ATTOT_NUM_OH_Plus) -#define ATBIT_O_Plus (1 << ATTOT_NUM_O_Plus) -#define ATBIT_Proton (1 << ATTOT_NUM_Proton) -#define ATBIT_HalAnion (1 << ATTOT_NUM_HalAnion) -#define ATBIT_HalAcid (1 << ATTOT_NUM_HalAcid) - - -#define ATBIT_Errors (1 << ATTOT_NUM_Errors) - -typedef struct tagProtonRemovalMaskAndType -{ - int typePos; /* atoms accessible to positive charges */ - int maskPos; - int typeNeg; /* atoms accessible to negative charges */ - int maskNeg; - int typeH; /* atoms accessible to hydrogen atoms */ - int maskH; -} PRMAT; - -#define PR_SIMPLE_MSK (ATBIT_NP_Proton | ATBIT_OH_Plus) -#define PR_SIMPLE_TYP (ATT_ATOM_N | ATT_ATOM_P | ATT_O_PLUS) - -#define ATBIT_MSK_NP (ATBIT_NP_Plus | ATBIT_NP_Proton | ATBIT_NP_H | ATBIT_N_Minus | ATBIT_NP) -#define KNOWN_ACIDIC_TYPE (ATT_ACIDIC_CO | ATT_ACIDIC_S | ATT_OO | ATT_ZOO | ATT_NO) -#define ATBIT_MSK_OS (ATBIT_COH | ATBIT_CSH | ATBIT_ZOH | ATBIT_OOH | ATBIT_ZOOH | ATBIT_NOH | ATBIT_N_OH |\ - ATBIT_CO | ATBIT_ZO | ATBIT_NO | ATBIT_N_O |\ - ATBIT_CO_Minus | ATBIT_CS_Minus | ATBIT_ZO_Minus | ATBIT_OO_Minus |\ - ATBIT_ZOO_Minus | ATBIT_NO_Minus | ATBIT_N_O_Minus /*| ATBIT_O_Minus*/ ) -#define ATBIT_MSK_H (ATBIT_NP_Proton | ATBIT_NP_H | ATBIT_COH | ATBIT_CSH | ATBIT_ZOH | ATBIT_OOH |\ - ATBIT_ZOOH | ATBIT_NOH | ATBIT_N_OH) - -#define ATTYP_OS (ATT_ACIDIC_CO | ATT_ACIDIC_S | ATT_OO | ATT_ZOO | ATT_NO /*| ATT_OTHER_NEG_O*/ | ATT_OTHER_ZO) -#define ATTYP_NP (ATT_ATOM_N | ATT_ATOM_P) -#define ATTYP_N (ATT_ATOM_N) -#define ATTYP_P (ATT_ATOM_P) - -/************* simple proton removal from acids **************************/ -#define AR_ANY_OH 0 /* 1 => create unknown to be acidic anions */ -#define AR_SIMPLE_STEPS 3 -/* acidic groups for proton removal, step 1 */ -#define AR_SIMPLE_MSK1 (ATBIT_COH | ATBIT_CSH | ATBIT_OOH | ATBIT_ZOOH | ATBIT_NOH | ATBIT_HalAcid) -#define AR_SIMPLE_TYP1 (ATT_ACIDIC_CO | ATT_ACIDIC_S | ATT_OO | ATT_ZOO | ATT_NO | ATT_HalAcid) -/* acidic groups for proton removal, step 2 */ -#define AR_SIMPLE_MSK2 (AR_ANY_OH? (ATBIT_N_OH) :0) -#define AR_SIMPLE_TYP2 (AR_ANY_OH? (ATT_N_O) :0) -/* acidic groups for proton removal, step 3 */ -#define AR_SIMPLE_MSK3 (AR_ANY_OH? (ATBIT_ZOH) :0) -#define AR_SIMPLE_TYP3 (AR_ANY_OH? (ATT_OTHER_ZO):0) - -/************* simple proton addition to acids **************************/ -#define AA_ANY_O_Minus 0 /* 1 => neutralize unknown to be acidic anions */ -#define AA_SIMPLE_STEPS 3 -/* acidic groups for proton addition, step 1 */ -#define AA_SIMPLE_MSK1 (ATBIT_CO_Minus | ATBIT_CS_Minus | ATBIT_OO_Minus | ATBIT_ZOO_Minus | ATBIT_NO_Minus | ATBIT_O_Minus | ATBIT_HalAnion) -#define AA_SIMPLE_TYP1 (ATT_ACIDIC_CO | ATT_ACIDIC_S | ATT_OO | ATT_ZOO | ATT_NO | ATT_OH_MINUS | ATT_HalAnion ) -/* acidic groups for proton addition, step 2 */ -#define AA_SIMPLE_MSK2 (AA_ANY_O_Minus? (ATBIT_N_O_Minus) :0) -#define AA_SIMPLE_TYP2 (AA_ANY_O_Minus? (ATT_N_O) :0) -/* acidic groups for proton addition, step 3 */ -#define AA_SIMPLE_MSK3 (AA_ANY_O_Minus? (ATBIT_ZO_Minus | ATBIT_O_Minus):0) -#define AA_SIMPLE_TYP3 (AA_ANY_O_Minus? (ATT_OTHER_ZO) :0) - -#if ( FIX_NP_MINUS_BUG == 1 ) -/* allow to add H(+) to =N(-) which previously was #N */ -#undef AA_SIMPLE_STEPS -#define AA_SIMPLE_STEPS 4 -#define AA_SIMPLE_MSK4 ATBIT_N_Minus -#define AA_SIMPLE_TYP4 ATT_NP_MINUS_V23 -#endif - -/************* hard proton removal from NP **************************/ -/* (+) charge group for proton removal: mask & type */ -#define PR_HARD_MSK_POS ATBIT_MSK_NP -#define PR_HARD_TYP_POS ATTYP_N -#define PR_HARD_TYP_POSP ATTYP_P -/* (-) charge group for proton removal */ -#define PR_HARD_MSK_NEG (ATBIT_MSK_NP | ATBIT_MSK_OS) -#define PR_HARD_TYP_NEG (ATTYP_N | ATTYP_OS) -/* H-group for proton removal */ -#define PR_HARD_MSK_H (ATBIT_MSK_NP | ATBIT_MSK_OS) -#define PR_HARD_TYP_H (ATTYP_N | ATTYP_OS) - -/************* hard proton removal from acids **************************/ -/* (+) charge group for proton removal: mask & type */ -#define AR_HARD_MSK_POS ATBIT_MSK_NP -#define AR_HARD_TYP_POS ATTYP_N -/* (-) charge group for proton removal */ -#define AR_HARD_MSK_NEG (ATBIT_MSK_NP | ATBIT_MSK_OS) -#define AR_HARD_TYP_NEG (ATTYP_N | ATTYP_OS) -/* H-group acid for proton removal */ -#define AR_HARD_MSK_HA (ATBIT_CO | ATBIT_NO ) -#define AR_HARD_TYP_HA (ATT_ACIDIC_CO | ATT_NO) -/* H-group non-acid for proton removal */ -#define AR_HARD_MSK_HN ((ATBIT_MSK_NP | ATBIT_MSK_OS) & ~AR_HARD_MSK_HA) -#define AR_HARD_TYP_HN ((ATTYP_N | ATTYP_OS) /*& ~AR_HARD_TYP_HA*/) - -/************* hard proton addition to acids **************************/ -/* (+) charge group for proton removal: mask & type */ -#define AA_HARD_MSK_POS ATBIT_MSK_NP -#define AA_HARD_TYP_POS ATTYP_N -/* (-) charge group for negative charge removal */ -#define AA_HARD_MSK_NEG ((ATBIT_MSK_NP | ATBIT_MSK_OS) & ~(ATBIT_CO | ATBIT_NO )) -#define AA_HARD_TYP_NEG (ATTYP_N | ATTYP_OS) -/* (-) charge group to accept negative charges */ -#define AA_HARD_MSK_CO (ATBIT_CO | ATBIT_NO ) -#define AA_HARD_TYP_CO (ATT_ACIDIC_CO | ATT_NO) -/* H-group non-acid for proton removal */ -#define AA_HARD_MSK_H (ATBIT_MSK_NP | ATBIT_MSK_OS) -#define AA_HARD_TYP_H (ATTYP_N | ATTYP_OS) - - -/*****************************************************************************/ -#define BNS_MAX_NUM_FLOW_CHANGES (1+2*MAX_BOND_EDGE_CAP) - -/* -- opiginal Pascal values -- -#define NO_VERTEX 0 -#define BLOSSOM_BASE -1 -#define FIRST_INDX 1 -*/ - -#define TREE_NOT_IN_M 0 /* not in T or T' */ -#define TREE_IN_2 1 /* in T' and not s-reachable */ -#define TREE_IN_2BLOSS 2 /* in T' and in a blossom, is s-reachable */ -#define TREE_IN_1 3 /* in T and is s-reachable */ - -#define TREE_IS_S_REACHABLE(X) (Tree[X] >= TREE_IN_2BLOSS) -#define TREE_IS_ON_SCANQ TREE_IS_S_REACHABLE -/* #define TREE_IS_ON_SCANQ(X) (Tree[X] != TREE_NOT_IN_M) */ -#define TREE_MARK(X, MARK) do{ if( Tree[X] < MARK ) Tree[X]=MARK; }while(0) - - -/***************************************************************************** -* store changes done to check whether an alternating path exists -* (see bSetBnsToCheckAltPath, bRestoreBnsAfterCheckAltPath) -******************************************************************************/ -typedef struct tagAltPathChanges -{ - /* caps changed in up to 2 vertices */ - VertexFlow nOldCapsVert[2][MAXVAL + 1]; - Vertex vOldVert[2]; - S_CHAR bSetOldCapsVert[2]; /* number of caps to restore, including st-cap */ - /* save ids of the newly created temporary vertices */ - Vertex vNewVertex[2]; - S_CHAR bSetNew[2]; /* indicators whether to remove vertices */ -} ALT_PATH_CHANGES; - - - -/*****************************************************************************/ - - -/* Local functions */ - -int RestoreRadicalsOnly( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at ); -int bRadChangesAtomType( BN_STRUCT *pBNS, BN_DATA *pBD, Vertex v, Vertex v_1, Vertex v_2 ); -int BnsAdjustFlowBondsRad( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at, int num_atoms ); -int SetAtomRadAndChemValFromVertexCapFlow( BN_STRUCT *pBNS, inp_ATOM *atom, int v1 ); -int bNeedToTestTheFlow( int bond_type, int nTestFlow, int bTestForNonStereoBond ); -int RestoreEdgeFlow( BNS_EDGE *edge, int delta, int bChangeFlow ); -int SetAtomBondType( BNS_EDGE *edge, U_CHAR *bond_type12, U_CHAR *bond_type21, int delta, int bChangeFlow ); -int RestoreBnStructFlow( BN_STRUCT *pBNS, int bChangeFlow ); -int CompTGroupNumber( const void *tg1, const void *tg2, void *p ); -int CompCGroupNumber( const void *cg1, const void *cg2, void *p ); - -/* Rings, Blocks, Non-stereo bonds */ -int ReInitBnStructForAltBns( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, int bUnknAltAsNoStereo ); -int MarkRingSystemsAltBns( BN_STRUCT* pBNS, int bUnknAltAsNoStereo ); -int MarkNonStereoAltBns( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, int bUnknAltAsNoStereo ); - -/* Called from BalancedNetworkSearch */ -int GetVertexDegree( BN_STRUCT* pBNS, Vertex v ); -/* Vertex Get2ndNeighbor1( BN_STRUCT* pBNS, Vertex u, EdgeIndex iedge ); not used */ -Vertex Get2ndEdgeVertex( BN_STRUCT* pBNS, Edge uv ); -Vertex GetVertexNeighbor( BN_STRUCT* pBNS, Vertex v, int neigh, EdgeIndex *iedge ); -int GetEdgePointer( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv, BNS_EDGE **uv, S_CHAR *s_or_t ); -int AugmentEdge( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv, int delta, S_CHAR bReverse, int bChangeFlow ); -int rescap_mark( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv ); -int rescap( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv ); -Vertex FindBase( Vertex u, Vertex *BasePtr ); -int FindPathToVertex_s( Vertex x, Edge *SwitchEdge, Vertex *BasePtr, Vertex *Path, int MaxPathLen ); -Vertex MakeBlossom( BN_STRUCT* pBNS, Vertex *ScanQ, int *pQSize, - Vertex *Pu, Vertex *Pv, int max_len_Pu_Pv, - Edge *SwitchEdge, Vertex *BasePtr, - Vertex u, Vertex v, EdgeIndex iuv, Vertex b_u, Vertex b_v, S_CHAR *Tree ); -int PullFlow( BN_STRUCT *pBNS, Edge *SwitchEdge, Vertex x, Vertex y, int delta, S_CHAR bReverse, int bChangeFlow ); -int FindPathCap( BN_STRUCT* pBNS, Edge *SwitchEdge, Vertex x, Vertex y, int delta ); - -/* -int SetBondType( BNS_EDGE *edge, U_CHAR *bond_type12, U_CHAR *bond_type21, int delta, int bChangeFlow ); -int SetBondsRestoreBnStructFlow( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, int bChangeFlow ); -*/ -int SetBondsFromBnStructFlow( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, int bChangeFlow0 ); -int MarkAtomsAtTautGroups( BN_STRUCT *pBNS, int num_atoms, BN_AATG *pAATG, int nEnd1, int nEnd2 ); - -int nMinFlow2Check( BN_STRUCT *pBNS, int iedge ); -int nMaxFlow2Check( BN_STRUCT *pBNS, int iedge ); -int nCurFlow2Check( BN_STRUCT *pBNS, int iedge ); - -/* Bonds testing */ -/* -int bRestoreFlowToCheckOneBond( BN_STRUCT *pBNS, BNS_FLOW_CHANGES *fcd, int nTestFlow, inp_ATOM *at, int num_atoms, int bChangeFlow ); -*/ -int bSetFlowToCheckOneBond( BN_STRUCT *pBNS, int iedge, int flow, BNS_FLOW_CHANGES *fcd ); -int bRestoreFlowAfterCheckOneBond( BN_STRUCT *pBNS, BNS_FLOW_CHANGES *fcd ); -int bSetBondsAfterCheckOneBond( BN_STRUCT *pBNS, BNS_FLOW_CHANGES *fcd, int nTestFlow, inp_ATOM *at, int num_atoms, int bChangeFlow ); -int BnsTestAndMarkAltBonds( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at, int num_atoms, BNS_FLOW_CHANGES *fcd, int bChangeFlow, int nBondTypeToTest ); -/* -int bIsAltBond(int bond_type); -- djb-rwth: function definition not found -*/ - -/* Fix bonds */ -int fix_special_bonds( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, int edge_forbidden_mask ); -int TempFix_NH_NH_Bonds( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms ); -int CorrectFixing_NH_NH_Bonds( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms ); -int fix_explicitly_indicated_bonds( int nebend, int *ebend, BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms ); - -/* Alt path testing */ -int bSetBnsToCheckAltPath( BN_STRUCT *pBNS, int nVertDoubleBond, int nVertSingleBond, AT_NUMB type, - int path_type, ALT_PATH_CHANGES *apc, BNS_FLOW_CHANGES *fcd, int *nDots ); -int bRestoreBnsAfterCheckAltPath( BN_STRUCT *pBNS, ALT_PATH_CHANGES *apc, int bChangeFlow ); -Vertex GetGroupVertex( BN_STRUCT *pBNS, Vertex v1, AT_NUMB type ); -BNS_IEDGE GetEdgeToGroupVertex( BN_STRUCT *pBNS, Vertex v1, AT_NUMB type ); -int bAddNewVertex( BN_STRUCT *pBNS, int nVertDoubleBond, int nCap, int nFlow, int nMaxAdjEdges, int *nDots ); -int AddNewEdge( BNS_VERTEX *p1, BNS_VERTEX *p2, BN_STRUCT *pBNS, int nEdgeCap, int nEdgeFlow ); -int bAddStCapToAVertex( BN_STRUCT *pBNS, Vertex v1, Vertex v2, VertexFlow *nOldCapVertSingleBond, int *nDots, int bAdjacentDonors ); - -static void remove_alt_bond_marks( inp_ATOM *at, int num_atoms ); -int bIsBnsEndpoint( BN_STRUCT *pBNS, int v ); - -/* Protons removal, charge neutralization */ -/* int is_acidic_CO(inp_ATOM* atom, int at_no); */ /* djb-rwth: function definition not found*/ -int mark_at_type( inp_ATOM *atom, int num_atoms, int nAtTypeTotals[] ); -int GetAtomChargeType( inp_ATOM *atom, int at_no, int nAtTypeTotals[], int *pMask, int bSubtract ); -int AddChangedAtHChargeBNS( inp_ATOM *at, int num_atoms, int nAtTypeTotals[], S_CHAR *mark ); -int EliminatePlusMinusChargeAmbiguity( BN_STRUCT *pBNS, int num_atoms ); -int AddOrRemoveExplOrImplH( int nDelta, inp_ATOM *at, int num_atoms, AT_NUMB at_no, T_GROUP_INFO *t_group_info ); -int SubtractOrChangeAtHChargeBNS( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, - int nAtTypeTotals[], S_CHAR *mark, T_GROUP_INFO *t_group_info, int bSubtract ); -int is_Z_atom( U_CHAR el_number ); -int IsZOX( inp_ATOM *atom, int at_x, int ord ); -int SimpleRemoveHplusNPO( inp_ATOM *at, int num_atoms, int nAtTypeTotals[], T_GROUP_INFO *t_group_info ); -int CreateCGroupInBnStruct( inp_ATOM *at, int num_atoms, - BN_STRUCT *pBNS, int nType, int nMask, int nCharge ); -int CreateTGroupInBnStruct( inp_ATOM *at, int num_atoms, - BN_STRUCT *pBNS, int nType, int nMask ); -int RemoveLastGroupFromBnStruct( inp_ATOM *at, int num_atoms, int tg, BN_STRUCT *pBNS ); -int SetInitCapFlowToCurrent( BN_STRUCT *pBNS ); -int SimpleRemoveAcidicProtons( inp_ATOM *at, int num_atoms, BN_AATG *pAATG, int num2remove ); -int SimpleAddAcidicProtons( inp_ATOM *at, int num_atoms, BN_AATG *pAATG, int num2add ); -int HardRemoveAcidicProtons( struct tagCANON_GLOBALS *pCG, inp_ATOM *at, int num_atoms, BN_AATG *pAATG, int num2remove, - int *nNumCanceledCharges, BN_STRUCT *pBNS, BN_DATA *pBD ); -int HardAddAcidicProtons( struct tagCANON_GLOBALS *pCG, inp_ATOM *at, int num_atoms, BN_AATG *pAATG, int num2add, - int *nNumCanceledCharges, BN_STRUCT *pBNS, BN_DATA *pBD ); -int HardRemoveHplusNP( struct tagCANON_GLOBALS *pCG, inp_ATOM *at, int num_atoms, int bCancelChargesAlways, int *nNumCanceledCharges, - BN_AATG *pAATG, BN_STRUCT *pBNS, BN_DATA *pBD ); -int RemoveNPProtonsAndAcidCharges( struct tagCANON_GLOBALS *pCG, inp_ATOM *at, int num_atoms, BN_AATG *pAATG, BN_STRUCT *pBNS, BN_DATA *pBD ); -Vertex GetPrevVertex( BN_STRUCT* pBNS, Vertex y, Edge *SwitchEdge, EdgeIndex *iuv ); -int bIgnoreVertexNonTACN_atom( BN_STRUCT* pBNS, Vertex u, Vertex v ); -int bIgnoreVertexNonTACN_group( BN_STRUCT* pBNS, Vertex v, Vertex w, Edge *SwitchEdge ); -int bIsRemovedHfromNHaion( BN_STRUCT* pBNS, Vertex u, Vertex v ); -int bIsAggressiveDeprotonation( BN_STRUCT* pBNS, Vertex v, Vertex w, Edge *SwitchEdge ); - -int bIsAtomTypeHard( inp_ATOM *at, int endpoint, int nType, int nMask, int nCharge ); -int bIsHDonorAccAtomType( inp_ATOM *at, int endpoint, int *cSubType ); -int bIsNegAtomType( inp_ATOM *at, int i, int *cSubType ); - -#if ( BNS_RAD_SEARCH == 1 ) -int RegisterRadEndpoint( BN_STRUCT *pBNS, BN_DATA *pBD, Vertex u ); -int cmp_rad_endpoints( const void *a1, const void *a2 ); -int cmp_endpoints_rad( const void *a1, const void *a2 ); -#endif - -int bHasChargedNeighbor( inp_ATOM *at, int iat ); -/*****************************************************************************/ -/**** prim(v) is v' *****/ -#define prim(v) (Vertex)((v)^1) - -/*****************************************************************************/ -#define SwitchEdge_Vert1(u) SwitchEdge[u][0] -#define SwitchEdge_Vert2(u) Get2ndEdgeVertex( pBNS, SwitchEdge[u] ) -#define SwitchEdge_IEdge(u) SwitchEdge[u][1] -/*****************************************************************************/ - - - - - -/**************************************************************************** -Returns value > 0 if a bond has been changed -****************************************************************************/ -int RestoreEdgeFlow( BNS_EDGE *edge, int delta, int bChangeFlow ) -{ - /*flow1 = edge->flow;*/ /* output from BNS */ - switch (bChangeFlow & BNS_EF_CHNG_RSTR) - { - case 0: - /* the flow has not been permitted to change inside the BNS */ - /* nothing to do */ - /*flow1 = edge->flow;*/ /* output from BNS, the original flow value */ - /*flow2 = flow1 + delta;*/ /* the flow would be changed to this value by the BNS if permitted */ - break; - case BNS_EF_CHNG_FLOW: - /* the flow has been changed by the BNS; update flow0 */ - /*flow2 = edge->flow;*/ /* output from BNS, the changed value */ - /*flow1 = flow2 - delta;*/ /* the original flow value before the BNS */ - edge->flow0 = edge->flow; /* SAVE NEW EDGE FLOW AS THE INITIAL FLOW FROM CHEM. BONDS */ - break; - case BNS_EF_CHNG_RSTR: - /* the flow has been changed by the BNS; requested to change it back */ - /*flow2 = edge->flow;*/ /* output from BNS, the changed value */ - /*flow1 = flow2 - delta;*/ /* the original flow value before the BNS */ - edge->flow = edge->flow - delta; /* CHANGE EDGE FLOW BACK (RESTORE) */ - break; - case BNS_EF_RSTR_FLOW: - /* the flow has not been permitted to change inside the BNS */ - /* nothing to do */ - /*flow1 = edge->flow;*/ /* output from BNS, the original flow value */ - /*flow2 = flow1 + delta;*/ /* the flow would be changed to this value by the BNS if permitted */ - break; - } - - return 0; -} - - -/**************************************************************************** -Returns value > 0 if a bond has been changed; do not change flow -****************************************************************************/ -int SetAtomBondType( BNS_EDGE *edge, - U_CHAR *bond_type12, - U_CHAR *bond_type21, - int delta, - int bChangeFlow ) -{ - int flow1, flow2, tmp, ret = 0; - int bond_mark = 0, bond_type, new_bond_type; /* djb-rwth: addressing LLVM warning */ - - if (!edge->pass || !bond_type21) - { - return 0; - } - - switch (bChangeFlow & BNS_EF_CHNG_RSTR) - { - case 0: /* the flow has not been permitted to change inside the BNS: simulated in case of check one bond */ - case BNS_EF_RSTR_FLOW: /* the flow has not been permitted to change inside the BNS: obsolete mode, unexpected bChangeFlow */ - flow1 = edge->flow0; /* output from BNS, the original (old) flow value */ - flow2 = flow1 + delta; /* the flow would be changed to this value by the BNS if permitted */ - break; - case BNS_EF_CHNG_FLOW: /* the flow has been changed by the BNS */ - case BNS_EF_CHNG_RSTR: /* the flow has been changed by the BNS; requested to change it back */ - flow2 = edge->flow; /* output from BNS, the changed (new) value */ - flow1 = edge->flow0; /* the original flow (old) value before the BNS */ - break; - default: - return 0; /* added 2006-03-21 */ - } - - if (( bChangeFlow & BNS_EF_CHNG_BONDS ) && ( bChangeFlow & BNS_EF_ALTR_NS ) != BNS_EF_ALTR_NS) - { - /* Set new bond types according to the new flow values */ - new_bond_type = flow2 + BOND_SINGLE; - if (*bond_type12 != new_bond_type) - { - *bond_type12 = *bond_type21 = new_bond_type; - ret++; - } - } - else - { - if (bChangeFlow & BNS_EF_ALTR_BONDS) - { - if (flow1 == flow2) - { - goto exit_function; - } - /* Update alternating bond information */ - if (flow1 > flow2) - { - /* Make sure flow2 > flow1 */ - tmp = flow1; - flow1 = flow2; - flow2 = tmp; - } - /* djb-rwth: removing redundant code */ - switch (bond_type = ( *bond_type12 & BOND_TYPE_MASK )) - { - case BOND_SINGLE: - case BOND_DOUBLE: - case BOND_TRIPLE: - /* assume that the input bond type fits either flow1 or flow2 */ - if (flow1 == 0 && flow2 == 1) - { - if (bChangeFlow & BNS_EF_SET_NOSTEREO) - { - bond_mark = BOND_MARK_ALT12NS; - bond_type = BOND_ALT12NS; - } - else - { - bond_mark = BOND_MARK_ALT12; - bond_type = BOND_ALTERN; - } - } - else - { - if (flow1 == 0 && flow2 == 2) - { - bond_mark = BOND_MARK_ALT13; - bond_type = BOND_ALT_13; - } - else - { - if (flow1 == 1 && flow2 == 2) - { - bond_mark = BOND_MARK_ALT23; - bond_type = BOND_ALT_23; - } - else - { - return BNS_BOND_ERR; /* error */ - } - } - } - break; - case BOND_TAUTOM: - if (flow1 == 0 && flow2 == 1) - { - bond_mark = BOND_MARK_ALT12NS; - } - else - if (flow1 == 1 && flow2 == 2) { - bond_mark = BOND_MARK_ALT23; - } - else { - return BNS_BOND_ERR; /* error */ - } - break; - default: - new_bond_type = bond_type; - bond_mark = ( *bond_type12 & BOND_MARK_MASK ); - switch (bond_mark) - { - case BOND_MARK_ALT12: - if (( bChangeFlow & BNS_EF_SET_NOSTEREO ) && flow1 == 0 && flow2 == 1) - { - bond_mark = BOND_MARK_ALT12NS; - new_bond_type = BOND_ALT12NS; - break; - } - case BOND_MARK_ALT12NS: - if (flow1 == 2 || flow2 == 2) - { - bond_mark = BOND_MARK_ALT123; - new_bond_type = BOND_ALT_123; - } - break; - case BOND_MARK_ALT13: - if (flow1 == 1 || flow2 == 1) - { - bond_mark = BOND_MARK_ALT123; - new_bond_type = BOND_ALT_123; - } - break; - case BOND_MARK_ALT23: - if (flow1 == 0 || flow2 == 0) - { - bond_mark = BOND_MARK_ALT123; - new_bond_type = BOND_ALT_123; - } - break; - case BOND_MARK_ALT123: - break; - - case 0: /* special case: second alt bond testing */ - if (flow1 == 0 && flow2 == 1) - { - bond_mark = BOND_MARK_ALT12; - } - else - { - if (flow1 == 0 && flow2 == 2) - { - bond_mark = BOND_MARK_ALT13; - } - else - { - if (flow1 == 1 && flow2 == 2) - { - bond_mark = BOND_MARK_ALT23; - } - else - { - return BNS_BOND_ERR; /* error */ - } - } - } - break; - - default: - return BNS_BOND_ERR; /* error */ - } - - switch (bond_type) - { - case BOND_TAUTOM: - break; - case BOND_ALTERN: - case BOND_ALT12NS: - case BOND_ALT_123: - case BOND_ALT_13: - case BOND_ALT_23: - bond_type = new_bond_type; - break; - default: - return BNS_BOND_ERR; /* error */ - } - } - - new_bond_type = bond_type | bond_mark; - if (new_bond_type != *bond_type12) - { - *bond_type12 = *bond_type21 = new_bond_type; - ret++; - } - } - } - -exit_function: - - return ret; -} - - -/**************************************************************************** -Run BalancedNetworkSearch( ... ) until no aug pass is found -****************************************************************************/ -int RunBalancedNetworkSearch( BN_STRUCT *pBNS, BN_DATA *pBD, int bChangeFlow ) -{ - int pass, delta = 0, nSumDelta; - - nSumDelta = 0; - for (pass = 0; pass < pBNS->max_altp; pass++) - { - pBNS->alt_path = pBNS->altp[pass]; - pBNS->bChangeFlow = 0; - delta = BalancedNetworkSearch( pBNS, pBD, bChangeFlow ); - ReInitBnData( pBD ); - if (0 < delta) - { - pBNS->num_altp++; - nSumDelta += abs( delta ); - } - else - { - break; - } - } - - if (IS_BNS_ERROR( delta )) - { - return delta; - } - - if (bInchiTimeIsOver( pBNS->ic, pBNS->ulTimeOutTime )) - { - return BNS_TIMEOUT; - } - - return nSumDelta; /* number of eliminated pairs of "dots" */ -} - - -/****************************************************************************/ -int SetAtomRadAndChemValFromVertexCapFlow( BN_STRUCT *pBNS, - inp_ATOM *atom, - int v1 ) -{ - BNS_VERTEX *vert = pBNS->vert + v1; - inp_ATOM *at = atom + v1; - S_CHAR cValue; - int nChanges = 0; - - /* Set only on the 1st pass */ - if (!vert->st_edge.pass) - { - return 0; - } - - /* Adjust chem_bonds_valence */ - cValue = at->chem_bonds_valence - at->valence; - if (cValue >= 0 && cValue != vert->st_edge.flow) - { - at->chem_bonds_valence = at->valence + vert->st_edge.flow; - nChanges++; - } - - /* Adjist radical */ - switch (vert->st_edge.cap - vert->st_edge.flow) - { - case 0: - cValue = 0; - break; - case 1: - cValue = RADICAL_DOUBLET; - break; - case 2: - cValue = RADICAL_TRIPLET; - break; - default: - return BNS_BOND_ERR; - } - if (cValue != at->radical) - { - at->radical = cValue; - nChanges++; - } - - return nChanges; -} - - -/****************************************************************************/ -int AddChangedAtHChargeBNS( inp_ATOM *at, - int num_atoms, - int nAtTypeTotals[], - S_CHAR *mark ) -{ - int i, mask, num; - for (i = 0, num = 0; i < num_atoms; i++) - { - if (mark[i]) - { - mark[i] = 0; -#if ( FIX_NORM_BUG_ADD_ION_PAIR == 1 ) - /* add ignoring adjacent charges */ - at[i].at_type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, -2 ); -#else - at[i].at_type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); -#endif - num++; - } - } - - return num; -} - - -/**************************************************************************** -Eliminate neutral representation ambiguity: - -replace (+)--N==(-) with (+)==N--(-) - -here (+) is positive charge group, -(-) is negative charge group, N is N or P -This reduces possibility of creating ion pair -OH => -O(+) + H(+) -instead of removing H(+) from N or P - -!Call this function after alt path was found and new flows have been set. -****************************************************************************/ -int EliminatePlusMinusChargeAmbiguity( BN_STRUCT *pBNS, int num_atoms ) -{ - int pass, i, v0, v1, v2, ineigh1, /*ineigh0,*/ /*ineigh2,*/ - vLast, n, delta, ret, err = 0; - int nFound, k; - BNS_EDGE *edge; - - for (pass = pBNS->num_altp - 1, ret = 0; 0 <= pass; pass--) - { - - pBNS->alt_path = pBNS->altp[pass]; - v1 = ALTP_START_ATOM( pBNS->alt_path ); - n = ALTP_PATH_LEN( pBNS->alt_path ); - delta = ALTP_DELTA( pBNS->alt_path ); - vLast = ALTP_END_ATOM( pBNS->alt_path ); - v0 = v2 = NO_VERTEX; /* negative number */ - - for (i = 0; i < n; i++, delta = -delta, v0 = v1, v1 = v2 /*, ineigh0 = ineigh1*/) - { - ineigh1 = ALTP_THIS_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v1->v2 neighbor */ - /*ineigh2 = ALTP_NEXT_ATOM_NEIGHBOR(pBNS->alt_path, i);*/ /* v2->v1 neighbor */ - edge = pBNS->edge + pBNS->vert[v1].iedge[ineigh1]; - /* follow the BN Structure, not the inp_ATOM, to take care of swithching to - t-groups, c-groups or other fictitious edges/vertices - */ - v2 = edge->neighbor12 ^ v1; - if (v1 < num_atoms && - ( (v0 >= num_atoms && ( pBNS->vert[v0].type & BNS_VERT_TYPE_C_GROUP )) || - (v2 >= num_atoms && ( pBNS->vert[v2].type & BNS_VERT_TYPE_C_GROUP ) ))) /* djb-rwth: addressing LLVM warning */ - { - int cgPos = 0, cgNeg = 0; - int neighPos = -1, neighNeg = -1; - BNS_EDGE *edgePos, *edgeNeg; - nFound = 0; - for (k = pBNS->vert[v1].num_adj_edges - 1; k >= 0 && ( neighPos < 0 || neighNeg < 0 ); k--) - { - BNS_EDGE *next_edge = pBNS->edge + pBNS->vert[v1].iedge[k]; - int v = next_edge->neighbor12 ^ v1; - if (pBNS->vert[v].type & BNS_VERT_TYPE_C_GROUP) - { - if (pBNS->vert[v].type & BNS_VERT_TYPE_C_NEGATIVE) - { - cgNeg = v; - neighNeg = k; - nFound++; - } - else - { - cgPos = v; - neighPos = k; - nFound++; - } - } - } - if (2 == nFound && neighPos >= 0 && neighNeg >= 0) - { - /* both c-groups have been found */ - edgePos = pBNS->edge + pBNS->vert[v1].iedge[neighPos]; - edgeNeg = pBNS->edge + pBNS->vert[v1].iedge[neighNeg]; - if (edgePos->flow < edgeNeg->flow) - { - /* ambiguity found; replace (+cg)--N==(-cg) with (+cg)==N--(-cg) */ - int dflow = edgeNeg->flow - edgePos->flow; - - edgePos->flow += dflow; - pBNS->vert[cgPos].st_edge.cap += dflow; - pBNS->vert[cgPos].st_edge.flow += dflow; - - edgeNeg->flow -= dflow; - pBNS->vert[cgNeg].st_edge.cap -= dflow; - pBNS->vert[cgNeg].st_edge.flow -= dflow; - ret++; - } - } - } - } - - if (v2 != vLast) - { - err = BNS_PROGRAM_ERR; - } - } - - return err ? err : ret; -} - - -/**************************************************************************** -Add or remove ixplicit or implicit hydrogens -****************************************************************************/ -int AddOrRemoveExplOrImplH( int nDelta, - inp_ATOM *at, - int num_atoms, - AT_NUMB at_no, - T_GROUP_INFO *t_group_info ) -{ - int i, iso, tot_num_iso_H, - num_H, /* number of H before the removal, including explicit H */ - nNum2Remove, /* number of H to remove */ - nNumRemovedExplicitH; /* djb-rwth: removing redundant variables */ - S_CHAR num_iso_H[NUM_H_ISOTOPES]; - inp_ATOM *at_H; - - if (!nDelta) - { - return 0; - } - /* add */ - if (nDelta > 0) - { - at[at_no].num_H += nDelta; - t_group_info->tni.nNumRemovedProtons--; - return nDelta; - } - /* remove */ - nNum2Remove = -nDelta; - nNumRemovedExplicitH = t_group_info->tni.nNumRemovedExplicitH; /* number of explicit H saved separately in - at[num_atoms+i], i=0..nNumRemovedExplicitH-1 */ - tot_num_iso_H = NUM_ISO_H( at, at_no ); - num_H = at[at_no].num_H; - /* - tot_num_iso_H = NUM_ISO_H(at,at_no); - num_H = at[at_no].num_H; - nNumAtomExplicitH = 0; - nNumRemovedExplicitH = t_group_info->tni.nNumRemovedExplicitH; - tot_num_explicit_iso_H = 0; - */ - - at_H = at + num_atoms; - memcpy(num_iso_H, at[at_no].num_iso_H, sizeof(num_iso_H)); - /* Remove all explicit H, otherwise a false stereo can occur. - Example: remove H(+) from the following substructure: - - H H - A / A / - >X==N(+) produces false stereogenic bond: >X==N - B \ B - H - - To avoid this effect all explicit H atoms must be removed - */ - - /* djb-rwth: removing redundant code */ - for (i = 0; i < nNumRemovedExplicitH; ) - { - if (at_H[i].neighbor[0] == at_no) - { - int m, k, orig_no = at_H[i].orig_at_number; - nNumRemovedExplicitH--; - /* djb-rwth: removing redundant code */ - if (nNumRemovedExplicitH > i) - { - inp_ATOM at_i = at_H[i]; - memmove(at_H + i, at_H + i + 1, sizeof(at_H[0]) * ((long long)nNumRemovedExplicitH - i)); /* djb-rwth: cast operator added */ - at_H[nNumRemovedExplicitH] = at_i; /* save removed H (for debugging purposes?) */ - } - /* Adjust 0D parities */ - if (at[at_no].sb_parity[0]) - { - for (m = 0; m < MAX_NUM_STEREO_BONDS && at[at_no].sb_parity[m]; m++) - { - if (at[at_no].sn_orig_at_num[m] == orig_no) - { - if (at[at_no].valence >= MIN_NUM_STEREO_BOND_NEIGH) - { - at[at_no].sn_ord[m] = k = ( at[at_no].sb_ord[m] == 0 ); - at[at_no].sn_orig_at_num[m] = at[(int) at[at_no].neighbor[k]].orig_at_number; - if (ATOM_PARITY_WELL_DEF( at[at_no].sb_parity[m] )) - { - at[at_no].sb_parity[m] = 3 - at[at_no].sb_parity[m]; - } - } - else - { - at[at_no].sn_ord[m] = -99; /* no sb neighbor exists anymore */ - at[at_no].sn_orig_at_num[m] = 0; - if (ATOM_PARITY_WELL_DEF( at[at_no].sb_parity[m] )) - { - int pnxt_atom, pinxt2cur, pinxt_sb_parity_ord; - if (0 < get_opposite_sb_atom( at, at_no, at[at_no].sb_ord[m], - &pnxt_atom, &pinxt2cur, &pinxt_sb_parity_ord )) - { - at[at_no].sb_parity[m] = - at[pnxt_atom].sb_parity[pinxt_sb_parity_ord] = AB_PARITY_UNDF; - } - } - } - } - } - } - /* do not increment i here: we have shifted next at_H[] element - to the ith position and decremented nNumRemovedExplicitH */ - } - else - { - i++; - } - } - - for (iso = -1; iso < NUM_H_ISOTOPES && 0 < nNum2Remove; iso++) - { - /* Each pass removes up to one H */ - if (iso < 0) - { - /* Try to remove non-isotopic */ - while (tot_num_iso_H < num_H && 0 < nNum2Remove) - { - /* Non-isotopic H exists */ - num_H--; - t_group_info->tni.nNumRemovedProtons++; - nNum2Remove--; - } - } - else - { - /* Remove isotopic */ - while (num_iso_H[iso] && num_H && 0 < nNum2Remove) - { - /* Isotopic H exists */ - num_H--; - num_iso_H[iso] --; - t_group_info->tni.nNumRemovedProtonsIsotopic[iso] ++; - t_group_info->tni.nNumRemovedProtons++; - nNum2Remove--; - } - } - } -#if ( bRELEASE_VERSION != 1 ) - if (nNum2Remove) - { - int stop = 1; /* Program error */ - } -#endif - if (nDelta + nNum2Remove < 0) - { - at[at_no].num_H = num_H; - memcpy(at[at_no].num_iso_H, num_iso_H, sizeof(at[0].num_iso_H)); - t_group_info->tni.nNumRemovedExplicitH = nNumRemovedExplicitH; - } - - return nDelta + nNum2Remove; -} - - -/****************************************************************************/ -int SubtractOrChangeAtHChargeBNS( BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - int nAtTypeTotals[], - S_CHAR *mark, - T_GROUP_INFO *t_group_info, - int bSubtract ) -{ - int pass, i, v0, v1, v2, ineigh1, /*ineigh2,*/ vLast, n, delta, ret, err = 0; - BNS_EDGE *edge; - int nDeltaH, nDeltaCharge; - int mask, type; /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - - for (pass = pBNS->num_altp - 1, ret = 0; 0 <= pass; pass--) - { - - pBNS->alt_path = pBNS->altp[pass]; - v1 = ALTP_START_ATOM( pBNS->alt_path ); - n = ALTP_PATH_LEN( pBNS->alt_path ); - delta = ALTP_DELTA( pBNS->alt_path ); - vLast = ALTP_END_ATOM( pBNS->alt_path ); - v0 = v2 = NO_VERTEX; - - for (i = 0; i < n; i++, delta = -delta, v0 = v1, v1 = v2) - { - ineigh1 = ALTP_THIS_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v1->v2 neighbor */ - /*ineigh2 = ALTP_NEXT_ATOM_NEIGHBOR(pBNS->alt_path, i);*/ /* v2->v1 neighbor */ - edge = pBNS->edge + pBNS->vert[v1].iedge[ineigh1]; - /* follow the BN Structure, not the inp_ATOM, to take care of swithching to - t-groups, c-groups or other fictitious edges/vertices - */ - v2 = edge->neighbor12 ^ v1; - if (v1 < num_atoms && ( v0 >= num_atoms || v2 >= num_atoms )) - { - nDeltaH = nDeltaCharge = 0; - if (v0 >= num_atoms) - { - /* delta(v0-v1) = -delta(v1-v2) along the alternating path */ - if (pBNS->vert[v0].type & BNS_VERT_TYPE_TGROUP) - { - nDeltaH -= delta; - } - else - { - if (pBNS->vert[v0].type & BNS_VERT_TYPE_C_GROUP) - { - nDeltaCharge += delta; - } - } - } - if (v2 >= num_atoms) - { - if (pBNS->vert[v2].type & BNS_VERT_TYPE_TGROUP) - { - nDeltaH += delta; - } - else - { - if (pBNS->vert[v2].type & BNS_VERT_TYPE_C_GROUP) - { - nDeltaCharge -= delta; - } - } - } - if (nDeltaH || nDeltaCharge) - { - if (bSubtract) - { - if (!mark[v1]) - { - /* first time the atom has been encountered: subtract */ - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ -#if ( FIX_NORM_BUG_ADD_ION_PAIR == 1 ) - type = GetAtomChargeType(at, v1, nAtTypeTotals, &mask, 2); -#else - type = GetAtomChargeType(at, v1, nAtTypeTotals, &mask, 1); -#endif - ret++; /* number of changed atoms */ - mark[v1] ++; - } - } - else - { - /* Change */ - at[v1].charge += nDeltaCharge; - if (nDeltaH) - { - AddOrRemoveExplOrImplH( nDeltaH, at, num_atoms, (AT_NUMB) v1, t_group_info ); - } - ret++; /* number of changed atoms */ - } - } - } - } - - if (v2 != vLast) - { - err = BNS_PROGRAM_ERR; - } - } - - return err ? err : ret; -} - - -/**************************************************************************** -Set Bonds From BnS Struct Flow -****************************************************************************/ -int SetBondsFromBnStructFlow( BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - int bChangeFlow0 ) -{ - int pass, i, v0, v1, v2, ineigh1, ineigh2, vLast, n, delta, ret, ret_val, err = 0; - BNS_EDGE *edge; - int bChangeFlowAdd; /* djb-rwth: removing redundant variables */ - int bChangeFlow = ( bChangeFlow0 & ~BNS_EF_SET_NOSTEREO ); - /* - bCheckMovingRad = (bChangeFlow & BNS_EF_ALTR_NS) == BNS_EF_ALTR_NS && - pBNS->tot_st_cap > pBNS->tot_st_flow; - */ - for (pass = pBNS->num_altp - 1, ret = 0; 0 <= pass; pass--) - { - pBNS->alt_path = pBNS->altp[pass]; - v1 = ALTP_START_ATOM( pBNS->alt_path ); - n = ALTP_PATH_LEN( pBNS->alt_path ); - delta = ALTP_DELTA( pBNS->alt_path ); - vLast = ALTP_END_ATOM( pBNS->alt_path ); - if (( bChangeFlow0 & BNS_EF_SET_NOSTEREO ) && - ( pBNS->vert[v1].st_edge.cap0 > pBNS->vert[v1].st_edge.flow0 || - pBNS->vert[vLast].st_edge.cap0 > pBNS->vert[vLast].st_edge.flow0 )) - { - /* djb-rwth: removing redundant code */ - bChangeFlowAdd = BNS_EF_SET_NOSTEREO; - ret |= 2; - } - else - { - bChangeFlowAdd = 0; - } - /* start vertex */ - if (( bChangeFlow & BNS_EF_CHNG_RSTR ) == BNS_EF_CHNG_RSTR) - { - /* Restore s-v1 edge flow to the BNS this pass input value */ - ; /*pBNS->vert[v1].st_edge.flow -= delta;*/ - } - else - { - if (( bChangeFlow & BNS_EF_SAVE_ALL ) == BNS_EF_SAVE_ALL) - { - if (v1 < num_atoms) - { - /* Will produce wrong result if called for v1 next time? */ - ret_val = SetAtomRadAndChemValFromVertexCapFlow( pBNS, at, v1 ); - if (ret_val < 0) - { - err = BNS_PROGRAM_ERR; - } - else - { - ret |= ( ret_val > 0 ); - } - } - /*pBNS->vert[v1].st_edge.flow0 = pBNS->vert[v1].st_edge.flow;*/ - } - } - - pBNS->vert[v1].st_edge.pass = 0; - - v0 = v2 = NO_VERTEX; - for (i = 0; i < n; i++, delta = -delta, v0 = v1, v1 = v2) - { - ineigh1 = ALTP_THIS_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v1->v2 neighbor */ - ineigh2 = ALTP_NEXT_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v2->v1 neighbor */ - edge = pBNS->edge + pBNS->vert[v1].iedge[ineigh1]; - /* follow the BN Structure, not the inp_ATOM, to take care of swithching to - t-groups, c-groups or other fictitious edges/vertices - */ - - v2 = edge->neighbor12 ^ v1; - - /* change at->chem_bonds_valence 2004-03-08 */ - if (( bChangeFlow & BNS_EF_CHNG_BONDS ) && v1 < num_atoms) - { - if (v0 >= num_atoms && v2 < num_atoms) - { - at[v1].chem_bonds_valence += delta; /* change in v1-v2 bond order */ - } - else - { - if (v0 < num_atoms && v2 >= num_atoms && v0 != NO_VERTEX) - { - at[v1].chem_bonds_valence -= delta; /* change in v0-v1 bond order */ - } - } - } - - if (!edge->pass) - { - continue; - } - - if (v1 < num_atoms && ineigh1 < at[v1].valence && - v2 < num_atoms && ineigh2 < at[v2].valence) - { - if (( bChangeFlow0 & BNS_EF_ALTR_NS ) == BNS_EF_ALTR_NS && - ( bChangeFlow0 & BNS_EF_SAVE_ALL ) == BNS_EF_SAVE_ALL) - { - /* 2004-07-02 special mode: save new ring bonds and mark as non-stereo non-ring bonds */ - if (at[v1].nRingSystem != at[v2].nRingSystem) - { - /* Non-ring bond (bridge) */ - bChangeFlowAdd = BNS_EF_ALTR_NS; - } - else - { - /* Ring bond */ - bChangeFlowAdd = 0; - } - } - /* Change bonds on the first pass only: in this case all flow correspond to the BNS output */ - ret_val = SetAtomBondType( edge, &at[v1].bond_type[ineigh1], &at[v2].bond_type[ineigh2], delta, bChangeFlow | bChangeFlowAdd ); - if (ret_val < 0) - { - err = BNS_PROGRAM_ERR; - } - else - { - ret |= ( ret_val > 0 ); - } - } - edge->pass = 0; - } - - if (v2 != vLast) - { - err = BNS_PROGRAM_ERR; - } - else - { - if (( bChangeFlow & BNS_EF_CHNG_RSTR ) == BNS_EF_CHNG_RSTR) - { - /* Restore v2-t edge flow to the BNS this pass input value */ - /* "+=" instead of "-=" explanation: delta must have same sign as at the last edge */ - ; /*pBNS->vert[v2].st_edge.flow += delta; */ - } - else - { - if (( bChangeFlow & BNS_EF_SAVE_ALL ) == BNS_EF_SAVE_ALL) - { - if (v2 < num_atoms) - { - ret_val = SetAtomRadAndChemValFromVertexCapFlow( pBNS, at, v2 ); - if (ret_val < 0) - { - err = BNS_PROGRAM_ERR; - } - else - { - ret |= ( ret_val > 0 ); - } - } - /*pBNS->vert[v2].st_edge.flow0 = pBNS->vert[v2].st_edge.flow;*/ - } - } - } - pBNS->vert[v2].st_edge.pass = 0; - } - - return err ? err : ret; -} - - -/****************************************************************************/ -int MarkAtomsAtTautGroups( BN_STRUCT *pBNS, - int num_atoms, - BN_AATG *pAATG, - int nEnd1, - int nEnd2 ) -{ - int pass, i, j, v1, v2, ineigh1, ineigh2, vLast, vFirst, n, delta, err = 0; /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ - BNS_EDGE *edge; - S_CHAR cDelta[MAX_ALT_AATG_ARRAY_LEN]; - AT_NUMB nVertex[MAX_ALT_AATG_ARRAY_LEN]; - int nLenDelta = 0, last_i, nNumFound; - - for (pass = pBNS->num_altp - 1; 0 <= pass; pass--) - { - pBNS->alt_path = pBNS->altp[pass]; - vFirst = - v1 = ALTP_START_ATOM( pBNS->alt_path ); - n = ALTP_PATH_LEN( pBNS->alt_path ); - delta = ALTP_DELTA( pBNS->alt_path ); - vLast = ALTP_END_ATOM( pBNS->alt_path ); - v2 = NO_VERTEX; - pAATG->nNumFound = 0; /* initialize */ - - if (nEnd1 != vFirst && nEnd1 != vLast) - { - nEnd1 = -1; /* really not the end */ - } - if (nEnd2 != vFirst && nEnd2 != vLast) - { - nEnd2 = -1; /* really not the end */ - } - - for (i = 0; i < n; i++, delta = -delta, v1 = v2) - { - ineigh1 = ALTP_THIS_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v1->v2 neighbor */ - ineigh2 = ALTP_NEXT_ATOM_NEIGHBOR(pBNS->alt_path, i); /* v2->v1 neighbor */ /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ - edge = pBNS->edge + pBNS->vert[v1].iedge[ineigh1]; - /* follow the BN Structure, not the inp_ATOM, to take care of swithching to - t-groups, c-groups or other fictitious edges/vertices - */ - v2 = edge->neighbor12 ^ v1; - /* - if ( v1 < num_atoms && v2 < num_atoms ) { - continue; - } - */ - /* BNS increased edge flow by delta */ - if (v1 >= num_atoms && - ( ( pBNS->vert[v1].type & BNS_VERT_TYPE_TGROUP ) || ( pBNS->vert[v1].type & BNS_VERT_TYPE_TEMP ) ) && - 0 <= v2 && v2 < num_atoms && ( pBNS->vert[v2].type & BNS_VERT_TYPE_ATOM )) - { - /* - if ( !(pAATG->nMarkedAtom[v2] & AATG_MARK_IN_PATH) ) { - pAATG->nMarkedAtom[v2] |= AATG_MARK_IN_PATH; - pAATG->nNumFound ++; - } - */ - - /* BNS increased bond order in v1(t-group)-v2(atom) by delta: added delta attachments */ - if (nLenDelta < MAX_ALT_AATG_ARRAY_LEN) - { - cDelta[nLenDelta] = delta; - nVertex[nLenDelta] = v2; - nLenDelta++; - } - } - else - { - if (v2 >= num_atoms && - ( ( pBNS->vert[v2].type & BNS_VERT_TYPE_TGROUP ) || ( pBNS->vert[v2].type & BNS_VERT_TYPE_TEMP ) ) && - 0 <= v1 && v1 < num_atoms && ( pBNS->vert[v1].type & BNS_VERT_TYPE_ATOM )) - { - /* - if ( !(pAATG->nMarkedAtom[v1] & AATG_MARK_IN_PATH) ) { - pAATG->nMarkedAtom[v1] |= AATG_MARK_IN_PATH; - pAATG->nNumFound ++; - } - */ - - /* BNS increased bond order in v1(atom)-v2(t-group) by delta: added delta attachments */ - if (nLenDelta < MAX_ALT_AATG_ARRAY_LEN) - { - cDelta[nLenDelta] = delta; - nVertex[nLenDelta] = v1; - nLenDelta++; - } - } - else - { - /* Special case when the testing 'dot' was placed on an atom (should be nEnd1 only) */ - if ((0 <= v1 && v1 == nEnd1) || (v1 == nEnd2 && 0 <= v2 && v2 < num_atoms)) /* djb-rwth: addressing LLVM warning */ - { - if (nLenDelta < MAX_ALT_AATG_ARRAY_LEN) - { - cDelta[nLenDelta] = -delta; - nVertex[nLenDelta] = v1; - nLenDelta++; - } - } - else - { - if ((0 <= v2 && v2 == nEnd1) || (v2 == nEnd2 && 0 <= v1 && v1 < num_atoms)) /* djb-rwth: addressing LLVM warning */ - { - if (nLenDelta < MAX_ALT_AATG_ARRAY_LEN) - { - cDelta[nLenDelta] = -delta; - nVertex[nLenDelta] = v2; - nLenDelta++; - } - } - } - } - } - } - - if (v2 != vLast) - { - err = BNS_PROGRAM_ERR; - } - else - { - last_i = -1; - nNumFound = 0; - /* first run */ - for (i = 1, j = 0; i < nLenDelta; j = i++) - { - /* Ignore sequences (-1,+1) and (+1,-1) in cDelta[] because they */ - /* describe ordinary aug. paths of moving a single attachment */ - /* we are looking for aug. paths describing movement of 2 or more */ - if ((cDelta[j] > 0 && cDelta[i] > 0) || - (cDelta[j] < 0 && cDelta[i] < 0)) /* djb-rwth: addressing LLVM warning */ - { - if (j == last_i) - { - /* Three attachments moved */ - return 0; - } - v1 = nVertex[j]; - if (!( pAATG->nMarkedAtom[v1] & AATG_MARK_IN_PATH )) - { - nNumFound++; - } - v2 = nVertex[i]; - if (!( pAATG->nMarkedAtom[v2] & AATG_MARK_IN_PATH )) - { - nNumFound++; - } - last_i = i; - } - } - if (!nNumFound) - { - return 0; - } - if (nNumFound > 4) - { - return 0; - } - if (nNumFound < 4) - { - return 0; - } - - /* Second run */ - for (i = 1, j = 0; i < nLenDelta; j = i++) - { - /* Ignore sequences (-1,+1) and (+1,-1) in cDelta[] because they */ - /* describe ordinary aug. paths of moving a single attachment */ - /* we are looking for aug. paths describing movement of 2 or more */ - if ((cDelta[j] > 0 && cDelta[i] > 0) || - (cDelta[j] < 0 && cDelta[i] < 0)) /* djb-rwth: addressing LLVM warning */ - { - v1 = nVertex[i - 1]; - if (!( pAATG->nMarkedAtom[v1] & AATG_MARK_IN_PATH )) - { - pAATG->nMarkedAtom[v1] |= AATG_MARK_IN_PATH; - pAATG->nNumFound++; - } - v2 = nVertex[i]; - if (!( pAATG->nMarkedAtom[v2] & AATG_MARK_IN_PATH )) - { - pAATG->nMarkedAtom[v2] |= AATG_MARK_IN_PATH; - pAATG->nNumFound++; - } - } - } - } - } - - return err ? err : pAATG->nNumFound; -} - - -/****************************************************************************/ -int RestoreBnStructFlow( BN_STRUCT *pBNS, int bChangeFlow ) -{ - int pass, i, v1, v2, ineigh1, ineigh2, vLast, n, delta, ret, err = 0; /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ - BNS_EDGE *edge; - - for (pass = pBNS->num_altp - 1, ret = 0; 0 <= pass; pass--) - { - pBNS->alt_path = pBNS->altp[pass]; - v1 = ALTP_START_ATOM( pBNS->alt_path ); - n = ALTP_PATH_LEN( pBNS->alt_path ); - delta = ALTP_DELTA( pBNS->alt_path ); - vLast = ALTP_END_ATOM( pBNS->alt_path ); - v2 = NO_VERTEX; - /* starting vertex */ - if (( bChangeFlow & BNS_EF_CHNG_RSTR ) == BNS_EF_CHNG_RSTR) - { - pBNS->vert[v1].st_edge.flow -= delta; /* restore s-v1 edge flow to the BNS input value */ - } - else - { - if (( bChangeFlow & BNS_EF_SAVE_ALL ) == BNS_EF_SAVE_ALL) - { - pBNS->vert[v1].st_edge.flow0 = pBNS->vert[v1].st_edge.flow; - } - } - - /* Augmenting path edges */ - for (i = 0; i < n; i++, delta = -delta, v1 = v2) - { - ineigh1 = ALTP_THIS_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v1->v2 neighbor */ - ineigh2 = ALTP_NEXT_ATOM_NEIGHBOR(pBNS->alt_path, i); /* v2->v1 neighbor */ /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ - edge = pBNS->edge + pBNS->vert[v1].iedge[ineigh1]; - v2 = edge->neighbor12 ^ v1; - RestoreEdgeFlow( edge, delta, bChangeFlow ); - edge->pass = 0; - } - - /* Ending vertex */ - if (v2 != vLast) - { - err = BNS_PROGRAM_ERR; - } - else - { - if (( bChangeFlow & BNS_EF_CHNG_RSTR ) == BNS_EF_CHNG_RSTR) - { - /* Restore v2-t edge flow to the original value */ - /* "+=" instead of "-=" explanation: delta must have same sign as at the last edge */ - pBNS->vert[v2].st_edge.flow += delta; - } - else - { - if (( bChangeFlow & BNS_EF_SAVE_ALL ) == BNS_EF_SAVE_ALL) - { - pBNS->vert[v2].st_edge.flow0 = pBNS->vert[v2].st_edge.flow; - } - } - } - } - - return err ? err : ret; -} - - -/****************************************************************************/ -int bNeedToTestTheFlow( int bond_type, - int nTestFlow, - int bTestForNonStereoBond ) -{ - int nBondType = ( BOND_TYPE_MASK & bond_type ); - int nBondAttrib = ( BOND_MARK_MASK & bond_type ); - - if (bTestForNonStereoBond) - { - if (nBondAttrib || nBondType == BOND_ALTERN || nBondType == BOND_ALT12NS) - { - switch (nTestFlow) - { - case 0: /* single: can be 1 (single)? */ - if (nBondAttrib == BOND_MARK_ALT12NS || - nBondAttrib == BOND_MARK_ALT123 || - nBondAttrib == BOND_MARK_ALT13) - { - return 0; /* yes, already checked */ - } - break; - - case 1: /* double: can be 2 (double)? */ - if (nBondAttrib == BOND_MARK_ALT12NS || - nBondAttrib == BOND_MARK_ALT123 || - nBondAttrib == BOND_MARK_ALT23) - { - return 0; /* yes, already checked */ - } - break; - case 2: /* triple: can be 3 (triple)? */ - if (nBondAttrib == BOND_MARK_ALT13 || - nBondAttrib == BOND_MARK_ALT123 || - nBondAttrib == BOND_MARK_ALT23) - { - return 0; /* yes, already checked */ - } - break; - } - } - } - else - { - if (nBondAttrib || nBondType == BOND_ALTERN || nBondType == BOND_ALT12NS) - { - switch (nTestFlow) - { - case 0: /* single: can be 1 (single)? */ - if (nBondAttrib == BOND_MARK_ALT12 || - nBondAttrib == BOND_MARK_ALT12NS || - nBondAttrib == BOND_MARK_ALT123 || - nBondAttrib == BOND_MARK_ALT13) - { - return 0; - } - break; - - case 1: /* double: can be 2 (double)? */ - if (nBondAttrib == BOND_MARK_ALT12 || - nBondAttrib == BOND_MARK_ALT12NS || - nBondAttrib == BOND_MARK_ALT123 || - nBondAttrib == BOND_MARK_ALT23) - { - return 0; /* yes */ - } - break; - case 2: /* triple: can be 3 (triple)? */ - if (nBondAttrib == BOND_MARK_ALT13 || - nBondAttrib == BOND_MARK_ALT123 || - nBondAttrib == BOND_MARK_ALT23) - { - return 0; - } - break; - } - } - } - - return 1; -} - - -/****************************************************************************/ -int nBondsValenceInpAt( const inp_ATOM *at, - int *nNumAltBonds, - int *nNumWrongBonds ) -{ - int j, bond_type, nBondsValence = 0, nAltBonds = 0, nNumWrong = 0; - for (j = 0; j < at->valence; j++) - { - bond_type = at->bond_type[j] & BOND_TYPE_MASK; - switch (bond_type) - { - case 0: /* for structure from InChI reconstruction */ - case BOND_SINGLE: - case BOND_DOUBLE: - case BOND_TRIPLE: - nBondsValence += bond_type; - break; - case BOND_ALTERN: - nAltBonds++; - break; - default: - nNumWrong++; - } - } - switch (nAltBonds) - { - case 0: - break; - case 1: - nBondsValence += 1; /* 1 or greater than 3 is wrong */ - nNumWrong++; - break; - default: - nBondsValence += nAltBonds + 1; - break; - } - if (nNumAltBonds) - { - *nNumAltBonds = nAltBonds; - } - if (nNumWrongBonds) - { - *nNumWrongBonds = nNumWrong; - } - - return nBondsValence; -} - - -/**************************************************************************** -If radical or has aromatic bonds, -then augment to the lowest "multiplicity" -****************************************************************************/ -int BnsAdjustFlowBondsRad( BN_STRUCT *pBNS, - BN_DATA *pBD, - inp_ATOM *at, - int num_atoms ) -{ - int bError = 0, nOrigDelta = 0, ret, num_removed; - -#if( CHECK_AROMBOND2ALT == 1 ) - int *pcValMinusBondsVal = NULL; - int i, nValMinusBondsVal, nAltBonds, bIgnore, valen, is_rad, excess; - - /* Find valence excess (it may only be due to aromatic bonds) */ - for (i = 0; i < num_atoms; i++) - { - valen = nBondsValenceInpAt( at + i, &nAltBonds, &bIgnore ); - nValMinusBondsVal = (int) at[i].chem_bonds_valence - valen; - bIgnore += ( nAltBonds > 3 ); - if (!bIgnore && nValMinusBondsVal > 0) - { - if (!pcValMinusBondsVal && - !( pcValMinusBondsVal = (int *) inchi_calloc( num_atoms, sizeof( pcValMinusBondsVal[0] ) ) )) - { - bError = BNS_OUT_OF_RAM; - goto exit_function; - } - /* Mark atoms that have extra unsatisfied valence due to aromatic bonds */ - is_rad = ( at[i].radical == RADICAL_DOUBLET ); - excess = nValMinusBondsVal + is_rad; - pcValMinusBondsVal[i] = excess; - } - } -#endif /* CHECK_AROMBOND2ALT */ - - /* Match bonds to valences */ - do - { - num_removed = 0; - ret = RunBalancedNetworkSearch( pBNS, pBD, BNS_EF_CHNG_FLOW ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - else - { - nOrigDelta += ret; - num_removed = pBNS->num_altp; /* number of augmenting paths */ - if (ret > 0) - { - /* save new bonds in at[] and flows in pBNS and at[] */ - ret = SetBondsFromBnStructFlow( pBNS, at, num_atoms, BNS_EF_SAVE_ALL ); /* must include 1: 5=(4|1) */ - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - ret = RestoreBnStructFlow( pBNS, BNS_EF_SAVE_ALL ); /* must include 1: 5=(4|1) */ - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - } - ReInitBnStructAltPaths( pBNS ); - } - } while (num_removed && num_removed == pBNS->max_altp && !bError); - -#if( CHECK_AROMBOND2ALT == 1 ) - /* Check whether aromatic bonds have been replaced with alternating bonds */ - if (!bError && pcValMinusBondsVal) - { - for (i = 0; i < num_atoms; i++) - { - if (!pcValMinusBondsVal[i]) - { - continue; - } - valen = nBondsValenceInpAt( at + i, &nAltBonds, &bIgnore ); - nValMinusBondsVal = (int) at[i].chem_bonds_valence - valen; - is_rad = ( at[i].radical == RADICAL_DOUBLET ); - excess = nValMinusBondsVal + is_rad; - if (bIgnore || - ( pcValMinusBondsVal[i] - excess ) != 1) - { - /* radical excess has not been reduced */ - bError = BNS_ALTBOND_ERR; - break; - } - } - } - -exit_function: - if (pcValMinusBondsVal) - { - inchi_free( pcValMinusBondsVal ); - } -#endif /* CHECK_AROMBOND2ALT */ - - return bError ? bError : nOrigDelta; -} - - -/****************************************************************************/ -int BnsTestAndMarkAltBonds( BN_STRUCT *pBNS, - BN_DATA *pBD, - inp_ATOM *at, - int num_atoms, - BNS_FLOW_CHANGES *fcd, - int bChangeFlow, - int nBondTypeToTest ) -{ - int ret, iat, ineigh, neigh; - int nMinFlow, nMaxFlow, nTestFlow, nCurFlow; - int iedge, bError, nDots, nChanges, bTestForNonStereoBond; /* djb-rwth: removing redundant variables */ - - /* Normalize bonds and find tautomeric groups */ - bError = 0; - nChanges = 0; - bTestForNonStereoBond = pBNS->tot_st_cap > pBNS->tot_st_flow; - - for (iat = 0; iat < num_atoms && !bError; iat++) - { - for (ineigh = 0; ineigh < at[iat].valence && !bError; ineigh++) - { - neigh = at[iat].neighbor[ineigh]; - if (neigh < iat) - { - continue; /* we have already tested the bond */ - } - iedge = pBNS->vert[iat].iedge[ineigh]; - if (IS_FORBIDDEN( pBNS->edge[iedge].forbidden, pBNS )) - { - continue; - } - if (nBondTypeToTest && ( at[iat].bond_type[ineigh] & BOND_TYPE_MASK ) != nBondTypeToTest) - { - continue; - } - nMinFlow = nMinFlow2Check( pBNS, iedge ); - nMaxFlow = nMaxFlow2Check( pBNS, iedge ); - nCurFlow = nCurFlow2Check( pBNS, iedge ); - if (nMinFlow == nMaxFlow) - { - if (nMaxFlow && bTestForNonStereoBond) - { - nTestFlow = nMaxFlow - (int) ( pBNS->tot_st_cap - pBNS->tot_st_flow ); /* temporary use of nTestFlow */ - nMinFlow = inchi_max( 0, nTestFlow ); - } - else - { - continue; - } - } - for (nTestFlow = nMinFlow; nTestFlow <= nMaxFlow && !bError; nTestFlow++) - { - if (nTestFlow == nCurFlow) - { - continue; - } - if (!bNeedToTestTheFlow( at[iat].bond_type[ineigh], nTestFlow, bTestForNonStereoBond )) - { - continue; - } - /* djb-rwth: removing redundant code */ - nDots = bSetFlowToCheckOneBond( pBNS, iedge, nTestFlow, fcd ); - - if (IS_BNS_ERROR( nDots )) - { - if (nDots == BNS_CANT_SET_BOND) - { - ret = bRestoreFlowAfterCheckOneBond( pBNS, fcd ); - if (!IS_BNS_ERROR( ret )) - { - continue; - } - } - bError = nDots; - } - else - { - if (nDots > 0) - { - ret = RunBalancedNetworkSearch( pBNS, pBD, bChangeFlow ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - else - { - if (ret > 0) - { - if (2 * ret == nDots) - { - ret = bSetBondsAfterCheckOneBond( pBNS, fcd, nTestFlow, at, num_atoms, bChangeFlow ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - else - { - nChanges += ( ret & 1 ); - ret = SetBondsFromBnStructFlow( pBNS, at, num_atoms, bChangeFlow ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - else - { - if (ret >= 0) - { - nChanges += ( ret & 1 ); - /* djb-rwth: removing redundant code */ - } - else - { - bError = ret; - } - } - } - } - /* typically 2*ret < nDots; 2*ret > nDots should not happen. Check later */ - ret = RestoreBnStructFlow( pBNS, bChangeFlow & BNS_EF_CHNG_RSTR ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - } - } - /* --- Reinitialize to repeat the calculations --- */ - ReInitBnStructAltPaths( pBNS ); - } - - else - { - if (nDots == 0) - { - ret = bSetBondsAfterCheckOneBond( pBNS, fcd, nTestFlow, at, num_atoms, bChangeFlow ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - else - { - nChanges += ( ret & 1 ); - } - } - } - } - - ret = bRestoreFlowAfterCheckOneBond( pBNS, fcd ); - - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - - } /* for (nTestFlow = */ - } /* for (ineigh = */ - } /* for (iat = */ - - return bError ? bError : nChanges; -} - - -/****************************************************************************/ -static void remove_alt_bond_marks( inp_ATOM *at, int num_atoms ) -{ - int i, j, val; - for (i = 0; i < num_atoms; i++) - { - for (val = at[i].valence, j = 0; j < val; j++) - { - at[i].bond_type[j] &= BOND_TYPE_MASK; - } - } - -} - - -/****************************************************************************/ -int SetForbiddenEdges( BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - int forbidden_mask, - int nebend, - int *ebend ) -{ - - - int i, j, neigh, num_found; - BNS_IEDGE iedge; - /*S_CHAR edge_forbidden_mask = BNS_EDGE_FORBIDDEN_MASK;*/ - S_CHAR edge_forbidden_mask = forbidden_mask; - - pBNS->edge_forbidden_mask |= forbidden_mask; - - num_found = 0; - - for (i = 0; i < num_atoms; i++) - { - /* acetyl */ - if (at[i].el_number == EL_NUMBER_C && 3 == at[i].valence && - 4 == at[i].chem_bonds_valence) - { - int num_O = 0; - int bond_to_O_val = 0; - int forbidden_bond_pos = -1; - int forbidden_bond_val = -1; - for (j = 0; j < at[i].valence; j++) - { - neigh = at[i].neighbor[j]; - if (at[neigh].el_number == EL_NUMBER_O && - at[neigh].valence == 1) - { - num_O++; - bond_to_O_val += ( at[i].bond_type[j] & BOND_TYPE_MASK ); - } - else - { - forbidden_bond_pos = j; - forbidden_bond_val = ( at[i].bond_type[j] & BOND_TYPE_MASK ); - } - } - if (2 == num_O && 3 == bond_to_O_val && 1 == forbidden_bond_val) - { - iedge = pBNS->vert[i].iedge[forbidden_bond_pos]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_found++; - } - } - else - { - /* nitro */ - if (at[i].el_number == EL_NUMBER_N && 3 == at[i].valence && - ( 4 == at[i].chem_bonds_valence || 5 == at[i].chem_bonds_valence )) - { - int num_O = 0; - int bond_to_O_val = 0; - int forbidden_bond_pos = -1; - int forbidden_bond_val = -1; - for (j = 0; j < at[i].valence; j++) - { - neigh = at[i].neighbor[j]; - if (at[neigh].el_number == EL_NUMBER_O && - at[neigh].valence == 1) - { - num_O++; - bond_to_O_val += ( at[i].bond_type[j] & BOND_TYPE_MASK ); - } - else - { - forbidden_bond_pos = j; - forbidden_bond_val = ( at[i].bond_type[j] & BOND_TYPE_MASK ); - } - } - if (2 == num_O && ( 3 == bond_to_O_val || 4 == bond_to_O_val ) && 1 == forbidden_bond_val) - { - iedge = pBNS->vert[i].iedge[forbidden_bond_pos]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_found++; - } - } - } - } - -#ifdef FIX_SRU_CYCLIZING_PS_BONDS_IN_BNS - if (nebend > 1) - num_found += fix_explicitly_indicated_bonds( nebend, ebend, pBNS, at, num_atoms ); -#endif - -#if ( REMOVE_ION_PAIRS_FIX_BONDS == 1 ) - num_found += fix_special_bonds( pBNS, at, num_atoms, edge_forbidden_mask ); -#endif -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - num_found += TempFix_NH_NH_Bonds( pBNS, at, num_atoms ); -#endif - - return num_found; -} - - - -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - - -/****************************************************************************/ -int TempFix_NH_NH_Bonds( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms ) -{ - int i, j, neigh, num_found; - BNS_IEDGE iedge; - S_CHAR edge_forbidden_mask = BNS_EDGE_FORBIDDEN_TEMP; - for (i = 0, num_found = 0; i < num_atoms; i++) - { - /* -NH-NH- or -NH-NH3 */ - if (at[i].el_number == EL_NUMBER_N && at[i].valence < 3 && at[i].num_H && - 3 == at[i].chem_bonds_valence + at[i].num_H && - at[i].chem_bonds_valence == at[i].valence && - !at[i].charge && !at[i].radical) - { - for (j = 0; j < at[i].valence; j++) - { - neigh = at[i].neighbor[j]; - if (neigh < i && - at[neigh].el_number == EL_NUMBER_N && at[neigh].valence < 3 && at[neigh].num_H && - 3 == at[neigh].chem_bonds_valence + at[neigh].num_H && - at[neigh].chem_bonds_valence == at[neigh].valence && - !at[neigh].charge && !at[neigh].radical) - { - iedge = pBNS->vert[i].iedge[j]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_found++; - } - } - } - } - - return num_found; -} - - -/****************************************************************************/ -int CorrectFixing_NH_NH_Bonds( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms ) -{ - int i, j, neigh, num_found; - BNS_IEDGE iedge; - S_CHAR edge_forbidden_mask = BNS_EDGE_FORBIDDEN_TEMP; - - for (i = 0, num_found = 0; i < num_atoms; i++) - { - /* -NH-NH- or -NH-NH3 */ - if (at[i].el_number == EL_NUMBER_N && at[i].valence < 3) - { - for (j = 0; j < at[i].valence; j++) - { - neigh = at[i].neighbor[j]; - if (neigh < i && - at[neigh].el_number == EL_NUMBER_N && at[neigh].valence < 3) - { - if (BOND_TYPE_SINGLE != ( at[i].bond_type[j] & BOND_TYPE_MASK )) - { - iedge = pBNS->vert[i].iedge[j]; - if (pBNS->edge[iedge].forbidden & edge_forbidden_mask) - { - pBNS->edge[iedge].forbidden &= ~edge_forbidden_mask; - num_found++; - } - } - } - } - } - } - - return num_found; -} -#endif - -/**************************************************************************** -Fixes bonds which were set by remove_ion_pairs( ... ) -****************************************************************************/ -int fix_special_bonds( BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - int forbidden_mask ) -{ - int num_changes = 0; - -#define MAX_NEIGH 6 - - int i, k, n1, n2, n3, i1, i2, i3, i4, bond_type; /* djb-rwth: removing redundant variables */ - inp_ATOM *a; - int j[3], m[3], num_O, k_O, num_N, num_OH, num_OM, num_X, num_other, k_N; - - BNS_IEDGE iedge; - /*S_CHAR edge_forbidden_mask = BNS_EDGE_FORBIDDEN_MASK;*/ - S_CHAR edge_forbidden_mask = forbidden_mask; - - pBNS->edge_forbidden_mask |= edge_forbidden_mask; - - for (i = 0, a = at; i < num_atoms; i++, a++) - { - - if (!a->charge && !a->radical && - 2 <= a->chem_bonds_valence + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && - 0 == num_of_H( at, i ) && - 2 == nNoMetalBondsValence( at, i ) + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && - ion_el_group( at[i].el_number ) == EL_NUMBER_N ) - { - /* Found N(V), no H */ - if (2 == nNoMetalNumBonds( at, i )) - { - /* #N= */ - /* fix bonds: double and triple: =N# so that bonds cannot be changed by the normalization */ -#if ( FIX_N_V_METAL_BONDS_GPF == 1 ) - if (0 > ( i1 = nNoMetalNeighIndex( at, i ) ) || - 0 > ( i2 = nNoMetalOtherNeighIndex( at, i, n1 = a->neighbor[i1]/* non-metal neighbor #1 */ ) )) - { - /*num_err ++; */ /* do not count would-be original InChI v.1 buffer overflow GPF */ - continue; /* v1 bug: 2 bonds to metal yield i1 < 0 and/or i2 < 0 => bounds violation */ - } -#else - i1 = nNoMetalNeighIndex( at, i ); - n1 = a->neighbor[i1]; /* non-metal neighbor #1 */ - i2 = nNoMetalOtherNeighIndex( at, i, n1 ); -#endif - n2 = a->neighbor[i2]; /* non-metal neighbor #2 */ - /* forbid all edges to non-metals */ - iedge = pBNS->vert[i].iedge[i1]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; /* fix bond to neighbor #1 */ - iedge = pBNS->vert[i].iedge[i2]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; /* fix bond to neighbor #1 */ - num_changes++; /* added 11-15-2005 */ - /* i n3 */ - /* forbid single bond edge beyond the neighboring =N- as in #N=N- */ - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - if (( at[i].bond_type[i1] & BOND_TYPE_MASK ) == BOND_TYPE_DOUBLE) - { - i3 = i1; /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - n3 = n1; - } - else - { - i3 = i2; /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - n3 = n2; - } - if (0 == NUMH( at, n3 ) && 2 == nNoMetalNumBonds( at, n3 ) && - 3 == nNoMetalBondsValence( at, n3 ) && - ion_el_group( at[n3].el_number ) == EL_NUMBER_N && - 0 <= ( k = nNoMetalOtherNeighIndex( at, n3, i ) )) - { - /* found =N- ; forbid the edge*/ - iedge = pBNS->vert[n3].iedge[k]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - } - } - else if (3 == nNoMetalNumBonds( at, i ) && - /* | */ - /* found =N= */ - /* locate all non-metal neighbors */ - 0 <= ( j[0] = nNoMetalNeighIndex( at, i ) ) && - 0 <= ( j[1] = nNoMetalOtherNeighIndex( at, i, m[0] = a->neighbor[j[0]] ) ) && - 0 <= ( j[2] = nNoMetalOtherNeighIndex2( at, i, m[0], m[1] = a->neighbor[j[1]] ) )) - { - /* Count specific neighbors: N(V)=N, N(V)-N N(V)=O, and N(V)-N */ - - /* if there is a single neighbor connected by a double bond, namely - N(V)=N and/or N(V)=O, then fix the bond(s). - If N(V)=O was fixed then do not fix another bond */ - m[2] = a->neighbor[j[2]]; - num_O = num_N = 0; - for (k = 0; k < 3; k++) - { - n1 = m[k]; - i1 = j[k]; /* djb-rwth: ignoring LLVM warning: variable used */ - if (ion_el_group( at[n1].el_number ) == EL_NUMBER_N) - { - k_N = k; - num_N++; - } - else if (ion_el_group( at[n1].el_number ) == EL_NUMBER_O && - 1 == nNoMetalNumBonds( at, n1 )) - { - k_O = k; - num_O++; - } - } - num_other = 0; - if (1 == num_O && - 0 == at[n1 = m[k_O]].charge && - 0 == at[n1].radical && - BOND_TYPE_DOUBLE == ( at[i].bond_type[i1 = j[k_O]] & BOND_TYPE_MASK ) - ) - { - /* Fix bond to neighbor =O */ - iedge = pBNS->vert[i].iedge[i1]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - num_other++; /* indicator: double to a terminal O has been fixed */ - } - if (!num_other && - num_O <= 1 && - 1 == num_N && - 0 == at[n1 = m[k_N]].charge && - 0 == at[n1].radical && - BOND_TYPE_DOUBLE == ( at[i].bond_type[i1 = j[k_N]] & BOND_TYPE_MASK )) - { - /* Fix bond to neighbor =N */ - iedge = pBNS->vert[i].iedge[i1]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - } - } - else if (4 == nNoMetalNumBonds( at, i )) - { - /* | */ - /* found -N=N- */ - /* | */ - /* locate non-metal neighbor connected by a double bond; - * if it is =N- then fix the double bond and the single bond beyond the neighbor - */ - num_N = 0; - num_other = 0; /* djb-rwth: ignoring LLVM warning: variable used */ - for (i1 = 0; i1 < at[i].valence; i1++) - { - if (BOND_TYPE_DOUBLE == ( at[i].bond_type[i1] & BOND_TYPE_MASK ) && - !is_el_a_metal( at[n1 = (int) at[i].neighbor[i1]].el_number ) && - ion_el_group( at[n1].el_number ) == EL_NUMBER_N) - { - num_N++; - n2 = n1; - i2 = i1; - } - } - if (1 == num_N && 0 == NUMH( at, n2 ) && - 2 == nNoMetalNumBonds( at, n2 ) && - 3 == nNoMetalBondsValence( at, n2 ) && - 0 <= ( i3 = nNoMetalOtherNeighIndex( at, n2, i ) ) && - BOND_TYPE_SINGLE == ( at[n2].bond_type[i3] & BOND_TYPE_MASK )) - { - /* fix the single bond beyond the N(V) neighbor N(V)=N- */ - iedge = pBNS->vert[n2].iedge[i3]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - /* fix the double bond */ - iedge = pBNS->vert[i].iedge[i2]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - } - } - } - - else if (!a->charge && !a->radical && - 2 <= a->chem_bonds_valence + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && - 0 == num_of_H( at, i ) && - 2 == nNoMetalBondsValence( at, i ) + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && - a->el_number != EL_NUMBER_O && ion_el_group( a->el_number ) == EL_NUMBER_O && - 3 == nNoMetalNumBonds( at, i )) - { - /* Found S(IV), no H, one double bond, total 3 bonds */ - /* OH - / - in O=S (X != O) fix single bond O-X (type 1) - \ - X - - X - / - in Z=S (X, Y != OH) fix double bond Z=S (type 2) - \ - Y - */ - num_N = 0; /* number of non-metal neighbors connected by a double bond */ - num_OH = 0; /* number of neighbors OH connected by a single bond */ - num_OM = 0; /* number of charged neighbors O connected by a single bond */ - num_O = 0; /* number of neighbors =O connected by a double bond */ - num_other = 0; - - for (i1 = 0; i1 < a->valence; i1++) - { - n1 = (int) a->neighbor[i1]; - if (is_el_a_metal( at[n1].el_number )) - { - continue; - } - - bond_type = ( a->bond_type[i1] & BOND_TYPE_MASK ); - - if (BOND_TYPE_DOUBLE == bond_type) - { - num_N++; - n2 = n1; - i2 = i1; - if (ion_el_group( at[n1].el_number ) == EL_NUMBER_O) - { - num_O++; - } - } - else if (BOND_TYPE_SINGLE == bond_type && - 1 == nNoMetalNumBonds( at, n1 ) && - 1 == nNoMetalBondsValence( at, n1 ) && - ion_el_group( at[n1].el_number ) == EL_NUMBER_O) - { - if (0 == at[n1].charge) - { - num_OH++; - n3 = n1; - i3 = i1; /* djb-rwth: ignoring LLVM warning: variable used */ - } - else - { - num_OM++; - } - } - else - { - num_other++; - /* djb-rwth: removing redundant code */ - i4 = i1; - } - } /* for (i1 = */ - - if (1 == num_N && 1 == num_O && 1 == num_OH + num_OM) - { - if (1 == num_other) - { - /* type 1: fix the single bond S-X */ - iedge = pBNS->vert[i].iedge[i4]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - } - } - else if (1 == num_N && !num_OH && !num_OM) - { - int bFound = 0; /* flag */ - int bDoNotFixAnyBond = 0; /* flag */ - /* Avoid case N=S-NH or N=S-N(-); N = N, P, As, Sb */ - if (ion_el_group( at[n2].el_number ) == EL_NUMBER_N) - { - U_CHAR el_number = at[n2].el_number; - for (i1 = 0; i1 < a->valence; i1++) - { - n1 = (int) a->neighbor[i1]; - bond_type = ( a->bond_type[i1] & BOND_TYPE_MASK ); - if (BOND_TYPE_SINGLE == bond_type && - ( NUMH( at, n1 ) || -1 == at[n1].charge ) && - el_number == at[n1].el_number) - { - i3 = i1; /* djb-rwth: ignoring LLVM warning: variable used */ - n3 = n1; - bFound++; - } - } - } - /* Exception: check if Z==X and they belong to the same ring system */ - for (i1 = 0; i1 < a->valence; i1++) - { - if (i1 != i2) - { - n1 = (int) a->neighbor[i1]; - if (at[n2].el_number == at[n1].el_number && - at[n2].nRingSystem == at[n1].nRingSystem) - { - bDoNotFixAnyBond++; - } - } - } - if (bDoNotFixAnyBond) - { - ; /* do nothing */ - } - else if (bFound) - { - if (1 == bFound && - 0 <= ( i4 = nNoMetalOtherNeighIndex2( at, i, n2, n3 ) )) - { - /* fix bond i4 */ - iedge = pBNS->vert[i].iedge[i4]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - } - } - else - { - /* fix the double bond >S=X */ - iedge = pBNS->vert[i].iedge[i2]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - /* -- test later -- - if ( 2 == nNoMetalNumBonds( at, n2 ) && - 0 <= ( i3 = nNoMetalOtherNeighIndex( at, n2, i ) ) ) { - iedge = pBNS->vert[n2].iedge[i3]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes ++; - } - -------------------*/ - } - } - } - - else if (!a->charge && !a->radical && - 4 <= a->chem_bonds_valence + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && - 0 == num_of_H( at, i ) && - 4 == nNoMetalBondsValence( at, i ) + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && - a->el_number != EL_NUMBER_O && ion_el_group( a->el_number ) == EL_NUMBER_O && - 4 == nNoMetalNumBonds( at, i )) - { - /* Found S(VI), no H, two double bonds or one triple bond */ - /* O - || - in O=S--Y- (X, Y -- non-terminal) fix single bonds S-X, S-Y (type 1) - \ - X-- - - O - || - in O=S--O(-) (X -- non-terminal) fix single bond S-X (type 2) - \ - X-- - - O - || - in O=S--OH (X -- non-terminal) fix single bond S-X (type 3) - \ - X-- - - */ - int iN[4]; /* indexes of non-terminal neighbors connected by a single bond */ - num_N = 0; /* number of non-metal neighbors connected by a double bond */ - num_OH = 0; /* number of neighbors OH connected by a single bond */ - num_OM = 0; /* number of non-terminal neighbors connected by a single bond */ - num_O = 0; /* number of neighbors =O connected by a double bond */ - num_X = 0; /* number of terminal atom X != O connected by a single bond */ - num_other = 0; - for (i1 = 0; i1 < a->valence; i1++) - { - n1 = (int) a->neighbor[i1]; - if (is_el_a_metal( at[n1].el_number )) - { - continue; - } - bond_type = ( a->bond_type[i1] & BOND_TYPE_MASK ); - if (BOND_TYPE_DOUBLE == bond_type) - { - num_N++; - if (( 0 == at[n1].charge -#if ( S_VI_O_PLUS_METAL_FIX_BOND == 1 ) - || (1 == at[n1].charge && 2 == at[n1].valence) /* djb-rwth: addressing LLVM warning */ -#endif - ) && - 0 == at[n1].radical && - 0 == num_of_H( at, n1 ) && - ion_el_group( at[n1].el_number ) == EL_NUMBER_O && - 1 == nNoMetalNumBonds( at, n1 )) - { - num_O++; - } - } - else if (BOND_TYPE_SINGLE == bond_type && - 1 == nNoMetalNumBonds( at, n1 ) && - ion_el_group( at[n1].el_number ) == EL_NUMBER_O && - 1 >= num_of_H( at, n1 ) && - 1 == ( ( 0 == at[n1].charge ) && 1 == num_of_H( at, n1 ) ) - + ( ( -1 == at[n1].charge ) && 0 == num_of_H( at, n1 ) )) - { - num_OH++; /* -OH or -O(-) */ - } - else if (BOND_TYPE_SINGLE == bond_type && - 1 < nNoMetalNumBonds( at, n1 )) - { - iN[num_OM++] = i1; /* non-terminal neighbor connected by a single bond */ - } - else if (BOND_TYPE_SINGLE == bond_type && - 1 == nNoMetalNumBonds( at, n1 )) - { - num_X++; /* other terminal neighbor connected by a single bond */ - } - else - { - num_other++; - } - } - if (num_N == num_O && 2 == num_O && 2 == num_OH + num_OM + num_X && 0 == num_other) - { - for (i2 = 0; i2 < num_OM; i2++) - { - i1 = iN[i2]; - /* fix bond i1 */ - iedge = pBNS->vert[i].iedge[i1]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - } - } - } - - else if (!a->charge && !a->radical && - 6 <= a->chem_bonds_valence + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && - 0 == num_of_H( at, i ) && - 6 == nNoMetalBondsValence( at, i ) + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && - a->el_number != EL_NUMBER_O && ion_el_group( a->el_number ) == EL_NUMBER_O && - 5 == nNoMetalNumBonds( at, i )) - { - /* Found S(VIII), no H, three double bonds or two triple bond */ - /* - - O - || - in O=S--Y-- (X, Y -- non-terminal) fix single bond S-X, S-Y (type 4) - //\ - O X-- - - note: this structure is a mistakenly drawn structure - - O O - || || - O=S--O--Y-- or O=S--Y-- - \ \ - X-- O--X-- - - - */ - int iN[5]; /* indexes of non-terminal neighbors connected by a single bond */ - num_N = 0; /* number of non-metal neighbors connected by a double bond */ - num_OH = 0; /* number of neighbors OH connected by a single bond */ - num_OM = 0; /* number of non-terminal neighbors connected by a single bond */ - num_O = 0; /* number of neighbors =O connected by a double bond */ - num_X = 0; /* number of terminal atom X != O connected by a single bond */ - num_other = 0; - for (i1 = 0; i1 < a->valence; i1++) - { - n1 = (int) a->neighbor[i1]; - if (is_el_a_metal( at[n1].el_number )) - { - continue; - } - bond_type = ( a->bond_type[i1] & BOND_TYPE_MASK ); - if (BOND_TYPE_DOUBLE == bond_type) - { - num_N++; - if (( 0 == at[n1].charge -#if ( S_VI_O_PLUS_METAL_FIX_BOND == 1 ) - || (1 == at[n1].charge && 2 == at[n1].valence) /* djb-rwth: addressing LLVM warning */ -#endif - ) - && 0 == at[n1].radical && - 0 == num_of_H( at, n1 ) && - ion_el_group( at[n1].el_number ) == EL_NUMBER_O && - 1 == nNoMetalNumBonds( at, n1 )) - { - num_O++; - } - } - else if (BOND_TYPE_SINGLE == bond_type && - 1 == nNoMetalNumBonds( at, n1 ) && - ion_el_group( at[n1].el_number ) == EL_NUMBER_O && - 1 >= num_of_H( at, n1 ) && - 1 == ( ( 0 == at[n1].charge ) && 1 == num_of_H( at, n1 ) ) - + ( ( -1 == at[n1].charge ) && 0 == num_of_H( at, n1 ) )) - { - num_OH++; /* -OH or -O(-) */ - } - else - { - if (BOND_TYPE_SINGLE == bond_type && - 1 < nNoMetalNumBonds( at, n1 )) - { - - iN[num_OM++] = i1; /* non-terminal neighbor connected by a single bond */ - } - else - { - if (BOND_TYPE_SINGLE == bond_type && 1 == nNoMetalNumBonds( at, n1 )) - { - - num_X++; /* other terminal neighbor connected by a single bond */ - } - else - { - num_other++; - } - } - } - } - if (num_N == num_O && 3 == num_O && 2 == num_OH + num_OM + num_X && 0 == num_other) - { - for (i2 = 0; i2 < num_OM; i2++) - { - i1 = iN[i2]; - /* fix bond i1 */ - iedge = pBNS->vert[i].iedge[i1]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - } - } - } - - } /* for (i = */ - - return num_changes; -} - - -/****************************************************************************/ -int fix_explicitly_indicated_bonds( int nebend, - int *ebend, - BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms ) -{ - int i, num_changes = 0; - inp_ATOM *a; - int j, ia1, ia2, i1 = -1, i2 = -1, index = -1, neigh; - BNS_IEDGE iedge; - S_CHAR edge_forbidden_mask = BNS_EDGE_FORBIDDEN_MASK; - pBNS->edge_forbidden_mask |= edge_forbidden_mask; - - if (nebend < 1 || !ebend) - { - return 0; - } - - for (j = 0; j < nebend; j += 2) - { - - ia1 = ebend[2 * j]; - ia2 = ebend[2 * j + 1]; - - for (i = 0; i < num_atoms; i++) - { - if (at[i].orig_at_number == ia1) - { - i1 = i; - } - else if (at[i].orig_at_number == ia2) - { - i2 = i; - } - if (i1 > 0 && i2 > 0) - { - break; - } - } - - if (i1 < 0 || i2 < 0) - { - return 0; - } - - if (i2 < i1) - { - int tmp = i1; i1 = i2; i2 = tmp; - } - - a = at + i1; - for (i = 0; i < a->valence; i++) - { - neigh = (int) a->neighbor[i]; - if (neigh == i2) - { - index = i; break; - } - } - if (index > -1) - { - iedge = pBNS->vert[i].iedge[index]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - } - } - - return num_changes; -} - - - - -#define ALL_NONMETAL_Z 0 - - -/****************************************************************************/ -int is_Z_atom( U_CHAR el_number ) -{ - switch ( el_number ) - { - case EL_NUMBER_C: /* fallthrough */ - case EL_NUMBER_N: - case EL_NUMBER_P: - case EL_NUMBER_AS: - case EL_NUMBER_SB: - case EL_NUMBER_S: - case EL_NUMBER_SE: - case EL_NUMBER_TE: - case EL_NUMBER_CL: - case EL_NUMBER_BR: - case EL_NUMBER_I: -#if ( ALL_NONMETAL_Z == 1 ) - case EL_NUMBER_B: - case EL_NUMBER_O: - case EL_NUMBER_SI: - case EL_NUMBER_GE: - case EL_NUMBER_F: - case EL_NUMBER_AT: -#endif - return 1; - default: - return 0; - } -} - - -/**************************************************************************** -Detect O==Z--X, O=O,S,Se,Te -****************************************************************************/ -int IsZOX( inp_ATOM *atom, int at_x, int ord ) -{ - inp_ATOM *at_Z = atom + atom[at_x].neighbor[ord]; - - int i, neigh, num_O; - - for (i = 0, num_O = 0; i < at_Z->valence; i++) - { - neigh = at_Z->neighbor[i]; - if (neigh == at_x) - { - continue; - } - if (atom[neigh].valence == 1 && - atom[neigh].chem_bonds_valence == 2 && - atom[neigh].charge == 0 && - atom[neigh].radical == 0 && - ( atom[neigh].el_number == EL_NUMBER_O || - atom[neigh].el_number == EL_NUMBER_S || - atom[neigh].el_number == EL_NUMBER_SE || - atom[neigh].el_number == EL_NUMBER_TE )) - { - num_O++; - } - } - - return num_O; -} - -#if ( FIX_RENUM_BUG_FOR_CASE_OF_ACIDIC_OH_AT_P_PLUS == 1 ) -void update_some_attype_totals(int nAtTypeTotals[], int mask, int delta, S_CHAR at_charge); -/****************************************************************************/ -void update_some_attype_totals(int nAtTypeTotals[], int mask, int delta, S_CHAR at_charge) -{ - int i; - int32_t bit; /* djb-rwth: fixing coverity CID #499534 */ - if (nAtTypeTotals) - { - if (mask && !(mask & (ATBIT_Errors))) - { - for (i = 0, bit = 1; i < ATTOT_ARRAY_LEN; i++, bit <<= 1) - { - if (bit & mask) - { - nAtTypeTotals[i] += delta; - } - } - } - /* Count charges */ - if (at_charge) - { - nAtTypeTotals[ATTOT_TOT_CHARGE] += delta * at_charge; - nAtTypeTotals[ATTOT_NUM_CHARGES] += delta; - } - } - return; -} -#endif -/****************************************************************************/ -int GetAtomChargeType( inp_ATOM *atom, - int at_no, - int nAtTypeTotals[], - int *pMask, - int bSubtract ) -{ - - inp_ATOM *at = atom + at_no; -#if ( FIX_NORM_BUG_ADD_ION_PAIR == 1 ) - int i, neigh, mask, type, num_z, num_m, num_o, delta = bSubtract > 0 ? -1 : 1; /* 0 or -2 => add, 1 or 2 => subtract */ - int32_t bit; /* djb-rwth: fixing coverity CID #499579 */ - int bNoAdjIon = ( bSubtract == 0 || bSubtract == 1 ); -#else - int i, neigh, mask, bit, type, num_z, num_m, num_o, delta = bSubtract ? -1 : 1; -#endif - int bUnsatNHasTerminalO = 0; - - type = ATT_NONE; - mask = 0; - - if (at->radical && at->radical != RADICAL_SINGLET) - { - goto exit_function; - } - - if (is_el_a_metal( at->el_number )) - { - goto exit_function; - } - if (at->charge < -1 || at->charge > 1) - { - goto exit_function; - } - - if (!at->valence && at->charge == 1 && !at->num_H && !at->radical && at->el_number == EL_NUMBER_H) - { - /* a proton H+ (#1) */ - type = ATT_PROTON; - mask = ATBIT_Proton; - goto count_mask_bits; - } - - if ( !at->valence && at->charge == -1 && - !at->num_H && !at->radical && - ( at->el_number == EL_NUMBER_F || at->el_number == EL_NUMBER_CL || - at->el_number == EL_NUMBER_BR || at->el_number == EL_NUMBER_I ) - ) - { - /* a halogen anion Hal- (#2) */ - type = ATT_HalAnion; - mask = ATBIT_HalAnion; - goto count_mask_bits; - } -#if ( HAL_ACID_H_XCHG == 1 ) - /* halogen/chalcogen acid */ - if ((!at->valence && at->charge == 0 && 1 == at->num_H && !at->radical && - ( at->el_number == EL_NUMBER_F || - at->el_number == EL_NUMBER_CL || - at->el_number == EL_NUMBER_BR || - at->el_number == EL_NUMBER_I )) || - (!at->valence && at->charge == 0 && 2 == at->num_H && !at->radical && - ( at->el_number == EL_NUMBER_O || - at->el_number == EL_NUMBER_S || - at->el_number == EL_NUMBER_SE || - at->el_number == EL_NUMBER_TE )) /* djb-rwth: addressing LLVM warning */ - ) - { - /* a halogen/chalcogen acid (#3) */ - type = ATT_HalAcid; - mask = ATBIT_HalAcid; - goto count_mask_bits; - } -#endif - - if (detect_unusual_el_valence( at->el_number, at->charge, at->radical, - at->chem_bonds_valence, at->num_H, at->valence )) - { - goto exit_function; /* unusual valence state */ - } - - /* Check neighbors */ - for (i = 0, num_z = 0, num_m = 0, num_o = 0; i < at->valence; i++) - { - neigh = at->neighbor[i]; -#if ( FIX_NORM_BUG_ADD_ION_PAIR == 1 ) - if (atom[neigh].charge < -1 || atom[neigh].charge > 1) - { - goto exit_function; /* neighboring charge */ - } - if (atom[neigh].charge && at->charge) - { - if (bNoAdjIon) - { -#if ( FIX_RENUM_BUG_FOR_CASE_OF_ACIDIC_OH_AT_P_PLUS == 1 ) - goto count_mask_bits; - /*update_some_attype_totals(nAtTypeTotals, mask, delta, at->charge);*/ -#endif - goto exit_function; /* neighboring charge */ - } - type = ATT_NONE; - mask = 0; - goto count_mask_bits; - } -#else - if (atom[neigh].charge < -1 || atom[neigh].charge > 1 || atom[neigh].charge && at->charge) - { - goto exit_function; /* neighboring charge */ - } -#endif - if (detect_unusual_el_valence( atom[neigh].el_number, atom[neigh].charge, atom[neigh].radical, - atom[neigh].chem_bonds_valence, atom[neigh].num_H, - atom[neigh].valence )) - { - /* neighbor in unusual valence state */ - goto exit_function; - } - if (is_Z_atom( atom[neigh].el_number )) - { - num_z++; - } - if (is_el_a_metal( atom[neigh].el_number )) - { - num_m++; - } - num_o += ( atom[neigh].el_number == EL_NUMBER_O ); - if (at->el_number == EL_NUMBER_N && at->valence == 2 && !at->charge && - /*at->valence < at->chem_bonds_valence &&*/ - atom[neigh].valence == 1 && atom[neigh].chem_bonds_valence == 2 && - ( atom[neigh].el_number == EL_NUMBER_O || - atom[neigh].el_number == EL_NUMBER_S || - atom[neigh].el_number == EL_NUMBER_SE || - atom[neigh].el_number == EL_NUMBER_TE )) - { - bUnsatNHasTerminalO++; - } - } /* eof check neighbors */ - - /* O, S, Se, Te */ - if ( at->el_number == EL_NUMBER_O || - at->el_number == EL_NUMBER_S || - at->el_number == EL_NUMBER_SE || - at->el_number == EL_NUMBER_TE ) - { - if (at->charge == 1) - { - if (at->num_H) - { - /* #4 */ - type = ATT_O_PLUS; - mask |= ATBIT_OH_Plus; - } - else - { - /* #5 */ - type = ATT_O_PLUS; - mask |= ATBIT_O_Plus; - } - } - else - { - /* at->charge != 1 */ - if (at->valence > 1) - { - goto exit_function; /* not a terminal atom #C1 */ - } - else - { - if (at->valence && !( num_z || num_o )) - { - if (num_m == at->valence) - { - goto exit_function; /* #C2 */ - } - goto count_mask_bits; /* #C3 count charges, no donor or acceptor found */ - } - else - { - /* Here at->neigh[0] is one of: O, or Z={C, N, P, As, Sb, S, Se, Te, Cl, Br, I} */ - if (at->valence) - { - neigh = at->neighbor[0]; /* Z or O only */ - if (!atom[neigh].charge && atom[neigh].el_number == EL_NUMBER_C && - atom[neigh].chem_bonds_valence > atom[neigh].valence) - { - /* =C-OH, #C-OH, =C-O(-), #C-O(-), -C=O, =C=O; O = O, S, Se, Te */ - type = ATT_ACIDIC_CO; - if (at->num_H == 1) - { - mask |= ( ATBIT_COH ); /* #6: =C-OH, #C-OH; O=O,S,Se,Te */ - /*nAtTypeTotals[ATTOT_NUM_COH] ++;*/ - } - else - { - if (at->charge == -1) - { - mask |= ( ATBIT_CO_Minus ); /* #7: =C-O(-), #C-O(-); O=O,S,Se,Te */ - /*nAtTypeTotals[ATTOT_NUM_CO_Minus] ++;*/ - } - else - { - if (!at->num_H && !at->charge) - { - mask |= ( ATBIT_CO ); /* #8 -C=O, =C=O; O=O,S,Se,Te */ - /*nAtTypeTotals[ATTOT_NUM_CO] ++;*/ - } - else - { - mask |= ( ATBIT_Errors ); - /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ - } - } - } - } - else - { - if (!atom[neigh].charge && - ( atom[neigh].el_number == EL_NUMBER_O || - atom[neigh].el_number == EL_NUMBER_S || - atom[neigh].el_number == EL_NUMBER_SE || - atom[neigh].el_number == EL_NUMBER_TE ) && - atom[neigh].chem_bonds_valence == atom[neigh].valence) - { - /* -O-OH, -O-O(-); O = O, S, Se, Te */ - type = ATT_OO; - if (at->num_H == 1) - { - mask |= ( ATBIT_OOH ); /* #9 -O-OH */ - /*nAtTypeTotals[ATTOT_NUM_OOH] ++;*/ - } - else - { - if (at->charge == -1) - { - mask |= ( ATBIT_OO_Minus ); /* #10 -O-O(-) */ - /*nAtTypeTotals[ATTOT_NUM_OO_Minus] ++;*/ - } - else - { - mask |= ( ATBIT_Errors ); - /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ - } - } - } - else - { - if (!atom[neigh].charge && - atom[neigh].chem_bonds_valence == atom[neigh].valence && - atom[neigh].el_number == EL_NUMBER_C && - at->el_number != EL_NUMBER_O) - { - /* >C-S(-), >C-SH; S = S, Se, Te */ - type = ATT_ACIDIC_S; - if (at->num_H == 1) - { - mask |= ( ATBIT_CSH ); /* #11: >C-SH, >CH-SH, -CH2-SH; S = S, Se, Te */ - /*nAtTypeTotals[ATTOT_NUM_CSH] ++;*/ - } - else - { - if (at->charge == -1) - { - mask |= ( ATBIT_CS_Minus ); /* #12: >C-S(-), >CH-S(-), -CH2-S(-); S = S, Se, Te */ - /*nAtTypeTotals[ATTOT_NUM_CS_Minus] ++;*/ - } - else - { - mask |= ( ATBIT_Errors ); - /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ - } - } - } - else - { - if (atom[neigh].el_number == EL_NUMBER_N && - atom[neigh].valence == 2 && - ( !atom[neigh].num_H || (atom[neigh].num_H == 1 && atom[neigh].charge == 1) )) /* djb-rwth: addressing LLVM warning */ - { - /* N or N(-) or NH(+) neighbor */ - type = ATT_NO; /* single bond only */ - if (at->num_H == 1) - { - mask |= ( ATBIT_NOH ); /* #13: =N-OH, =NH(+)-OH, #N(+)-OH, -N(-)-OH; O = O, S, Se, Te */ - /*nAtTypeTotals[ATTOT_NUM_NOH] ++;*/ - } - else - { - if (at->charge == -1) - { - mask |= ( ATBIT_NO_Minus ); /* #14: =N-O(-); O = O, S, Se, Te */ - /*nAtTypeTotals[ATTOT_NUM_NO_Minus] ++;*/ - } - else - { - if (atom[neigh].charge == 1 || atom[neigh].charge == 0) - { - mask |= ( ATBIT_NO ); /* #15: =N(+)=O, -NH(+)=O -N=O */ - /*nAtTypeTotals[ATTOT_NUM_NO] ++;*/ - } - else - { - mask |= ( ATBIT_Errors ); - /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ - } - } - } - } - else - { - if (atom[neigh].el_number == EL_NUMBER_N) - { - type = ATT_N_O; /* #16: single bond only */ - if (at->num_H == 1) - { - mask |= ( ATBIT_N_OH ); /* #16: -NH-OH, >N-OH or >N(+)charge == -1) - { - mask |= ( ATBIT_N_O_Minus ); /* #17: -NH-O(-), >N-O(-); O = O, S, Se, Te */ - /*nAtTypeTotals[ATTOT_NUM_NO_Minus] ++;*/ - } - else - { - if (atom[neigh].charge == 1) - { - mask |= ( ATBIT_N_O ); /* #18: >N(+)=O */ - /*nAtTypeTotals[ATTOT_NUM_NO] ++;*/ - } - else - { - mask |= ( ATBIT_Errors ); - /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ - } - } - } - } - else - { - if ( atom[neigh].el_number != EL_NUMBER_C && - atom[neigh].el_number != EL_NUMBER_O && - !is_el_a_metal( atom[neigh].el_number ) && - atom[neigh].chem_bonds_valence > atom[neigh].valence) - { - /* =Z-OH, #Z-OH, =Z-O(-), #Z-O(-), -Z=O, =Z=O; - =Z(+)-OH, #Z(+)-OH, =Z-O(-), #Z-O(-), -Z(+)=O, =Z(+)=O; O = O, S, Se, Te */ - /* neigh = Z\{N,C} = P, As, Sb, S, Se, Te, Cl, Br, I */ - if (at->chem_bonds_valence == 1 && IsZOX( atom, at_no, 0 )) - { - type = ATT_ZOO; - if (at->num_H == 1) - { - mask |= ( ATBIT_ZOOH ); /* 18: O=Z-OH; O=O,S,Se,Te; Z may have charge */ - /*nAtTypeTotals[ATTOT_NUM_ZOOH] ++;*/ - } - else - { - if (at->charge == -1) - { - mask |= ( ATBIT_ZOO_Minus ); /* 19: O=Z-O(-); O = O, S, Se, Te */ - /*nAtTypeTotals[ATTOT_NUM_ZOO_Minus] ++;*/ - } - else - { - mask |= ( ATBIT_Errors ); - /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ - } - } - } - else - { - type = ATT_OTHER_ZO; - if (at->num_H == 1) - { - mask |= ( ATBIT_ZOH ); /* 20: =Z-OH, #Z-OH; O=O,S,Se,Te; Z may have charge */ - /*nAtTypeTotals[ATTOT_NUM_ZOH] ++;*/ - } - else - { - if (at->charge == -1) - { - mask |= ( ATBIT_ZO_Minus ); /* 21: =Z-O(-), #Z-O(-); O = O, S, Se, Te */ - /*nAtTypeTotals[ATTOT_NUM_ZO_Minus] ++;*/ - } - else - { - if (at->num_H == 0) - { - mask |= ( ATBIT_ZO ); /* 22: -Z=O, =Z=O; O=O,S,Se,Te; Z may have charge */ - /*nAtTypeTotals[ATTOT_NUM_ZO] ++;*/ - } - else - { - mask |= ( ATBIT_Errors ); - /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ - } - } - } - } - } - else - { - if (at->charge == -1 && !is_el_a_metal( atom[neigh].el_number )) - { - /* >Z-O(-); O=O,S,Se,Te */ - type = ATT_OTHER_NEG_O; - mask |= ( ATBIT_O_Minus ); /* 23: -Z-O(-); O=O,S,Se,Te */ - /*nAtTypeTotals[ATTOT_NUM_ZO_Minus] ++;*/ - } - } - } - } - } - } - } - } - - else - { - if (at->charge == -1 && at->num_H == 1) - { - type = ATT_OH_MINUS; - mask |= ( ATBIT_O_Minus ); /* 25: HO(-); O=O,S,Se,Te */ - } - } - } - } - } - } - - else - { - /* P, N, neutral valence = 3 (not 5) */ - if (( at->el_number == EL_NUMBER_N || - at->el_number == EL_NUMBER_P ) && - 0 <= at->valence && at->valence <= 3 && - at->chem_bonds_valence + at->num_H == 3 + at->charge) - { - if (at->valence && !( num_z /*|| num_o == at->valence*/ )) - { - if (num_m == at->valence) - { - goto exit_function; - } - goto count_mask_bits; /* N(III), N(-)(II), N(+)(IV) and same P that have only oxygen neighbors are ignored here */ - } - type = ( at->el_number == EL_NUMBER_N ) ? ATT_ATOM_N : ATT_ATOM_P; - switch (at->charge) - { - case -1: - if (at->el_number == EL_NUMBER_N) - { - mask |= ( ATBIT_N_Minus ); /* 26: -NH(-), =N(-), >N(-) */ - if (at->num_H) - { - mask |= ( ATBIT_NP_H ); /* 27: -NH(-) */ - } -#if ( FIX_NP_MINUS_BUG == 1 ) - else - { - if (at->valence == 1 && at->chem_bonds_valence >= 2 && ( at->bond_type[0] & BOND_MARK_ALL )) - { - type |= ATT_NP_MINUS_V23; /* =N(-) created by normalization 2010-03-11 DT */ - } - } -#endif - } - /*nAtTypeTotals[ATTOT_NUM_N_Minus] += (at->el_number == EL_NUMBER_N);*/ - break; - case 0: - if (at->num_H) - { - mask |= ( ATBIT_NP_H ); /* 28: -NH2, =NH, >NH */ - /*nAtTypeTotals[ATTOT_NUM_NP_H] ++;*/ - } - else - { - if (bUnsatNHasTerminalO == 1) - { - mask |= ( ATBIT_ON ); /* 29: -N=O,-N=OH(+) only, not =N-OH */ - } - else - { - mask |= ( ATBIT_NP ); /* 30: -P=O,-P=OH(+), >N- =N- (incl. =N-OH) , #N */ - /*nAtTypeTotals[ATTOT_NUM_NP] ++;*/ - } - } - break; /* ignore neutral N or P */ - case 1: - if (at->num_H) - { - mask |= ( ATBIT_NP_Proton ); /* 31: NH4(+), -NH3(+), =NH2(+), >NH2(+), =NH(+)-, >NH(+)-, #NH(+) */ - /*nAtTypeTotals[ATTOT_NUM_NP_Proton] ++;*/ - } - else - { - if (at->chem_bonds_valence > at->valence) - { - mask |= ( ATBIT_NP_Plus ); /* =N(+)=, #N(+)-, =N(+)< */ - /*nAtTypeTotals[ATTOT_NUM_NP_Plus] ++;*/ - } - else - { - type = 0; /* 32: ignore onium cations >N(+)< */ - } - } - break; - default: - mask |= ( 1 << ATTOT_NUM_Errors ); - /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ - break; - } - } - } - -count_mask_bits: - if (nAtTypeTotals) - { - if (mask && !( mask & ( ATBIT_Errors ) )) - { - for (i = 0, bit = 1; i < ATTOT_ARRAY_LEN; i++, bit <<= 1) - { - if (bit & mask) - { - nAtTypeTotals[i] += delta; - } - } - } - - /* Count charges */ - if (at->charge) - { - nAtTypeTotals[ATTOT_TOT_CHARGE] += delta * at->charge; - nAtTypeTotals[ATTOT_NUM_CHARGES] += delta; - } - } - - if (pMask) - { - *pMask = mask; - } - -exit_function: - if (mask & ( ATBIT_Errors )) - { - type = 0; - if (nAtTypeTotals) - { - nAtTypeTotals[ATTOT_NUM_Errors] += 1; - } - } - - - return type; -} - - -/****************************************************************************/ -int SimpleRemoveHplusNPO( inp_ATOM *at, - int num_atoms, - int nAtTypeTotals[], - T_GROUP_INFO *t_group_info ) -{ - int i, mask, type, num_removed; - for (i = 0, num_removed = 0; i < num_atoms; i++) - { - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - if (( PR_SIMPLE_TYP & ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) ) ) && - ( PR_SIMPLE_MSK & mask )) - { -#if ( bRELEASE_VERSION == 0 ) - if (at[i].charge != 1 || at[i].num_H == 0) - { - return -1; /* program error */ - } -#endif - type = GetAtomChargeType(at, i, nAtTypeTotals, &mask, 1); /* subtract at[i] */ /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - at[i].charge = 0; - AddOrRemoveExplOrImplH( -1, at, num_atoms, (AT_NUMB) i, t_group_info ); - /*at[i].num_H --;*/ - num_removed++; -#if ( FIX_NORM_BUG_ADD_ION_PAIR == 1 ) - type = GetAtomChargeType(at, i, nAtTypeTotals, &mask, 0); /* add changed at[i] */ /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ -#else - type = GetAtomChargeType(at, i, nAtTypeTotals, &mask, 1); /* bug: subtract instead of add */ /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ -#endif - /* - if ( nAtTypeTotals ) { - nAtTypeTotals[ATTOT_NUM_NP_Proton] --; - if ( at[i].num_H ) { - nAtTypeTotals[ATTOT_NUM_NP_H] ++; - } else { - nAtTypeTotals[ATTOT_NUM_NP] ++; - } - nAtTypeTotals[ATTOT_TOT_CHARGE] --; - nAtTypeTotals[ATTOT_NUM_CHARGES] --; - } - */ - } - } - - return num_removed; -} - - -/****************************************************************************/ -int bIsAtomTypeHard( inp_ATOM *at, - int endpoint, - int nType, - int nMask, - int nCharge ) -{ - int mask; - if (( nType & GetAtomChargeType( at, endpoint, NULL, &mask, 0 ) ) && ( mask & nMask ) -#if ( OPPOSITE_CHARGE_IN_CGROUP == 0 ) - && ( at[endpoint].charge == nCharge || !at[endpoint].charge ) -#endif - ) - { - return 1; - } - - return 0; -} - - -/****************************************************************************/ -int bIsHDonorAccAtomType( inp_ATOM *at, int endpoint, int *cSubType ) -{ - if (bIsAtomTypeHard( at, endpoint, PR_HARD_TYP_H, PR_HARD_MSK_H, 0 )) - { - /* Obtain donor/acceptor info */ - int neutral_valence = at[endpoint].chem_bonds_valence + at[endpoint].num_H - at[endpoint].charge; - if (neutral_valence != 2 /* O, S, Se, Te */ && - neutral_valence != 3 /* N, P */) - { - return -1; /* wrong endpoint neutral valence */ - } - else - { - int edge_flow = at[endpoint].num_H; - int num_bonds = at[endpoint].valence; - int edge_cap = neutral_valence - num_bonds; /* does not allow to reduce -NH3(+) to #N or -OH(+)- to -O- */ - edge_flow = inchi_min( edge_flow, edge_cap ); - /* what this means: */ - if (edge_cap) - { - if (edge_cap > edge_flow) - { - *cSubType |= SALT_ACCEPTOR; - } - if (edge_flow) - { - *cSubType |= SALT_DONOR_H; - } - return 4; - } - } - } - - return -1; -} - - -/****************************************************************************/ -int bIsNegAtomType( inp_ATOM *at, int endpoint, int *cSubType ) -{ - int sub_type = 0; - if (bIsAtomTypeHard( at, endpoint, PR_HARD_TYP_NEG, PR_HARD_MSK_NEG, -1 )) - { - /* Obtain donor/acceptor info */ - int neutral_valence = at[endpoint].chem_bonds_valence + at[endpoint].num_H - at[endpoint].charge; - if (neutral_valence != 2 /* O, S, Se, Te */ && - neutral_valence != 3 /* N, P */) - { - return -1; /* wrong endpoint neutral valence */ - } - else - { - int edge_flow = ( at[endpoint].charge == -1 ); - int num_bonds = at[endpoint].valence; - int edge_cap = neutral_valence - num_bonds - at[endpoint].num_H; /* does not allow to reduce -NH3(+) to #N or -OH(+)- to -O- */ - edge_flow = inchi_min( edge_flow, edge_cap ); - /* what this means: */ - if (edge_cap) - { - if (edge_cap > edge_flow) - { - sub_type |= SALT_ACCEPTOR; - } - if (edge_flow) - { - sub_type |= SALT_DONOR_Neg; - } - if (sub_type) - { - *cSubType |= sub_type; - return 4; - } - } - } - } - - return -1; -} - - -/****************************************************************************/ -int bIsHardRemHCandidate( inp_ATOM *at, int i, int *cSubType ) -{ - int ret1, ret2, ret; - int sub_type = 0; - ret1 = bIsHDonorAccAtomType( at, i, &sub_type ); - ret2 = bIsNegAtomType( at, i, &sub_type ); - ret = inchi_max( ret1, ret2 ); - if (ret > 0 && sub_type) - { - *cSubType |= sub_type; - return ret; - } - return -1; -} - - -/****************************************************************************/ -int CreateCGroupInBnStruct( inp_ATOM *at, - int num_atoms, - BN_STRUCT *pBNS, - int nType, - int nMask, - int nCharge ) -{ - int k, c_point, cg, centerpoint, fictpoint, type, ret = 0; - int num_cg = 1; - int num_edges = pBNS->num_edges; - int num_vertices = pBNS->num_vertices; /* new c-group bns-ID */ - BNS_VERTEX *vert_ficpoint, *ver_ficpont_prev; /* fictitious vertex describing charge c-group */ - BNS_VERTEX *vertex_cpoint; - BNS_EDGE *edge; /* edge between that vertex and the tautomeric c_point */ - int mask, num_CPoints; - - /* Debug: check overflow */ - if (num_vertices + num_cg >= pBNS->max_vertices) - { - return BNS_VERT_EDGE_OVFL; - } - - /* Count new c-group edges */ - for (c_point = 0, num_CPoints = 0; c_point < num_atoms; c_point++) - { - if (( nType & GetAtomChargeType( at, c_point, NULL, &mask, 0 ) ) && ( mask & nMask ) -#if ( OPPOSITE_CHARGE_IN_CGROUP == 0 ) - && ( at[c_point].charge == nCharge || !at[c_point].charge ) -#endif - ) - { - num_CPoints++; - } - } - - if (!num_CPoints) - { - return 0; - } - - /* Clear the new vertex */ - memset( pBNS->vert + num_vertices, 0, 1 * sizeof( pBNS->vert[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - - /* *old* Make sure the last t-group has the largest t-group ID: - this is necessary to correctly add new edges and vertices for testing augmenting paths - */ - - /**************************************/ - /* initialize new fictitious vertex */ - /* representing c-point group */ - /**************************************/ - - ver_ficpont_prev = pBNS->vert + num_vertices - 1; - - for (cg = 0; cg < num_cg; cg++, ver_ficpont_prev = vert_ficpoint) - { - /* - vert_ficpoint-1 is the last vertex; - vert_ficpoint is the being added vertex - Note: nGroupNumber are not contiguous - */ - vert_ficpoint = pBNS->vert + num_vertices + cg; - vert_ficpoint->iedge = ver_ficpont_prev->iedge + ver_ficpont_prev->max_adj_edges; - vert_ficpoint->max_adj_edges = num_CPoints + BNS_ADD_EDGES; - vert_ficpoint->num_adj_edges = 0; - vert_ficpoint->st_edge.flow = vert_ficpoint->st_edge.flow0 = 0; - vert_ficpoint->st_edge.cap = vert_ficpoint->st_edge.cap0 = 0; - vert_ficpoint->type = BNS_VERT_TYPE_C_GROUP | ( ( nCharge < 0 ) ? BNS_VERT_TYPE_C_NEGATIVE : 0 ); - } - - /************************************************/ - /* Connect c-points to the fictitious vertices */ - /* representing c-point groups; set caps, flows */ - /************************************************/ - cg = 1; - for (c_point = 0; c_point < num_atoms; c_point++) - { - if (( nType & ( type = GetAtomChargeType( at, c_point, NULL, &mask, 0 ) ) ) && ( mask & nMask ) -#if ( OPPOSITE_CHARGE_IN_CGROUP == 0 ) - && ( at[c_point].charge == nCharge || !at[c_point].charge ) -#endif - ) - { - ; - } - else - { - continue; - } - - fictpoint = cg + num_vertices - 1; /* c-group vertex index */ - vert_ficpoint = pBNS->vert + fictpoint; /* c-group vertex */ - vertex_cpoint = pBNS->vert + c_point; /* c_point vertex */ - - /* Debug: check overflow */ - if (fictpoint >= pBNS->max_vertices || - num_edges >= pBNS->max_edges || - vert_ficpoint->num_adj_edges >= vert_ficpoint->max_adj_edges || - vertex_cpoint->num_adj_edges >= vertex_cpoint->max_adj_edges) - { - /* djb-rwth: removing redundant code */ - break; - } - vertex_cpoint->type |= BNS_VERT_TYPE_C_POINT; - if (( KNOWN_ACIDIC_TYPE & type ) && nCharge < 0) - { - vertex_cpoint->type |= pBNS->type_TACN; - } - -#if ( FIX_CPOINT_BOND_CAP != 1 ) /* { */ - /* Set capacity = 1 to the edges from the c_point to the centerpoint(s) */ - /* if their current capacity is zero */ - /* the centerpoint is any adjacent atom that is adjacent to a multiple bond */ - for (k = 0; k < vertex_cpoint->num_adj_edges; k++) - { - int iedge = vertex_cpoint->iedge[k]; - if (!pBNS->edge[iedge].cap) - { - /* single bond, possibly between c_point and centerpoint */ - centerpoint = ( pBNS->edge[iedge].neighbor12 ^ c_point ); - if (centerpoint < pBNS->num_atoms && - pBNS->vert[centerpoint].st_edge.cap >= 1) - { - int bond_type = ( at[c_point].bond_type[k] & BOND_TYPE_MASK ); - if (bond_type == BOND_TAUTOM || - bond_type == BOND_ALTERN || - bond_type == BOND_SINGLE) - { - pBNS->edge[iedge].cap = 1; - } - } - } - } -#endif /* } FIX_CPOINT_BOND_CAP */ - - /* Create a new edge connecting c_point to the new fictitious c-group vertex vert_ficpoint */ - edge = pBNS->edge + num_edges; - edge->cap = 1; - edge->flow = 0; - edge->pass = 0; -#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) - edge->forbidden &= pBNS->edge_forbidden_mask; /* remove previous temporary ban */ -#endif - - /* nCharge = +1: mark edge to c-point having no (+)-moveable charge with flow=1 */ - /* nCharge = -1: mark edge to c-point having -1 moveable charge with flow=1 */ - - if ((nCharge == 1 && at[c_point].charge != 1) || (nCharge == -1 && at[c_point].charge == -1)) /* djb-rwth: addressing LLVM warning */ - /*if ( !CHARGED_CPOINT(at,c_point) )*/ - { - /* Increment new edge flow, update st_edges of the adjacent vertices */ - edge->flow++; - /* Increment c-group vertex st-flow & cap */ - vert_ficpoint->st_edge.flow++; - vert_ficpoint->st_edge.cap++; - /* Increment c-point vertex st-flow & cap */ - vertex_cpoint->st_edge.flow++; - vertex_cpoint->st_edge.cap++; - } - -#if ( FIX_CPOINT_BOND_CAP == 1 ) /* { */ - /* Set capacity = 1 to the edges from the c_point to the centerpoint(s) */ - /* if their current capacity is zero */ - /* the centerpoint is any adjacent atom that is adjacent to a multiple bond */ - for (k = 0; k < vertex_cpoint->num_adj_edges; k++) - { - int iedge = vertex_cpoint->iedge[k]; - VertexFlow nNewCap = vertex_cpoint->st_edge.cap; - centerpoint = ( pBNS->edge[iedge].neighbor12 ^ c_point ); - if (!pBNS->edge[iedge].cap) - { - /* Single bond, possibly between c_point and centerpoint */ - if (centerpoint < pBNS->num_atoms && - pBNS->vert[centerpoint].st_edge.cap >= 1) - { - nNewCap = inchi_min( pBNS->vert[centerpoint].st_edge.cap, nNewCap ); - nNewCap = inchi_min( nNewCap, MAX_BOND_EDGE_CAP ); - pBNS->edge[iedge].cap = nNewCap; - } - } -#if ( FIX_CPOINT_BOND_CAP2 == 1 ) /* multiple bond */ - else - { - if (centerpoint < pBNS->num_atoms && - edge->flow && pBNS->edge[iedge].cap < MAX_BOND_EDGE_CAP) - { - pBNS->edge[iedge].cap++; - } - } -#endif - } -#endif /* } FIX_CPOINT_BOND_CAP */ - - /* Connect edge to c_point and fictpoint and increment the counters of neighbors and edges */ - edge->neighbor1 = c_point; /* the smallest out of v1=endopoint and v2=num_vertices */ - edge->neighbor12 = c_point ^ fictpoint; /* v1 ^ v2 */ - vertex_cpoint->iedge[vertex_cpoint->num_adj_edges] = num_edges; - vert_ficpoint->iedge[vert_ficpoint->num_adj_edges] = num_edges++; - edge->neigh_ord[0] = vertex_cpoint->num_adj_edges++; - edge->neigh_ord[1] = vert_ficpoint->num_adj_edges++; - edge->cap0 = edge->cap; - edge->flow0 = edge->flow; - } - - ret = pBNS->num_vertices; /* new c-group atom number */ - pBNS->num_edges = num_edges; - pBNS->num_vertices += num_cg; - pBNS->num_c_groups += num_cg; - - return ret; -} - - -/****************************************************************************/ -int CreateTGroupInBnStruct( inp_ATOM *at, - int num_atoms, - BN_STRUCT *pBNS, - int nType, - int nMask ) -{ - int ret = 0; - /* ret = ReInitBnStruct( pBNS ); */ - int k, endpoint, tg, centerpoint, fictpoint; - int num_tg = 1; - int num_edges = pBNS->num_edges; - int num_vertices = pBNS->num_vertices; - BNS_VERTEX *vert_ficpoint, *ver_ficpont_prev; /* fictitious vertex describing t-group */ - BNS_VERTEX *vert_endpoint; - BNS_EDGE *edge; /* edge between that vertex and the tautomeric endpoint */ - int mask, num_endpoints, neutral_valence, edge_flow, edge_cap, num_bonds; - - /* Debug: check overflow */ - if (num_vertices + num_tg >= pBNS->max_vertices) - { - return BNS_VERT_EDGE_OVFL; - } - - /* Count new t-group edges */ - for (endpoint = 0, num_endpoints = 0; endpoint < num_atoms; endpoint++) - { - if (( nType & GetAtomChargeType( at, endpoint, NULL, &mask, 0 ) ) && ( mask & nMask ) - ) - { - num_endpoints++; - } - } - - if (!num_endpoints) - { - return 0; - } - - /* Since t-group IDs may be not contiguous, clear all vertices that will be added. - all-zeroes-vertex will be ignored by the BNS - */ - memset( pBNS->vert + num_vertices, 0, num_tg * sizeof( pBNS->vert[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - - /* *old* Make sure the last t-group has the largest t-group ID: - this is necessary to correctly add new edges and vertices for testing augmenting paths - */ - - /**************************************/ - /* Initialize new fictitious vertex */ - /* representing t-point group */ - /**************************************/ - ver_ficpont_prev = pBNS->vert + num_vertices - 1; - - for (tg = 0; tg < num_tg; tg++, ver_ficpont_prev = vert_ficpoint) - { - /* - vert_ficpoint-1 is the last vertex; - vert_ficpoint is the vertex that is being added - Note: nGroupNumber are not contiguous - */ - vert_ficpoint = pBNS->vert + num_vertices + tg; - vert_ficpoint->iedge = ver_ficpont_prev->iedge + ver_ficpont_prev->max_adj_edges; - vert_ficpoint->max_adj_edges = num_endpoints + BNS_ADD_EDGES + BNS_ADD_SUPER_TGROUP; - vert_ficpoint->num_adj_edges = 0; - vert_ficpoint->st_edge.flow = vert_ficpoint->st_edge.flow0 = 0; - vert_ficpoint->st_edge.cap = vert_ficpoint->st_edge.cap0 = 0; - vert_ficpoint->type |= BNS_VERT_TYPE_TGROUP; - } - - tg = 1; - for (endpoint = 0; endpoint < num_atoms; endpoint++) - { - if (( nType & GetAtomChargeType( at, endpoint, NULL, &mask, 0 ) ) && ( mask & nMask )) - { - ; - } - else - { - continue; - } - fictpoint = tg + num_vertices - 1; - vert_ficpoint = pBNS->vert + fictpoint; - vert_endpoint = pBNS->vert + endpoint; - /* Debug: check overflow */ - if (fictpoint >= pBNS->max_vertices || - num_edges >= pBNS->max_edges || - vert_ficpoint->num_adj_edges >= vert_ficpoint->max_adj_edges || - vert_endpoint->num_adj_edges >= vert_endpoint->max_adj_edges) - { - /* djb-rwth: removing redundant code */ - break; - } - - /* Obtain donor/acceptor info */ - neutral_valence = at[endpoint].chem_bonds_valence + at[endpoint].num_H - at[endpoint].charge; - if (neutral_valence != 2 /* O, S, Se, Te */ && - neutral_valence != 3 /* N, P */) - { - /* djb-rwth: removing redundant code */ - break; - } - edge_flow = at[endpoint].num_H; - num_bonds = at[endpoint].valence; - edge_cap = neutral_valence - num_bonds; /* does not allow to reduce -NH3(+) to #N or -OH(+)- to -O- */ - - if (3 == neutral_valence /* N or P */ && 1 < num_bonds) - { - edge_cap++; /* allow -NH2(+)- => -N=, >NH(+)- => >N- */ - } - edge_flow = inchi_min( edge_flow, edge_cap ); - /* - if ( !nGetEndpointInfo( at, endpoint, &eif ) ) { - ret = BNS_BOND_ERR; - break; - } - */ - vert_endpoint->type |= BNS_VERT_TYPE_ENDPOINT; - - /* Create a new edge connecting endpoint to the new fictitious t-group vertex vert_ficpoint */ - edge = pBNS->edge + num_edges; - edge->cap = edge_cap; - edge->flow = edge_flow; - edge->pass = 0; -#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) - edge->forbidden &= pBNS->edge_forbidden_mask; -#endif - - /* Adjust st_flow and st_cap of the adjacent vertices */ - /* Adjust t-group vertex st-flow & cap */ - vert_ficpoint->st_edge.flow += edge->flow; - vert_ficpoint->st_edge.cap += edge->flow; - /* adjust endpoint vertex st-flow & cap */ - vert_endpoint->st_edge.flow += edge->flow; - vert_endpoint->st_edge.cap += edge->flow; - - /* Adjust edge cap & flow according to the number of H and number of bonds */ - for (k = 0; k < vert_endpoint->num_adj_edges; k++) - { - int iedge = vert_endpoint->iedge[k]; - VertexFlow nNewCap = vert_endpoint->st_edge.cap; - if (!pBNS->edge[iedge].cap) - { - /* single bond, possibly between endpoint and centerpoint */ - centerpoint = ( pBNS->edge[iedge].neighbor12 ^ endpoint ); - if (centerpoint < pBNS->num_atoms && - pBNS->vert[centerpoint].st_edge.cap >= 1) - { - nNewCap = inchi_min( pBNS->vert[centerpoint].st_edge.cap, nNewCap ); - nNewCap = inchi_min( nNewCap, MAX_BOND_EDGE_CAP ); - pBNS->edge[iedge].cap = nNewCap; - } - } - } - - /* Connect edge to endpoint and fictpoint and increment the counters of neighbors and edges */ - edge->neighbor1 = endpoint; /* the smallest out of v1=endopoint and v2=num_vertices */ - edge->neighbor12 = endpoint ^ fictpoint; /* v1 ^ v2 */ - vert_endpoint->iedge[vert_endpoint->num_adj_edges] = num_edges; - vert_ficpoint->iedge[vert_ficpoint->num_adj_edges] = num_edges++; - edge->neigh_ord[0] = vert_endpoint->num_adj_edges++; - edge->neigh_ord[1] = vert_ficpoint->num_adj_edges++; - edge->cap0 = edge->cap; - edge->flow0 = edge->flow; - } - - ret = pBNS->num_vertices; /* new t-group atom number */ - pBNS->num_edges = num_edges; - pBNS->num_vertices += num_tg; - pBNS->num_t_groups += num_tg; - - return ret; -} - - -/****************************************************************************/ -int RemoveLastGroupFromBnStruct( inp_ATOM *at, - int num_atoms, - int tg, - BN_STRUCT *pBNS ) -{ - int ret = 0; - /* ret = ReInitBnStruct( pBNS ); */ - int k, endpoint, /*centerpoint, fictpoint,*/ iedge; - int num_edges = pBNS->num_edges; - int num_vertices = pBNS->num_vertices; - BNS_VERTEX *vert_ficpoint /*, *ver_ficpont_prev*/; /* fictitious vertex describing t-group */ - BNS_VERTEX *vert_endpoint; - BNS_EDGE *edge; /* edge between that vertex and the tautomeric endpoint */ - /*int mask, num_endpoints, neutral_valence, edge_flow, edge_cap, num_bonds;*/ - int is_t_group = 0, is_c_group = 0; - - /* Debug: check overflow */ - if (pBNS->num_added_atoms + pBNS->num_c_groups + pBNS->num_t_groups + num_atoms >= pBNS->max_vertices) - { - return BNS_VERT_EDGE_OVFL; - } - - if (tg + 1 != num_vertices) - { - return BNS_VERT_EDGE_OVFL; - } - - vert_ficpoint = pBNS->vert + tg; - - if (vert_ficpoint->type & BNS_VERT_TYPE_TGROUP) - { - is_t_group = 1; - } - if (vert_ficpoint->type & BNS_VERT_TYPE_C_GROUP) - { - is_c_group = 1; - if (vert_ficpoint->type & BNS_VERT_TYPE_C_NEGATIVE) - { - is_c_group = 2; - } - } - - for (k = vert_ficpoint->num_adj_edges - 1; 0 <= k; k--) - { - iedge = vert_ficpoint->iedge[k]; - if (iedge + 1 != num_edges) - { - return BNS_VERT_EDGE_OVFL; - } - edge = pBNS->edge + iedge; - endpoint = edge->neighbor12 ^ tg; - vert_endpoint = pBNS->vert + endpoint; - /* adjust st_flow, st_cap */ - vert_endpoint->st_edge.cap0 = - vert_endpoint->st_edge.cap -= edge->flow; - vert_endpoint->st_edge.flow0 = - vert_endpoint->st_edge.flow -= edge->flow; - if (pBNS->type_TACN && ( vert_endpoint->type & pBNS->type_TACN ) == pBNS->type_TACN) - { - vert_endpoint->type ^= pBNS->type_TACN; - } - if (is_t_group) - { - vert_endpoint->type ^= ( vert_ficpoint->type & BNS_VERT_TYPE_ENDPOINT ); - } - if (is_c_group) - { - vert_endpoint->type ^= ( vert_ficpoint->type & BNS_VERT_TYPE_C_POINT ); - } - /* Remove edge */ - if (edge->neigh_ord[0] + 1 != vert_endpoint->num_adj_edges) - { - return BNS_VERT_EDGE_OVFL; - } - vert_endpoint->num_adj_edges--; - memset( edge, 0, sizeof( *edge ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - num_edges--; - if (1 == is_t_group && endpoint < num_atoms) - { - at->endpoint = 0; - } - if (1 == is_c_group && endpoint < num_atoms) - { - at->c_point = 0; - } - } - memset( vert_ficpoint, 0, sizeof( *vert_ficpoint ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - num_vertices--; - - pBNS->num_edges = num_edges; - pBNS->num_vertices = num_vertices; - if (is_t_group) - { - pBNS->num_t_groups--; - } - if (is_c_group) - { - pBNS->num_c_groups--; - } - - return ret; -} - - - -/****************************************************************************/ -int SetInitCapFlowToCurrent( BN_STRUCT *pBNS ) -{ - int i, j; - BNS_EDGE *pEdge = NULL; - for (i = 0; i < pBNS->num_vertices; i++) - { - pBNS->vert[i].st_edge.flow0 = pBNS->vert[i].st_edge.flow; - pBNS->vert[i].st_edge.cap0 = pBNS->vert[i].st_edge.cap; - for (j = 0; j < pBNS->vert[i].num_adj_edges; j++) - { - pEdge = pBNS->edge + pBNS->vert[i].iedge[j]; - pEdge->cap0 = pEdge->cap; - pEdge->flow0 = pEdge->flow; - } - } - - return 0; -} - - -int ArTypMask[] = -{ - AR_SIMPLE_TYP1, - AR_SIMPLE_MSK1, - AR_SIMPLE_TYP2, - AR_SIMPLE_MSK2, - AR_SIMPLE_TYP3, - AR_SIMPLE_MSK3, - 0, - 0 -}; - - - -/****************************************************************************/ -int SimpleRemoveAcidicProtons( inp_ATOM *at, - int num_atoms, - BN_AATG *pAATG, - int num2remove ) -{ - int i, j, max_j = -1, mask, type, num_removed; - int num[AR_SIMPLE_STEPS + 1], num_tot; - - for (j = 0; ArTypMask[2 * j]; j++) - { - num[max_j = j] = 0; - } - - for (i = 0; i < num_atoms; i++) - { - if (!at[i].charge && at[i].num_H && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) - { - for (j = 0; j <= max_j; j++) - { - if (( type & ArTypMask[2 * j] ) && ( mask && ArTypMask[2 * j + 1] )) - { - num[j] ++; - break; - } - } - } - } - for (j = 0, num_tot = 0; j <= max_j; j++) - { - if (( num_tot += num[j] ) >= num2remove) - { - max_j = j; - break; - } - } - if (!num_tot) - { - return 0; - } - for (i = 0, num_removed = 0; i < num_atoms && num_removed < num2remove; i++) - { - if (!at[i].charge && at[i].num_H && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) - { - for (j = 0; j <= max_j; j++) - { - if (num[j] && ( type & ArTypMask[2 * j] ) && ( mask && ArTypMask[2 * j + 1] )) - { - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - type = GetAtomChargeType(at, i, pAATG->nAtTypeTotals, &mask, 1); /* subtract at[i] */ - num[j] --; - at[i].charge--; - AddOrRemoveExplOrImplH( -1, at, num_atoms, (AT_NUMB) i, pAATG->t_group_info ); - /*at[i].num_H --;*/ - num_removed++; - type = GetAtomChargeType(at, i, pAATG->nAtTypeTotals, &mask, 0); /* add changed at[i] */ /* ! THIS CHANGES pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] */ - break; - } - } - } - } - - /* - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] -= num_removed; - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] += num_removed; - */ - - return num_removed; -} - - -/****************************************************************************/ -int bHasAcidicHydrogen( inp_ATOM *at, int i ) -{ - int bFound = 0, j, type, mask; - if (!at[i].charge && at[i].num_H && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) - { - for (j = 0; ArTypMask[2 * j]; j++) - { - if (( type & ArTypMask[2 * j] ) && ( mask & ArTypMask[2 * j + 1] )) - { - bFound++; - break; - } - } - } - - return bFound; -} - - -/****************************************************************************/ -int bHasOtherExchangableH( inp_ATOM *at, int i ) -{ - int bFound = 0, type, mask; - if (at[i].num_H && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) - { - if (( type & ATT_ATOM_N ) && ( mask & ATBIT_NP_H )) - { - bFound++; - } - } - - return bFound; -} - - -int AaTypMask[] = -{ - AA_SIMPLE_TYP1, - AA_SIMPLE_MSK1, -#if ( FIX_NP_MINUS_BUG == 1 ) - AA_SIMPLE_TYP4, - AA_SIMPLE_MSK4, /* should not follow 0,0 pair */ -#endif - AA_SIMPLE_TYP2, - AA_SIMPLE_MSK2, - AA_SIMPLE_TYP3, - AA_SIMPLE_MSK3, - 0, - 0 -}; - - -/****************************************************************************/ -int SimpleAddAcidicProtons( inp_ATOM *at, - int num_atoms, - BN_AATG *pAATG, - int num2add ) -{ - int i, j, max_j = -1, mask, type, num_added; - int num[AR_SIMPLE_STEPS + 1], num_tot; - - for (j = 0; AaTypMask[2 * j]; j++) - { - num[max_j = j] = 0; - } - - for (i = 0; i < num_atoms; i++) - { - if (at[i].charge == -1 && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) - { - for (j = 0; j <= max_j; j++) - { - if (( type & AaTypMask[2 * j] ) && ( mask && AaTypMask[2 * j + 1] )) - { - num[j] ++; - break; - } - } - } - } - for (j = 0, num_tot = 0; j <= max_j; j++) - { - if (( num_tot += num[j] ) >= num2add) - { - max_j = j; - break; - } - } - if (!num_tot) - { - return 0; - } - for (i = 0, num_added = 0; i < num_atoms && num_added < num2add; i++) - { - if (at[i].charge == -1 && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) - { - for (j = 0; j <= max_j; j++) - { - if (num[j] && ( type & AaTypMask[2 * j] ) && ( mask && AaTypMask[2 * j + 1] )) - { - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - type = GetAtomChargeType(at, i, pAATG->nAtTypeTotals, &mask, 1); /* subtract at[i] */ - num[j] --; - at[i].charge++; - AddOrRemoveExplOrImplH( 1, at, num_atoms, (AT_NUMB) i, pAATG->t_group_info ); - /*at[i].num_H ++;*/ - num_added++; - type = GetAtomChargeType(at, i, pAATG->nAtTypeTotals, &mask, 0); /* add changed at[i] */ - break; - } - } - } - } - - /* - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] += num_added; - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] -= num_added; - */ - - return num_added; -} - - -/****************************************************************************/ -int bHasAcidicMinus( inp_ATOM *at, int i ) -{ - int bFound = 0, j, type, mask; - if (at[i].charge == -1 && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) - { - for (j = 0; AaTypMask[2 * j]; j++) - { - if (( type & AaTypMask[2 * j] ) && ( mask & AaTypMask[2 * j + 1] )) - { - bFound++; - break; - } - } - } - - return bFound; -} - - -/**************************************************************************** -HardRemoveAcidicProtons( ... ) - -Create 2 tautomeric groups: -(1) for O on -C=O, -(2) for the rest of the atoms. -Pull H from (2) to (1); remove later -****************************************************************************/ -int HardRemoveAcidicProtons( CANON_GLOBALS *pCG, - inp_ATOM *at, - int num_atoms, - BN_AATG *pAATG, - int num2remove, - int *nNumCanceledCharges, - BN_STRUCT *pBNS, - BN_DATA *pBD ) -{ - int cg_Plus = 0; - int cg_Minus = 0; - int tg_H_Other = 0; - int tg_H_Acid = 0; - - int ret = 0, ret2; - int nDelta, nNumMoved2AcidH = 0, nNumNeutralized = 0, nPrevNumCharges; /* djb-rwth: removing redundant variables */ - - int nPosCharges, nPosCharges2; - int nNegCharges, nNegCharges2; - /* - int nNumNP_H, nNumNP_H2; - int nNumOS_H, nNumOS_H2; - */ - - nPosCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - nNegCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - /* - nNumNP_H = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + - pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; - nNumOS_H = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + - pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + - pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; - */ - - /* Prevent free exchange H <-> (-) */ - pBNS->type_CN = ( BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_C_NEGATIVE ); - pBNS->type_T = BNS_VERT_TYPE_TGROUP; - pBNS->type_TACN = BNS_VERT_TYPE_ACID; - - /* Create (+) charge group */ - cg_Plus = CreateCGroupInBnStruct( at, num_atoms, pBNS, AR_HARD_TYP_POS, AR_HARD_MSK_POS, 1 ); - - /* create (-) charge group */ - /* - if ( nAtTypeTotals[ATTOT_NUM_CO_Minus] + - nAtTypeTotals[ATTOT_NUM_CS_Minus] + - nAtTypeTotals[ATTOT_NUM_ZO_Minus] + - nAtTypeTotals[ATTOT_NUM_N_Minus] ) - */ - - cg_Minus = CreateCGroupInBnStruct( at, num_atoms, pBNS, AR_HARD_TYP_NEG, AR_HARD_MSK_NEG, -1 ); - - pBNS->type_CN = ( BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_C_NEGATIVE ); - pBNS->type_T = BNS_VERT_TYPE_TGROUP; - pBNS->type_TACN = BNS_VERT_TYPE_ACID; - - /* Create tautomeric group for non-acidic or negatively charged acidic O */ - tg_H_Other = CreateTGroupInBnStruct( at, num_atoms, pBNS, AR_HARD_TYP_HN, AR_HARD_MSK_HN ); - if (tg_H_Other) /* djb-rwth: fixing coverity CID #499503 */ - { - return BNS_PROGRAM_ERR; - } - - /* Create tautomeric group for possibly acidic O */ - tg_H_Acid = CreateTGroupInBnStruct( at, num_atoms, pBNS, AR_HARD_TYP_HA, AR_HARD_MSK_HA ); - if (tg_H_Other >= num_atoms && tg_H_Acid >= num_atoms) - { - /* Find alt path to remove one proton */ - do - { - /* Remove a proton */ - nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; - ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, - at, num_atoms, - tg_H_Other /*nVertDoubleBond*/, - tg_H_Acid /*nVertSingleBond*/, - ALT_PATH_MODE_REM_PROTON ); - if (IS_BNS_ERROR( ret )) - { - return ret; - } - if (ret & 1) - { - nDelta = ( ret & ~3 ) >> 2; - /* djb-rwth: removing redundant code */ - if (nDelta) - { - /* Radical pair has disappeared */ - ; /* goto quick_exit;*/ - } - nNumMoved2AcidH++; - if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + 1) - { - nNumNeutralized += ( nPrevNumCharges - ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - 1 ) ) / 2; - } - } - } while (( ret & 1 ) && nNumMoved2AcidH < num2remove); - - /* Neutralize: remove ion pairs like >N(+)=-O(-) => >N-=O */ - if (( nNumMoved2AcidH /*|| bCancelChargesAlways*/ ) && cg_Minus >= num_atoms && cg_Plus >= num_atoms && - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] > abs( pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] )) - { - do - { - nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; - ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, - at, num_atoms, - cg_Minus /*nVertDoubleBond*/, - cg_Plus /*nVertSingleBond*/, - ALT_PATH_MODE_REM_PROTON ); - if (IS_BNS_ERROR( ret )) - { - return ret; - } - if (ret & 1) - { - nDelta = ( ret & ~3 ) >> 2; - /* djb-rwth: removing redundant code */ - if (nDelta) - { - /* Radical pair has disappeared */ - ; /* goto quick_exit;*/ - } - if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]) - { - nNumNeutralized += ( nPrevNumCharges - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] ) / 2; - } - } - } while (ret & 1); - } - } - - ret = 0; - if (tg_H_Acid >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, tg_H_Acid, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - if (tg_H_Other >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, tg_H_Other, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - if (cg_Minus >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Minus, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - if (cg_Plus >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Plus, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - - pBNS->type_CN = 0; - pBNS->type_T = 0; - pBNS->type_TACN = 0; - - if (ret) - { - return ret; - } - - if (pAATG->nAtTypeTotals[ATTOT_NUM_CO_Minus] + pAATG->nAtTypeTotals[ATTOT_NUM_ZO_Minus] && - pAATG->nAtTypeTotals[ATTOT_NUM_N_Minus]) - { - } - - nPosCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - nNegCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - /* - nNumNP_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + - pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; - nNumOS_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + - pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + - pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; - */ - if (( nPosCharges - nNegCharges ) - ( nPosCharges2 - nNegCharges2 ) != 0) - { - return BNS_PROGRAM_ERR; - } - - if (nNumCanceledCharges) - { -#if ( FIX_CANCEL_CHARGE_COUNT_BUG == 1 ) - *nNumCanceledCharges += 2 * nNumNeutralized; -#else - *nNumCanceledCharges = 2 * nNumNeutralized; -#endif - } - - return nNumMoved2AcidH; -} - - -/****************************************************************************/ -int HardAddAcidicProtons( CANON_GLOBALS *pCG, - inp_ATOM *at, - int num_atoms, - BN_AATG *pAATG, - int num2add, - int *nNumCanceledCharges, - BN_STRUCT *pBNS, - BN_DATA *pBD ) -{ - int cg_Plus = 0; - int cg_Minus_CO = 0; - int cg_Minus_Other = 0; - int tg_H = 0; - - int ret = 0, ret2; - int nDelta, nNumChanges = 0, nNumMoved2AcidMinus = 0, nNumNeutralized = 0, nPrevNumCharges; /* djb-rwth: removing redundant variables */ - - int nPosCharges, nPosCharges2; - int nNegCharges, nNegCharges2; - /* - int nNumNP_H, nNumNP_H2; - int nNumOS_H, nNumOS_H2; - */ - nPosCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - nNegCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - /* - nNumNP_H = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + - pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; - nNumOS_H = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + - pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + - pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; - */ - - /* Prevent free exchange H <-> (-) */ - pBNS->type_CN = ( BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_C_NEGATIVE ); - pBNS->type_T = BNS_VERT_TYPE_TGROUP; - pBNS->type_TACN = BNS_VERT_TYPE_ACID; - - /* Create (+) charge group */ - cg_Plus = CreateCGroupInBnStruct( at, num_atoms, pBNS, AA_HARD_TYP_POS, AA_HARD_MSK_POS, 1 ); - - /* Create (-) charge group */ - /* - if ( nAtTypeTotals[ATTOT_NUM_CO_Minus] + - nAtTypeTotals[ATTOT_NUM_CS_Minus] + - nAtTypeTotals[ATTOT_NUM_ZO_Minus] + - nAtTypeTotals[ATTOT_NUM_N_Minus] ) - */ - cg_Minus_CO = CreateCGroupInBnStruct( at, num_atoms, pBNS, AA_HARD_TYP_CO, AA_HARD_MSK_CO, -1 ); - if (cg_Minus_CO < 0) /* djb-rwth: fixing coverity CID #499474 */ - { - return BNS_PROGRAM_ERR; - } - - cg_Minus_Other = CreateCGroupInBnStruct( at, num_atoms, pBNS, AA_HARD_TYP_NEG, AA_HARD_MSK_NEG, -1 ); - - pBNS->type_CN = ( BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_C_NEGATIVE ); - pBNS->type_T = BNS_VERT_TYPE_TGROUP; - pBNS->type_TACN = BNS_VERT_TYPE_ACID; - - /* Create tautomeric group for all H */ - tg_H = CreateTGroupInBnStruct( at, num_atoms, pBNS, AA_HARD_TYP_H, AA_HARD_MSK_H ); - - if (cg_Minus_Other >= num_atoms && cg_Minus_CO >= num_atoms) - { - /* Find alt path to remove one proton */ - do - { - /* Add a proton */ - nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; - ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, - at, num_atoms, - cg_Minus_Other /*nVertDoubleBond*/, - cg_Minus_CO /*nVertSingleBond*/, - ALT_PATH_MODE_REM_PROTON ); - if (IS_BNS_ERROR( ret )) - { - return ret; - } - if (ret & 1) - { - nDelta = ( ret & ~3 ) >> 2; - nNumChanges += (0 != (ret & 2)); /* djb-rwth: ignoring LLVM warning: variable used */ - if (nDelta) - { - /* Radical pair has disappeared */ - ; /* goto quick_exit;*/ - } - nNumMoved2AcidMinus++; - if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + 1) - { - nNumNeutralized += ( nPrevNumCharges - ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - 1 ) ) / 2; - } - } - } while (( ret & 1 ) && nNumMoved2AcidMinus < num2add); - - /* Neutralize: remove ion pairs like >N(+)=-O(-) => >N-=O */ - if (( nNumMoved2AcidMinus /*|| bCancelChargesAlways*/ ) && - cg_Minus_Other >= num_atoms && cg_Plus >= num_atoms && - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] > abs( pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] )) - { - do - { - nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; - ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, - at, num_atoms, - cg_Minus_Other /*nVertDoubleBond*/, - cg_Plus /*nVertSingleBond*/, - ALT_PATH_MODE_REM_PROTON ); - if (IS_BNS_ERROR( ret )) - { - return ret; - } - if (ret & 1) - { - nDelta = ( ret & ~3 ) >> 2; - nNumChanges += (0 != (ret & 2)); /* djb-rwth: ignoring LLVM warning: variable used */ - if (nDelta) - { - /* Radical pair has disappeared */ - ; /* goto quick_exit;*/ - } - if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]) - { - nNumNeutralized += ( nPrevNumCharges - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] ) / 2; - } - } - } while (ret & 1); - } - } - - ret = 0; - if (tg_H >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, tg_H, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - if (cg_Minus_Other >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Minus_Other, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - if (cg_Minus_CO >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Minus_CO, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - if (cg_Plus >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Plus, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - - pBNS->type_CN = 0; - pBNS->type_T = 0; - pBNS->type_TACN = 0; - - if (ret) - { - return ret; - } - - if (pAATG->nAtTypeTotals[ATTOT_NUM_CO_Minus] + pAATG->nAtTypeTotals[ATTOT_NUM_ZO_Minus] && - pAATG->nAtTypeTotals[ATTOT_NUM_N_Minus]) - { - } - - nPosCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - nNegCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - /* - nNumNP_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + - pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; - nNumOS_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + - pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + - pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; - */ - - if (( nPosCharges - nNegCharges ) - ( nPosCharges2 - nNegCharges2 ) != 0) - { - return BNS_PROGRAM_ERR; - } - - if (nNumCanceledCharges) - { -#if ( FIX_CANCEL_CHARGE_COUNT_BUG == 1 ) - *nNumCanceledCharges += 2 * nNumNeutralized; -#else - *nNumCanceledCharges = 2 * nNumNeutralized; -#endif - } - - return nNumMoved2AcidMinus; -} - - -/**************************************************************************** -HardRemoveHplusNP( ... ) - -Examples include removal of H from tautomeric O -that belongs to the same t-group as N: - ->N(+)=-N=-OH =(taut.) => ->N(+)=-NH-=O =(+charge move) => ->N-=NH(+)-=O => >N-=N-=O + H(+) -****************************************************************************/ -int HardRemoveHplusNP( CANON_GLOBALS *pCG, - inp_ATOM *at, - int num_atoms, - int bCancelChargesAlways, - int *nNumCanceledCharges, - BN_AATG *pAATG, - BN_STRUCT *pBNS, - BN_DATA *pBD ) -{ - - int cg_Plus = 0; - int cg_Minus = 0; - int tg_H = 0; -#if ( MOVE_PPLUS_TO_REMOVE_PROTONS == 1 ) - int cg_PlusP = 0; -#endif -#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) - int nPrevRemovedProtons, nCurrRemovedProtons; -#endif - int ret = 0, ret2; - int nDelta, nNumChanges = 0, nNumRemovedProtons = 0, nNumNeutralized = 0, nPrevNumCharges; /* djb-rwth: ignoring LLVM warning: variable used */ - - int nPosCharges, nPosCharges2; - int nNegCharges, nNegCharges2; - /* - int nNumNP_H, nNumNP_H2; - int nNumOS_H, nNumOS_H2; - */ - - nPosCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - nNegCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - /* - nNumNP_H = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + - pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; - nNumOS_H = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + - pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + - pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; - */ - - /* Prevent free exchange H <-> (-) */ - pBNS->type_CN = ( BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_C_NEGATIVE ); - pBNS->type_T = BNS_VERT_TYPE_TGROUP; - pBNS->type_TACN = BNS_VERT_TYPE_ACID; - - /* Create (+) charge group */ - cg_Plus = CreateCGroupInBnStruct( at, num_atoms, pBNS, PR_HARD_TYP_POS, PR_HARD_MSK_POS, 1 ); - - /* Create (-) charge group */ - /* - if ( nAtTypeTotals[ATTOT_NUM_CO_Minus] + - nAtTypeTotals[ATTOT_NUM_CS_Minus] + - nAtTypeTotals[ATTOT_NUM_ZO_Minus] + - nAtTypeTotals[ATTOT_NUM_N_Minus] ) - */ -#if ( MOVE_PPLUS_TO_REMOVE_PROTONS == 1 ) - cg_PlusP = CreateCGroupInBnStruct( at, num_atoms, pBNS, PR_HARD_TYP_POSP, PR_HARD_MSK_POS, 1 ); -#endif - cg_Minus = CreateCGroupInBnStruct( at, num_atoms, pBNS, PR_HARD_TYP_NEG, PR_HARD_MSK_NEG, -1 ); - - /* Create single tautomeric group */ - tg_H = CreateTGroupInBnStruct( at, num_atoms, pBNS, PR_HARD_TYP_H, PR_HARD_MSK_H ); - if (tg_H < 0) /* djb-rwth: fixing coverity CID #499572 */ - { - return BNS_PROGRAM_ERR; - } - - if (tg_H >= num_atoms && cg_Plus >= num_atoms) - { - -#if ( FIX_N_MINUS_NORN_BUG == 1 ) - /* neutralize: remove ion pairs like >N(+)=-O(-) => >N-=O; >N(+)=-NH(-) => >N-=NH */ - if (( nNumRemovedProtons || bCancelChargesAlways ) && cg_Minus >= num_atoms && cg_Plus >= num_atoms && - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] > abs( pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] )) - { - do - { - nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; -#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) - nPrevRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; -#endif - ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, at, num_atoms, - cg_Minus /*nVertDoubleBond*/, cg_Plus /*nVertSingleBond*/, ALT_PATH_MODE_REM_PROTON ); - if (IS_BNS_ERROR( ret )) - { - return ret; - } -#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) - nCurrRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; - if (nCurrRemovedProtons != nPrevRemovedProtons) - { - return BNS_RADICAL_ERR; - } -#endif - if (ret & 1) - { - nDelta = ( ret & ~3 ) >> 2; - nNumChanges += ( 0 != ( ret & 2 ) ); - if (nDelta) - { - /* radical pair has disappeared */ - ; /* goto quick_exit;*/ - } - if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]) - { - nNumNeutralized += ( nPrevNumCharges - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] ) / 2; - } - } - } while (ret & 1); - } -#endif - - /* Find alt path to remove one proton */ - do - { - /* Remove a proton */ - nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; -#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) - nPrevRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; -#endif - ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, at, num_atoms, - tg_H /*nVertDoubleBond*/, - cg_Plus /*nVertSingleBond*/, - ALT_PATH_MODE_REM_PROTON ); - if (IS_BNS_ERROR( ret )) - { - return ret; - } -#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) - nCurrRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; - if (nCurrRemovedProtons != nPrevRemovedProtons + ( ret & 1 )) - { - return BNS_RADICAL_ERR; - } -#endif - if (ret & 1) - { - nDelta = ( ret & ~3 ) >> 2; - nNumChanges += (0 != (ret & 2)); /* djb-rwth: ignoring LLVM warning: variable used */ - if (nDelta) - { - /* radical pair has disappeared */ - ; /* goto quick_exit;*/ - } - nNumRemovedProtons++; - if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + 1) - { - nNumNeutralized += ( nPrevNumCharges - ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - 1 ) ) / 2; - } - } - } while (ret & 1); - - /* Neutralize: remove ion pairs like >N(+)=-O(-) => >N-=O */ - if (( nNumRemovedProtons || bCancelChargesAlways ) && cg_Minus >= num_atoms && cg_Plus >= num_atoms && - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] > abs( pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] )) - { - do - { - nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; -#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) - nPrevRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; -#endif - ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, at, num_atoms, - cg_Minus /*nVertDoubleBond*/, - cg_Plus /*nVertSingleBond*/, - ALT_PATH_MODE_REM_PROTON ); - if (IS_BNS_ERROR( ret )) - { - return ret; - } -#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) - nCurrRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; - if (nCurrRemovedProtons != nPrevRemovedProtons) - { - return BNS_RADICAL_ERR; - } -#endif - if (ret & 1) - { - nDelta = ( ret & ~3 ) >> 2; - nNumChanges += (0 != (ret & 2)); /* djb-rwth: ignoring LLVM warning: variable used */ - if (nDelta) - { - /* Radical pair has disappeared */ - ; /* goto quick_exit;*/ - } - if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]) - { - nNumNeutralized += ( nPrevNumCharges - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] ) / 2; - } - } - } while (ret & 1); - } - } - - ret = 0; - if (tg_H >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, tg_H, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - if (cg_Minus >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Minus, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } -#if ( MOVE_PPLUS_TO_REMOVE_PROTONS == 1 ) - if (cg_PlusP >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_PlusP, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } -#endif - if (cg_Plus >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Plus, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - - pBNS->type_CN = 0; - pBNS->type_T = 0; - pBNS->type_TACN = 0; - - if (ret) - { - return ret; - } - - if (pAATG->nAtTypeTotals[ATTOT_NUM_CO_Minus] + pAATG->nAtTypeTotals[ATTOT_NUM_ZO_Minus] && - pAATG->nAtTypeTotals[ATTOT_NUM_N_Minus]) - { - } - - nPosCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - nNegCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - /* - nNumNP_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + - pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; - nNumOS_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + - pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + - pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; - */ - - if (( nPosCharges - nNegCharges ) - ( nPosCharges2 - nNegCharges2 ) != nNumRemovedProtons) - { - return BNS_PROGRAM_ERR; - } - - if (nNumCanceledCharges) - { -#if ( FIX_CANCEL_CHARGE_COUNT_BUG == 1 ) - *nNumCanceledCharges += 2 * nNumNeutralized; -#else - *nNumCanceledCharges = 2 * nNumNeutralized; -#endif - } - - return nNumRemovedProtons; -} - - -/****************************************************************************/ -int mark_at_type( inp_ATOM *atom, int num_atoms, int nAtTypeTotals[] ) -{ - int i, max_num_ions, mask, type; - /*int max_protons, max_O_Minus, num_H = 0, num_CO=0;*/ - - if (nAtTypeTotals) - { - memset( nAtTypeTotals, 0, ATTOT_ARRAY_LEN * sizeof( nAtTypeTotals[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - } - - for (i = 0; i < num_atoms; i++) - { - type = GetAtomChargeType( atom, i, nAtTypeTotals, &mask, 0 ); - atom[i].at_type = type; - /* - num_H += ((type & PR_HARD_TYP_H) && (mask & ATBIT_MSK_H)); - num_CO += ((type & AR_HARD_TYP_HA) && (mask & AR_HARD_MSK_HA)); - */ - } - - if (nAtTypeTotals) - { - /* - max_protons = nAtTypeTotals[ATTOT_NUM_NP_Proton] + - inchi_min(num_H, nAtTypeTotals[ATTOT_NUM_NP_Plus]); - max_O_Minus = nAtTypeTotals[ATTOT_NUM_CO_Minus] + nAtTypeTotals[ATTOT_NUM_CS_Minus] + - nAtTypeTotals[ATTOT_NUM_ZO_Minus] + nAtTypeTotals[ATTOT_NUM_OO_Minus] + - nAtTypeTotals[ATTOT_NUM_ZOO_Minus] + nAtTypeTotals[ATTOT_NUM_NO_Minus] + - nAtTypeTotals[ATTOT_NUM_O_Minus] +nAtTypeTotals[ATTOT_NUM_N_Minus]; - ; - max_num_ions = max_protons + max_O_Minus + nAtTypeTotals[ATTOT_NUM_CHARGES]; - */ - max_num_ions = nAtTypeTotals[ATTOT_NUM_CHARGES]; - } - else - { - max_num_ions = 0; - } - - return max_num_ions; -} - - -/****************************************************************************/ -int RemoveNPProtonsAndAcidCharges( CANON_GLOBALS *pCG, - inp_ATOM *at, - int num_atoms, - BN_AATG *pAATG, - BN_STRUCT *pBNS, - BN_DATA *pBD ) -{ - - /* Prepare data structure */ - int num; - int nNumCanceledCharges = 0; - /* djb-rwth: removing redundant variables */ - T_GROUP_INFO *t_group_info = pAATG->t_group_info; - int ret = 0, bError = 0; - - int bAllowHardRemove = ( t_group_info->bTautFlags & TG_FLAG_TEST_TAUT__SALTS ) && - ( t_group_info->bTautFlags & TG_FLAG_TEST_TAUT2_SALTS ) && - ( t_group_info->bTautFlags & TG_FLAG_MOVE_POS_CHARGES ) && - ( t_group_info->bTautFlags & TG_FLAG_HARD_ADD_REM_PROTONS ); - - if (pAATG->nMarkedAtom && num_atoms < pAATG->nAllocLen) - { - inchi_free( pAATG->nMarkedAtom ); - qzfree( pAATG->nEndPoint ); - memset( pAATG, 0, sizeof( *pAATG ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - } - - if (!pAATG->nMarkedAtom && ( pAATG->nMarkedAtom = (S_CHAR *) inchi_malloc( num_atoms * sizeof( pAATG->nMarkedAtom[0] ) ) )) - { - pAATG->nAllocLen = num_atoms; - pAATG->nNumFound = 0; - } - - /* o TECHMAN-5.1. Remove protons from charged heteroatoms */ - - /* (TECHMAN-5.1a) Simple remove of protons from N, P, and O,S,Se,Te */ - if ((num = pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton] + pAATG->nAtTypeTotals[ATTOT_NUM_OH_Plus])) /* djb-rwth: addressing LLVM warning */ - { - ret = SimpleRemoveHplusNPO( at, num_atoms, pAATG->nAtTypeTotals, t_group_info ); - if (ret != num) - { - bError = BNS_PROGRAM_ERR; - goto exit_function; - } - /*t_group_info->nNumRemovedProtons += ret;*/ - t_group_info->tni.bNormalizationFlags |= ( ret > 0 ) ? FLAG_PROTON_NPO_SIMPLE_REMOVED : 0; - } - - if (( num = pAATG->nAtTypeTotals[ATTOT_NUM_NP_Plus] ) && bAllowHardRemove) /* djb-rwth: ignoring LLVM warning: variable used */ - { - /* [TECHMAN-5.1b] Hard removing more protons from cationic N; charges may be canceled */ - ret = HardRemoveHplusNP( pCG, at, num_atoms, 1, &nNumCanceledCharges, pAATG, pBNS, pBD ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - /* djb-rwth: removing redundant code */ - /*t_group_info->nNumRemovedProtons += ret;*/ - t_group_info->tni.bNormalizationFlags |= ( ret > 0 ) ? FLAG_PROTON_NP_HARD_REMOVED : 0; - } - - if (pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] > 0) - { - /* o TECHMAN-5.2. Remove protons from neutral heteroatoms */ - - /* (TECHMAN-5.2a) Simple removal */ - ret = SimpleRemoveAcidicProtons( at, num_atoms, pAATG, pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - - /*t_group_info->nNumRemovedProtons += ret;*/ - t_group_info->tni.bNormalizationFlags |= ( ret > 0 ) ? FLAG_PROTON_AC_SIMPLE_REMOVED : 0; - - - if (pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] > 0 && bAllowHardRemove) - { - /* (TECHMAN-5.2b) Hard removal */ - ret = HardRemoveAcidicProtons(pCG, at, num_atoms, pAATG, pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE], &nNumCanceledCharges, pBNS, pBD); - if (IS_BNS_ERROR(ret)) - { - bError = ret; - goto exit_function; - } - if (ret > 0) - { - int ret2 = SimpleRemoveAcidicProtons(at, num_atoms, pAATG, ret); - if (ret2 != ret) - { - bError = BNS_PROGRAM_ERR; - goto exit_function; - } - /*t_group_info->nNumRemovedProtons += ret;*/ - t_group_info->tni.bNormalizationFlags |= (ret > 0) ? FLAG_PROTON_AC_HARD_REMOVED : 0; - /* djb-rwth: removing redundant code */ - } - } - - - } - else - { - if (pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] < 0) - { - ret = SimpleAddAcidicProtons( at, num_atoms, pAATG, -pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - /*t_group_info->nNumRemovedProtons -= ret;*/ - /* - CHECK_TACN == 1 prohibits replacing (-) on N with H unless H can be moved to N - along an alternating path from another heteroatom (t-group will be detected). - */ - t_group_info->tni.bNormalizationFlags |= ( ret > 0 ) ? FLAG_PROTON_AC_SIMPLE_ADDED : 0; - if (pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] < 0 && bAllowHardRemove) - { - ret = HardAddAcidicProtons( pCG, at, num_atoms, pAATG, -pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE], &nNumCanceledCharges, pBNS, pBD ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - if (ret > 0) - { - int ret2 = SimpleAddAcidicProtons( at, num_atoms, pAATG, ret ); - if (ret2 != ret) - { - bError = BNS_PROGRAM_ERR; - goto exit_function; - } - /*t_group_info->nNumRemovedProtons -= ret;*/ - t_group_info->tni.bNormalizationFlags |= FLAG_PROTON_AC_HARD_ADDED; /* djb-rwth: fixing coverity CID #499527 */ - /* djb-rwth: removing redundant code */ - } - } - } - } - - t_group_info->tni.bNormalizationFlags |= nNumCanceledCharges ? FLAG_PROTON_CHARGE_CANCEL : 0; - -exit_function: - if (bError) - { - ret = IS_BNS_ERROR( bError ) ? bError : BNS_PROGRAM_ERR; - } - - return ret; -} - - -/**************************************************************************** -Main normalization procedure -****************************************************************************/ -int mark_alt_bonds_and_taut_groups( struct tagINCHI_CLOCK *ic, - struct tagCANON_GLOBALS *pCG, - inp_ATOM *at, - inp_ATOM *at_fixed_bonds_out, - int num_atoms, - struct tagInchiTime *ulTimeOutTime, - T_GROUP_INFO *t_group_info, - INCHI_MODE *inpbTautFlags, - INCHI_MODE *inpbTautFlagsDone, - int nebend, - int *ebend ) - - -{ - BN_STRUCT *pBNS = NULL; - BN_DATA *pBD = NULL; - int bError, nChanges, taut_found, salt_found, salt_pass, salt_step, ret, ret2, num, num_changed_bonds; /* djb-rwth: removing redundant variables */ - int max_altp = BN_MAX_ALTP; - int bChangeFlow = ( BNS_EF_CHNG_RSTR | BNS_EF_ALTR_BONDS ); - BNS_FLOW_CHANGES fcd[BNS_MAX_NUM_FLOW_CHANGES + 1]; - C_GROUP_INFO CGroupInfo; - C_GROUP_INFO *c_group_info = &CGroupInfo; - S_GROUP_INFO SGroupInfo; - S_GROUP_INFO *s_group_info = &SGroupInfo; - INCHI_MODE *pbTautFlags = t_group_info ? &t_group_info->bTautFlags : inpbTautFlags; - INCHI_MODE *pbTautFlagsDone = t_group_info ? &t_group_info->bTautFlagsDone : inpbTautFlagsDone; - - int nAtTypeTotals[ATTOT_ARRAY_LEN]; - int nNumOrigTotAtoms; - - BN_AATG aatg; - BN_AATG *pAATG = &aatg; - -#ifdef FIX_AROM_RADICAL /* Added 2011-05-09 IPl */ - int i, n_arom_radicals = 0, *stored_radicals = NULL; -#endif - int at_prot; /* moved from below 2024-09-01 DT */ - - nChanges = 0; - bError = 0; - - memset( c_group_info, 0, sizeof( *c_group_info ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - memset( s_group_info, 0, sizeof( *s_group_info ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - memset( pAATG, 0, sizeof( *pAATG ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - - /*(@nnuk : Nauman Ullah Khan) :: Variable for checking (De)protonation status */ - LOG_NO_ARGS("\n############# Initial state before (De)Protonation (L5373:ichi_bns.c) ###############\n"); - for (at_prot = 0; at_prot < num_atoms; at_prot++) - { - LOG_MULT_ARGS("Atom %d: Element: %s, Num_H: %d, Charge: %hhd, Radical: %d\n", at_prot, at[at_prot].elname, at[at_prot].num_H, at[at_prot].charge, at[at_prot].radical); - } - LOG_NO_ARGS("\n#####################################################################################\n"); - - -#ifdef FIX_AROM_RADICAL /* Added 2011-05-09 IPl */ - for (i = 0; i < num_atoms; i++) - { - if (( at[i].radical == RADICAL_DOUBLET ) && ( at[i].valence == 2 ) && - ( at[i].bond_type[0] == BOND_ALTERN ) && ( at[i].bond_type[1] == BOND_ALTERN )) - { - n_arom_radicals++; - if (!stored_radicals) - { - stored_radicals = (int *) inchi_calloc( num_atoms, sizeof( int ) ); - /* 2011-08-05 explicit cast added due to Evan Bolton */ - if (!stored_radicals) - { - bError = BNS_OUT_OF_RAM; - goto exit_function; - } - stored_radicals[i] = RADICAL_DOUBLET; - at[i].radical = 0; - at[i].num_H++; - } - } - } - -#endif - - if (( *pbTautFlags & TG_FLAG_MOVE_POS_CHARGES ) && num_atoms > 1) - { - /* Charge groups memory allocation */ - c_group_info->c_group = (C_GROUP *) inchi_calloc( num_atoms / 2, sizeof( c_group_info->c_group[0] ) ); - c_group_info->c_candidate = (C_CANDIDATE*) inchi_calloc( num_atoms, sizeof( c_group_info->c_candidate[0] ) ); - if (c_group_info->c_group && c_group_info->c_candidate) - { - c_group_info->max_num_c_groups = num_atoms / 2; - c_group_info->max_num_candidates = num_atoms; - } - else - { - bError = BNS_OUT_OF_RAM; /* error: out of RAM */ - /*printf("BNS_OUT_OF_RAM-1: num_at=%d, c_gr=%lx c_can=%lx\n", num_atoms, c_group_info->c_group, c_group_info->c_candidate);*/ - goto exit_function; - } - } - - if (*pbTautFlags & TG_FLAG_TEST_TAUT__SALTS) - { - if (t_group_info) - { - /* Salt groups memory allocation */ - s_group_info->s_candidate = - (S_CANDIDATE*) inchi_calloc( num_atoms, - sizeof( s_group_info->s_candidate[0] ) ); - if (s_group_info->s_candidate) - { - s_group_info->max_num_candidates = num_atoms; - } - else - { - bError = BNS_OUT_OF_RAM; /* error: out of RAM */ - /*printf("BNS_OUT_OF_RAM-2\n");*/ - goto exit_function; - } - } - } - - if (t_group_info) - { - if (t_group_info->tGroupNumber) - { - inchi_free( t_group_info->tGroupNumber ); - } - t_group_info->tGroupNumber = (AT_NUMB *) inchi_calloc( 2 * (long long)num_atoms + 1, sizeof( t_group_info->tGroupNumber[0] ) ); /* djb-rwth: cast operator added */ - if (!t_group_info->tGroupNumber) - { - /*printf("BNS_OUT_OF_RAM-9\n");*/ - bError = BNS_OUT_OF_RAM; /* error: out of RAM */ - goto exit_function; - } - num = t_group_info->tni.nNumRemovedExplicitH; - memset( &t_group_info->tni, 0, sizeof( t_group_info->tni ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - t_group_info->tni.nNumRemovedExplicitH = num; - } - - /* - again: - */ - - /* Allocate Balanced Network Data Strucures; replace Alternating bonds with Single */ - if (( pBNS = AllocateAndInitBnStruct( at, num_atoms, - BNS_ADD_ATOMS, BNS_ADD_EDGES, - max_altp, &num_changed_bonds ) ) - && - ( pBD = AllocateAndInitBnData( pBNS->max_vertices ) )) - { - - - pBNS->pbTautFlags = pbTautFlags; /* carry through all functions */ - pBNS->pbTautFlagsDone = pbTautFlagsDone; /* carry through all functions */ - - pBNS->ulTimeOutTime = ulTimeOutTime; /* v. 1.05 */ - pBNS->ic = ic; /* v. 1.05 */ - -#if ( BNS_PROTECT_FROM_TAUT == 1 ) - /* Protect bonds to acetyl and nitro */ - SetForbiddenEdges( pBNS, at, num_atoms, BNS_EDGE_FORBIDDEN_MASK, nebend, ebend ); -#endif - - /* Set bonds in case of input "aromatic" bonds or multiple radicals */ -#ifdef FIX_AROM_RADICAL /* Added 2011-05-09 IPl */ - if (n_arom_radicals) - { - ret = BnsAdjustFlowBondsRad( pBNS, pBD, at, num_atoms ); - if (stored_radicals) - { - for (i = 0; i < num_atoms; i++) - { - if (stored_radicals[i]) - { - at[i].radical = stored_radicals[i]; - at[i].num_H--; - } - } - } - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - } -#endif - - ret = BnsAdjustFlowBondsRad( pBNS, pBD, at, num_atoms ); - - /* (here pair(s) of radicals could have disappeared from the atoms) */ - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - pBNS->tot_st_flow += 2 * ret; - - /*return 0;*/ /* debug */ - /* djb-rwth: removing redundant code */ - - if (pBNS->tot_st_cap > pBNS->tot_st_flow) - { - /* has radical */ - bChangeFlow |= BNS_EF_SET_NOSTEREO; - } - - /******************************************************************** - * Remove protons from NH(+), but not PH(+) - * Add protons to COO(-) etc. - * or remove protons from COOH etc to make the organic part neutral - * Note: for now (-) from N(-) can be only canceled or moved to -C=O - ********************************************************************/ - if (( *pbTautFlags & TG_FLAG_VARIABLE_PROTONS ) && - t_group_info && - mark_at_type( at, num_atoms, nAtTypeTotals ) && - nAtTypeTotals[ATTOT_NUM_CHARGES]) - { - /* - the structure is simple to neutralize if it yields exactly - num[H(+)] = num[N,P H(+)] - num[N,S,O(-)] = num[=C-O(-)] + num[C-S(-)] + num[N(-)] + num[other O(-), S(-)] - - and n(p) = num[H(+)] - num[N,S,O(-)] (no protons, no negative N,O,S condition) - - Additional check is needed if: - min{num[N,PH], num[N,P(+), not onium]} > 0 - => possibility to yield more H(+) - - min_charge = orig_charge(P,N,O,S) - n(p) - n(OH,SH) - max_charge = orig_charge(P,N,O,S) - n(p) + n(O,S,N(-)) - */ - - nNumOrigTotAtoms = t_group_info->tni.nNumRemovedExplicitH + num_atoms; - pAATG->nAtTypeTotals = nAtTypeTotals; - pAATG->t_group_info = t_group_info; -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; -#endif - - /***********************************************************/ - /* */ - /* ( D E ) P R O T O N A T I O N */ - /* */ - /***********************************************************/ - - ret = RemoveNPProtonsAndAcidCharges( pCG, at, num_atoms, pAATG, pBNS, pBD ); - -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; -#endif - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - - if (t_group_info->tni.bNormalizationFlags) - { - SetInitCapFlowToCurrent( pBNS ); - if (at_fixed_bonds_out) - { - /* Copy modified initial tautomeric structure for displaying - Warning: implicit H counts in at_fixed_bonds_out include explicit Hs */ - - memcpy(at_fixed_bonds_out, at, nNumOrigTotAtoms * sizeof(at_fixed_bonds_out[0])); - - /* -- will be done in FillOutInputInfAtom() -- - RemoveExcessiveImplicitH( num_atoms, t_group_info->tni.nNumRemovedExplicitH, at_fixed_bonds_out ); - */ - } - } - } - - /****************** Initial bonds normalization ***************/ - - if (*pbTautFlags & TG_FLAG_MOVE_POS_CHARGES) - { - /******************* Find moveable positive charges **********************/ - do - { - /* Cycling while ret>0 added 2004-06-04 */ -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; - CorrectFixing_NH_NH_Bonds( pBNS, at, num_atoms ); -#endif - ret = MarkChargeGroups( pCG, at, num_atoms, - c_group_info, t_group_info, - pBNS, pBD ); - -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; -#endif - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - if (ret) - { - nChanges += ret; - ret2 = AddCGroups2BnStruct( pCG, pBNS, at, num_atoms, c_group_info ); - if (IS_BNS_ERROR( ret2 )) - { - bError = ret2; - goto exit_function; - } - *pbTautFlagsDone |= TG_FLAG_MOVE_POS_CHARGES_DONE; - } - } while (ret > 0); - - -#if ( BNS_RAD_SEARCH == 1 ) -#else - /* moveable charges may allow to cancel radicals -- check it */ - if (pBNS->tot_st_cap > pBNS->tot_st_flow) - { - ret = BnsAdjustFlowBondsRad( pBNS, pBD, at, num_atoms ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - if (ret > 0) - { - /* - pBNS->tot_st_flow += 2*ret; - ret = ReInitBnStruct( pBNS, at, num_atoms, 1 ); - if ( IS_BNS_ERROR( ret ) ) { - bError = ret; - goto exit_function; - } - */ - bError = BNS_RADICAL_ERR; - goto exit_function; - } - } -#endif - } - - /************************************************************************/ - /******** Test bonds for bond tautomerism **************/ - /******** replace moveable bonds with "alternating" bonds **************/ - /************************************************************************/ - ret = BnsTestAndMarkAltBonds( pBNS, pBD, at, num_atoms, fcd, bChangeFlow, 0 ); - - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - /* djb-rwth: removing redundant code */ - - /*********************** End of initial bonds normalization *************/ - - /* djb-rwth: removing redundant code */ - - /* Check for tautomerism */ - /* find new tautomer groups */ - salt_pass = 0; - salt_step = 0; - salt_found = 0; - - /*************************************************************/ - /* */ - /* M A I N C Y C L E B E G I N */ - /* */ - /*************************************************************/ - - do - { - /* djb-rwth: removing redundant code */ - nChanges = 0; - /* djb-rwth: removing redundant code */ - - /**************** Regular bond/H/(-)/positive charges tautomerism cycle begin **************/ - do - { - /* djb-rwth: removing redundant code */ - for (taut_found = 0; - 0 < ( ret = MarkTautomerGroups( pCG, at, num_atoms, - t_group_info, c_group_info, - pBNS, pBD ) ); - taut_found++) - { - ; - } - if (ret < 0) - { - bError = ret; - } - if (taut_found && !salt_pass) - { - *pbTautFlagsDone |= TG_FLAG_TEST_TAUT__ATOMS_DONE; - } - - if (taut_found || salt_found) - { - /****************** repeat bonds normalization ***************/ - ret = ReInitBnStructAddGroups( pCG, pBNS, at, num_atoms, - t_group_info, c_group_info ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } -#if ( BNS_RAD_SEARCH == 1 ) -#else - /* discovered moveable charges and H-atoms may allow to cancel radicals */ - if (pBNS->tot_st_cap > pBNS->tot_st_flow) - { - ret = BnsAdjustFlowBondsRad( pBNS, pBD, at, num_atoms ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - if (ret > 0) - { - /* - pBNS->tot_st_flow += 2*ret; - ret = ReInitBnStruct( pBNS, at, num_atoms, 1 ); - if ( IS_BNS_ERROR( ret ) ) { - bError = ret; - goto exit_function; - } - */ - bError = BNS_RADICAL_ERR; - goto exit_function; - } - } -#endif - /****************** Update bonds normalization ***************/ - if (*pbTautFlags & TG_FLAG_MOVE_POS_CHARGES) - { - /******************* Find moveable charges ***************/ - do - { - /* Cycling while ret>0 added 2004-06-04 */ -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; - CorrectFixing_NH_NH_Bonds( pBNS, at, num_atoms ); -#endif - - ret = MarkChargeGroups( pCG, at, num_atoms, - c_group_info, t_group_info, - pBNS, pBD ); -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; -#endif - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - nChanges += ret; - if (ret > 0) - { - ret2 = ReInitBnStructAddGroups( pCG, pBNS, - at, num_atoms, - t_group_info, - c_group_info ); - if (IS_BNS_ERROR( ret2 )) - { - bError = ret2; - goto exit_function; - } - *pbTautFlagsDone |= TG_FLAG_MOVE_POS_CHARGES_DONE; - } - } while (ret > 0); - } - - /************************************************************************/ - /******** Find moveable bonds: **************/ - /******** test bonds for bond tautomerism **************/ - /******** replace moveable bonds with "alternating" bonds **************/ - /************************************************************************/ - ret = BnsTestAndMarkAltBonds( pBNS, pBD, at, num_atoms, fcd, bChangeFlow, 0 ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - nChanges += ret; - /****************** End of update bonds normalization ***************/ - - } - salt_found = 0; - } while (taut_found && !bError); - - - /**************** Regular bond/H/(-)/positive charges tautomerism cycle end **************/ - - if (bError) - { - break; - } - - - /******************* 'Salt' tautomerism permitted *************************/ - if (*pbTautFlags & TG_FLAG_TEST_TAUT__SALTS) - { - - if (*pbTautFlags & TG_FLAG_TEST_TAUT2_SALTS) - { - /*********** Requested one or more "salt" attachement migrartion test ********/ - if (!nChanges && salt_pass && salt_step) - { - break; /* done */ - } - if (!salt_step) - { - /* Salt step 0: process one attachment migrartion */ -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; - CorrectFixing_NH_NH_Bonds( pBNS, at, num_atoms ); -#endif - salt_found = MarkSaltChargeGroups( pCG, at, num_atoms, - s_group_info, - t_group_info, - c_group_info, - pBNS, pBD ); -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; -#endif - if (salt_found < 0) - { - bError = salt_found; - break; - } - else - { - if (salt_found > 0) - { - *pbTautFlagsDone |= TG_FLAG_TEST_TAUT__SALTS_DONE; - } - } - salt_step = !salt_found; - /* if new 'salt' atoms have been found then repeat regular taut. search - * MarkTautomerGroups() and do not perform salt step 1 - * if new 'salt' atoms have NOT been found then switch to salt step 1 - * and never repeat salt step 0 for the current structure - */ - } - - if (salt_step /*|| - (t_group_info->tni.bNormalizationFlags & FLAG_NORM_CONSIDER_TAUT)*/) - { - /* Salt step 1: process more than one attachment migration */ -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; - CorrectFixing_NH_NH_Bonds( pBNS, at, num_atoms ); -#endif - salt_found = MarkSaltChargeGroups2( pCG, at, num_atoms, - s_group_info, - t_group_info, - c_group_info, - pBNS, pBD ); -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; -#endif - if (salt_found < 0) - { - bError = salt_found; - break; - } - else - { - if (salt_found == 1 || salt_found == 5) - { - *pbTautFlagsDone |= TG_FLAG_TEST_TAUT2_SALTS_DONE; - if (salt_found == 5) - { - *pbTautFlagsDone |= TG_FLAG_TEST_TAUT3_SALTS_DONE; - } - /* salt_found == 2 => only negative charges involved */ - } - } - } - - salt_pass++; - } - else - { - /* !( *pbTautFlags & TG_FLAG_TEST_TAUT2_SALTS ) */ - /*************** Requested only one attachement migration test **********/ - if (!nChanges && salt_pass) - { - /* One attachment migration */ - break; - } - /* Salt step 0: process one attachment migration */ -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; - CorrectFixing_NH_NH_Bonds( pBNS, at, num_atoms ); -#endif - salt_found = MarkSaltChargeGroups( pCG, at, num_atoms, - s_group_info, - t_group_info, - c_group_info, - pBNS, pBD ); -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; -#endif - if (salt_found < 0) - { - bError = salt_found; - break; - } - else - { - if (salt_found > 0) - { - *pbTautFlagsDone |= TG_FLAG_TEST_TAUT__SALTS_DONE; - } - } - salt_pass++; - } /* ( *pbTautFlags & TG_FLAG_TEST_TAUT2_SALTS ) */ - } /* ( *pbTautFlags & TG_FLAG_TEST_TAUT__SALTS ) */ - } while (salt_found && !bError); - - /*************************************************************/ - /* */ - /* M A I N C Y C L E E N D */ - /* */ - /*************************************************************/ - - - if (*pbTautFlags & TG_FLAG_MERGE_TAUT_SALTS) - { - if (!bError && s_group_info /*&& s_group_info->num_candidates > 0*/) - { - ret = MergeSaltTautGroups( pCG, at, num_atoms, s_group_info, - t_group_info, c_group_info, pBNS ); - if (ret < 0) - { - bError = ret; - } - else - { - if (ret > 0) - { - *pbTautFlagsDone |= TG_FLAG_MERGE_TAUT_SALTS_DONE; - } - } - } - } - - if (!bError && t_group_info && - ( t_group_info->bTautFlags & TG_FLAG_VARIABLE_PROTONS ) && - ( t_group_info->bTautFlagsDone & ( TG_FLAG_FOUND_ISOTOPIC_ATOM_DONE | TG_FLAG_FOUND_ISOTOPIC_H_DONE ) )) - { - ret = MakeIsotopicHGroup( at, num_atoms, s_group_info, t_group_info ); - if (ret < 0) - { - bError = ret; - } - } - - /* Success */ - - remove_alt_bond_marks( at, num_atoms ); - - /************************************************ - * Temporarily ignore all non-alternating bonds - * and mark non-ring alt bonds non-stereogenic - ************************************************/ - - ReInitBnStructForAltBns( pBNS, at, num_atoms, 0 ); - MarkRingSystemsAltBns( pBNS, 0 ); - MarkNonStereoAltBns( pBNS, at, num_atoms, 0 ); -#if ( FIX_EITHER_DB_AS_NONSTEREO == 1 ) - /* second time unknown ("Either") alternating bonds are treated as non-stereogenic */ - /* stereobonds bonds that lost stereo get "Either" stereo_type */ - ReInitBnStructForAltBns( pBNS, at, num_atoms, 1 ); - MarkRingSystemsAltBns( pBNS, 1 ); - MarkNonStereoAltBns( pBNS, at, num_atoms, 1 ); -#endif - } - else - { - bError = BNS_OUT_OF_RAM; - /*printf("BNS_OUT_OF_RAM-3\n");*/ - } - - /*(@nnuk : Nauman Ullah Khan) */ - LOG_NO_ARGS("\n################# Modified state after (De)Protonation (L6014:ichi_bns.c) ################\n"); - for (at_prot = 0; at_prot < num_atoms; at_prot++) - { - LOG_MULT_ARGS("Atom %d: Element: %s, Num_H: %d, Charge: %hhd, Radical: %d\n", at_prot, at[at_prot].elname, at[at_prot].num_H, at[at_prot].charge, at[at_prot].radical); - } - LOG_NO_ARGS("\n##########################################################################################\n"); - -exit_function: - - /* djb-rwth: ignoring LLVM warning: variables used to store functions return values */ - pBNS = DeAllocateBnStruct(pBNS); - pBD = DeAllocateBnData(pBD); - /*#if ( MOVE_CHARGES == 1 )*/ - if (c_group_info) - { - if (c_group_info->c_group) - { - inchi_free( c_group_info->c_group ); - } - if (c_group_info->c_candidate) - { - inchi_free( c_group_info->c_candidate ); - } - } - /*#endif*/ - if (s_group_info && s_group_info->s_candidate) - { - inchi_free( s_group_info->s_candidate ); - } - if (pAATG && pAATG->nMarkedAtom) - { - inchi_free( pAATG->nMarkedAtom ); - qzfree( pAATG->nEndPoint ); - /*qzfree( pAATG->nAtTypeTotals );*/ /* nAtTypeTotals is a stack array */ - } - if (t_group_info && t_group_info->tGroupNumber) - { - inchi_free( t_group_info->tGroupNumber ); - t_group_info->tGroupNumber = NULL; - } - - if (!bError && num_atoms == 1 && at[0].at_type == ATT_PROTON && t_group_info && !t_group_info->tni.nNumRemovedExplicitH) - { - /* remove single isolated proton */ - t_group_info->tni.nNumRemovedProtons = 1; - t_group_info->tni.bNormalizationFlags |= FLAG_PROTON_SINGLE_REMOVED; - if (at[0].iso_atw_diff) - { -#if ( FIX_CURE53_ISSUE_NULL_DEREFERENCE_MAKE_A_COPY_OF_T_GROUP_INFO==1 || defined(FIX_IMPOSSIBLE_H_ISOTOPE_BUG) ) - if (at[0].iso_atw_diff <= NUM_H_ISOTOPES) - { - /* djb-rwth: possible false positive oss-fuzz issue #39064660 */ - t_group_info->tni.nNumRemovedProtonsIsotopic[at[0].iso_atw_diff - 1] ++; - } -#else - t_group_info->tni.nNumRemovedProtonsIsotopic[at[0].iso_atw_diff - 1] ++; -#endif - } - if (at_fixed_bonds_out) - { - memcpy(at_fixed_bonds_out, at, num_atoms * sizeof(at_fixed_bonds_out[0])); - } - /*num_atoms --;*/ - } - - - /* - Additional currently unused info: - - nOrigDelta > 0: original structure has been changed - due to fiund augmenting path(s) - nChanges > 0: either alt. bonds or taut. groups have been found - */ - -#ifdef FIX_AROM_RADICAL /* Added 2011-05-09 IPl */ - if (stored_radicals) - { - inchi_free( stored_radicals ); - } -#endif - - return bError ? bError : num_atoms; /* ret = 0 => success, any other => error */ -} - - -/****************************************************************************/ -int nMaxFlow2Check( BN_STRUCT *pBNS, int iedge ) -{ - BNS_EDGE *pEdge = pBNS->edge + iedge; - int nMaxFlow = ( pEdge->cap & EDGE_FLOW_MASK ); /* edge cap */ - - if (nMaxFlow > MAX_BOND_EDGE_CAP) - { - nMaxFlow = MAX_BOND_EDGE_CAP; - } - return nMaxFlow; -} - - -/****************************************************************************/ -int nCurFlow2Check( BN_STRUCT *pBNS, int iedge ) -{ - BNS_EDGE *pEdge = pBNS->edge + iedge; - int nCurFlow = ( pEdge->flow & EDGE_FLOW_MASK ); /* edge flow */ - return nCurFlow; -} - - -/****************************************************************************/ -int nMinFlow2Check( BN_STRUCT *pBNS, int iedge ) -{ - BNS_EDGE *pEdge = pBNS->edge + iedge; - Vertex v1 = pEdge->neighbor1; - Vertex v2 = v1 ^ pEdge->neighbor12; - int f12 = ( pEdge->flow & EDGE_FLOW_MASK ); - int rescap1, rescap2, rescap12, i, iedge_i; - - if (f12 > 0) - { - for (i = 0, rescap1 = 0; i < pBNS->vert[v1].num_adj_edges; i++) - { - iedge_i = pBNS->vert[v1].iedge[i]; - if (iedge_i == iedge) - { - continue; - } - rescap1 += ( pBNS->edge[iedge_i].cap & EDGE_FLOW_MASK ) - ( pBNS->edge[iedge_i].flow & EDGE_FLOW_MASK ); - } - for (i = 0, rescap2 = 0; i < pBNS->vert[v2].num_adj_edges; i++) - { - iedge_i = pBNS->vert[v2].iedge[i]; - if (iedge_i == iedge) - { - continue; - } - rescap2 += ( pBNS->edge[iedge_i].cap & EDGE_FLOW_MASK ) - ( pBNS->edge[iedge_i].flow & EDGE_FLOW_MASK ); - } - rescap12 = inchi_min( rescap1, rescap2 ); - rescap12 = inchi_min( rescap12, f12 ); - return f12 - rescap12; - } - - return 0; -} - - -/****************************************************************************/ -int bSetBondsAfterCheckOneBond( BN_STRUCT *pBNS, - BNS_FLOW_CHANGES *fcd, - int nTestFlow, - inp_ATOM *at, - int num_atoms, - int bChangeFlow0 ) -{ - int ifcd, iedge, new_flow, ret_val, nChanges = 0, bError = 0; - int bChangeFlow; - Vertex v1, v2; - int ineigh1, ineigh2; - BNS_EDGE *pEdge; - - bChangeFlow0 &= ~BNS_EF_CHNG_RSTR; /* do not change pEdge flow in SetBondType */ - if (!bChangeFlow0) - { - return 0; - } - - bChangeFlow = ( bChangeFlow0 & ~BNS_EF_SET_NOSTEREO ); - - /* Find the next to the last changed */ - if (bChangeFlow0 & BNS_EF_SET_NOSTEREO) - { - for (ifcd = 0; NO_VERTEX != ( iedge = fcd[ifcd].iedge ); ifcd++) /* djb-rwth: ignoring LLVM warning: variable used */ - { - iedge = fcd[ifcd].iedge; - pEdge = pBNS->edge + iedge; - if (!pEdge->pass) - { - continue; - } - - if (!ifcd && nTestFlow >= 0) - { - new_flow = nTestFlow; - } - else - { - new_flow = (int) pEdge->flow; - } - - v1 = pEdge->neighbor1; - v2 = pEdge->neighbor12 ^ v1; - if (v1 < num_atoms && v2 < num_atoms && new_flow != pEdge->flow0) - { - if (( pBNS->vert[v1].st_edge.cap0 == pBNS->vert[v1].st_edge.flow0 ) != - ( pBNS->vert[v1].st_edge.cap == pBNS->vert[v1].st_edge.flow ) || - ( pBNS->vert[v2].st_edge.cap0 == pBNS->vert[v2].st_edge.flow0 ) != - ( pBNS->vert[v2].st_edge.cap == pBNS->vert[v2].st_edge.flow )) - { - bChangeFlow |= BNS_EF_SET_NOSTEREO; - nChanges |= BNS_EF_SET_NOSTEREO; - } - } - } - } - else - { - for (ifcd = 0; NO_VERTEX != ( iedge = fcd[ifcd].iedge ); ifcd++) /* djb-rwth: ignoring LLVM warning: variable used */ - { - ; - } - } - - /* restore in reversed order to correctly handle vertex changed more than once */ - for (ifcd -= 1; 0 <= ifcd; ifcd--) - { - - iedge = fcd[ifcd].iedge; - pEdge = pBNS->edge + iedge; - if (!pEdge->pass) - { - continue; - } - - if (!ifcd && nTestFlow >= 0) - { - new_flow = nTestFlow; - } - else - { - new_flow = (int) pEdge->flow; - } - - v1 = pEdge->neighbor1; - v2 = pEdge->neighbor12 ^ v1; - if (v1 < num_atoms && v2 < num_atoms && bChangeFlow && new_flow != pEdge->flow0) - { - ineigh1 = pEdge->neigh_ord[0]; - ineigh2 = pEdge->neigh_ord[1]; - ret_val = SetAtomBondType( pEdge, &at[v1].bond_type[ineigh1], &at[v2].bond_type[ineigh2], new_flow - pEdge->flow0, bChangeFlow ); - if (!IS_BNS_ERROR( ret_val )) - { - nChanges |= ( ret_val > 0 ); - } - else - { - bError = ret_val; - } - } - pEdge->pass = 0; - } - - return bError ? bError : nChanges; -} - - -/****************************************************************************/ -int bRestoreFlowAfterCheckOneBond( BN_STRUCT *pBNS, BNS_FLOW_CHANGES *fcd ) -{ - int ifcd, iedge; - Vertex v1, v2; - BNS_EDGE *pEdge; - - /* Find the next to the last changed */ - for (ifcd = 0; NO_VERTEX != ( iedge = fcd[ifcd].iedge ); ifcd++) /* djb-rwth: ignoring LLVM warning: variable used */ - { - ; - } - - /* Restore in reversed order to correctly handle vertex changed more than once */ - for (ifcd -= 1; 0 <= ifcd; ifcd--) - { - /* Restore edge flow & cap */ - iedge = fcd[ifcd].iedge; - pEdge = pBNS->edge + iedge; - pEdge->flow = fcd[ifcd].flow; - pEdge->cap = fcd[ifcd].cap; - pEdge->pass = 0; - - /* Restore st-flow, cap */ - if (NO_VERTEX != ( v1 = fcd[ifcd].v1 )) - { - pBNS->vert[v1].st_edge.flow = fcd[ifcd].flow_st1; - pBNS->vert[v1].st_edge.cap = fcd[ifcd].cap_st1; - pBNS->vert[v1].st_edge.pass = 0; - } - if (NO_VERTEX != ( v2 = fcd[ifcd].v2 )) - { - pBNS->vert[v2].st_edge.flow = fcd[ifcd].flow_st2; - pBNS->vert[v2].st_edge.cap = fcd[ifcd].cap_st2; - pBNS->vert[v2].st_edge.pass = 0; - } - } - - return 0; -} - - -/****************************************************************************/ -int bSetFlowToCheckOneBond( BN_STRUCT *pBNS, - int iedge, - int flow, - BNS_FLOW_CHANGES *fcd ) -{ - BNS_EDGE *pEdge = pBNS->edge + iedge; - int f12 = ( pEdge->flow & EDGE_FLOW_MASK ); /* the original flow */ - int ifcd = 0; - int nDots = 0; - int i, iedge_i; - - fcd[ifcd].iedge = NO_VERTEX; - - if (f12 < flow) - { - /* Increase edge flow: Grab flow from the neighbors and delete it: set flow12=cap12 = 0 */ - /************************************************************************************/ - /* For example, simulate a new fixed double bond in place of a single bond and */ - /* creates ONE or NONE (in case of a radical on adjacent atom) augmenting paths and */ - /* makes it impossible for the BNS to set same flow as it originally was */ - /************************************************************************************/ - Vertex v1 = pEdge->neighbor1; - Vertex v2 = v1 ^ pEdge->neighbor12; - Vertex v_i; /* neighbor of v1 or v2 */ - BNS_EDGE *pEdge_i; - int delta1, delta2, f, st_edge_rescap; - - if (( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) < flow || - ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) < flow) - { - return BNS_CANT_SET_BOND; - } - if (( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ) < f12 || - ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ) < f12) - { - return BNS_CAP_FLOW_ERR; - } - - fcd[ifcd].iedge = iedge; - fcd[ifcd].flow = pEdge->flow; - fcd[ifcd].cap = pEdge->cap; - - fcd[ifcd].v1 = v1; - fcd[ifcd].flow_st1 = pBNS->vert[v1].st_edge.flow; - fcd[ifcd].cap_st1 = pBNS->vert[v1].st_edge.cap; - - fcd[ifcd].v2 = v2; - fcd[ifcd].flow_st2 = pBNS->vert[v2].st_edge.flow; - fcd[ifcd].cap_st2 = pBNS->vert[v2].st_edge.cap; - - fcd[++ifcd].iedge = NO_VERTEX; /* mark the end of the fcd[] data */ - pEdge->pass |= 64; - - delta1 = delta2 = flow - f12; - - if (f12 > 0) - { - /* Remove old edge flow from the flow and cap of the adjacent vertices' st-edges */ - pBNS->vert[v1].st_edge.cap = ( ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v1].st_edge.cap & ~EDGE_FLOW_ST_MASK ); - pBNS->vert[v2].st_edge.cap = ( ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v2].st_edge.cap & ~EDGE_FLOW_ST_MASK ); - pBNS->vert[v1].st_edge.flow = ( ( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v1].st_edge.flow & ~EDGE_FLOW_ST_MASK ); - pBNS->vert[v2].st_edge.flow = ( ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v2].st_edge.flow & ~EDGE_FLOW_ST_MASK ); - /* Delete current edge flow and capacity */ - pEdge->flow = ( pEdge->flow & ~EDGE_FLOW_MASK ); - } - pEdge->cap = ( pEdge->cap & ~EDGE_FLOW_MASK ); - - /* Grab the adjacent vertex1 radical (st_edge_rescap) if it exists */ - st_edge_rescap = ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) - ( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ); - while (st_edge_rescap && delta1) - { - st_edge_rescap--; /* grab the radical */ - delta1--; - pBNS->vert[v1].st_edge.cap = ( ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v1].st_edge.cap & ~EDGE_FLOW_ST_MASK ); - nDots--; - } - - /* Grab the adjacent vertex2 radical (st_edge_rescap) if it exists */ - st_edge_rescap = ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) - ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ); - while (st_edge_rescap && delta2) - { - st_edge_rescap--; /* grab the radical */ - delta2--; - pBNS->vert[v2].st_edge.cap = ( ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v2].st_edge.cap & ~EDGE_FLOW_ST_MASK ); - nDots--; - } - - /* Grab flows from v1 neighbors */ - for (i = 0; delta1 && i < pBNS->vert[v1].num_adj_edges; i++) - { - iedge_i = pBNS->vert[v1].iedge[i]; - if (iedge_i == iedge) - { - continue; - } - pEdge_i = pBNS->edge + iedge_i; - if (IS_FORBIDDEN( pEdge_i->forbidden, pBNS )) - { - continue; - } - f = ( pEdge_i->flow & EDGE_FLOW_MASK ); - if (f) - { - v_i = pEdge_i->neighbor12 ^ v1; - - fcd[ifcd].iedge = iedge_i; - fcd[ifcd].flow = pEdge_i->flow; - fcd[ifcd].cap = pEdge_i->cap; - - fcd[ifcd].v1 = v_i; - fcd[ifcd].flow_st1 = pBNS->vert[v_i].st_edge.flow; - fcd[ifcd].cap_st1 = pBNS->vert[v_i].st_edge.cap; - - fcd[ifcd].v2 = NO_VERTEX; - fcd[ifcd].flow_st2 = 0; - fcd[ifcd].cap_st2 = 0; - - fcd[++ifcd].iedge = NO_VERTEX; /* mark the end of the fcd[] data */ - pEdge_i->pass |= 64; - - while (f && delta1) - { - f--; - delta1--; - pEdge_i->flow = ( ( pEdge_i->flow & EDGE_FLOW_MASK ) - 1 ) | ( pEdge_i->flow & ~EDGE_FLOW_MASK ); - pBNS->vert[v_i].st_edge.flow = ( ( pBNS->vert[v_i].st_edge.flow & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v_i].st_edge.flow & ~EDGE_FLOW_ST_MASK ); - /* next 2 lines added 01-22-2002 */ - pBNS->vert[v1].st_edge.cap = ( ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v1].st_edge.cap & ~EDGE_FLOW_ST_MASK ); - pBNS->vert[v1].st_edge.flow = ( ( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v1].st_edge.flow & ~EDGE_FLOW_ST_MASK ); - - nDots++; - } - } - } - - /* Grab flows from v2 neighbors */ - for (i = 0; delta2 && i < pBNS->vert[v2].num_adj_edges; i++) - { - iedge_i = pBNS->vert[v2].iedge[i]; - if (iedge_i == iedge) - { - continue; - } - pEdge_i = pBNS->edge + iedge_i; - if (IS_FORBIDDEN( pEdge_i->forbidden, pBNS )) - { - continue; - } - f = ( pEdge_i->flow & EDGE_FLOW_MASK ); - if (f) - { - v_i = pEdge_i->neighbor12 ^ v2; - - fcd[ifcd].iedge = iedge_i; - fcd[ifcd].flow = pEdge_i->flow; - fcd[ifcd].cap = pEdge_i->cap; - - fcd[ifcd].v1 = v_i; - fcd[ifcd].flow_st1 = pBNS->vert[v_i].st_edge.flow; - fcd[ifcd].cap_st1 = pBNS->vert[v_i].st_edge.cap; - - fcd[ifcd].v2 = NO_VERTEX; - fcd[ifcd].flow_st2 = 0; - fcd[ifcd].cap_st2 = 0; - - fcd[++ifcd].iedge = NO_VERTEX; /* mark the end of the fcd[] data */ - pEdge_i->pass |= 64; - - while (f && delta2) - { - f--; - delta2--; - pEdge_i->flow = ( ( pEdge_i->flow & EDGE_FLOW_MASK ) - 1 ) | ( pEdge_i->flow & ~EDGE_FLOW_MASK ); - pBNS->vert[v_i].st_edge.flow = ( ( pBNS->vert[v_i].st_edge.flow & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v_i].st_edge.flow & ~EDGE_FLOW_ST_MASK ); - /* next 2 lines added 01-22-2002 */ - pBNS->vert[v2].st_edge.cap = ( ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v2].st_edge.cap & ~EDGE_FLOW_ST_MASK ); - pBNS->vert[v2].st_edge.flow = ( ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v2].st_edge.flow & ~EDGE_FLOW_ST_MASK ); - - nDots++; - } - } - } - if (delta1 || delta2) - { - return BNS_CANT_SET_BOND; - } - } - - if (f12 >= flow) - { - /* Decrease edge flow: Redirect flow to the neighbors and delete it on the edge: set flow12=cap12 = 0 */ - /* f12==flow fixes flow through the edge so that BNS cannot change it */ - /**********************************************************************************************/ - /* For example, simulate a removal of a double bond and create ONE or NONE augmenting path */ - /* Make it impossible for BNS to set same flow as it originally was */ - /**********************************************************************************************/ - Vertex v1 = pEdge->neighbor1; - Vertex v2 = ( v1 ^ pEdge->neighbor12 ); - int delta; - /* if NOT (st-cap >= st-flow >= f12 >= flow) then error in the BN structure */ - if (( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ) < f12 || - ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ) < f12 || - ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) < flow || - ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) < flow) - { - return BNS_CAP_FLOW_ERR; - } - fcd[ifcd].iedge = iedge; - fcd[ifcd].flow = pEdge->flow; - fcd[ifcd].cap = pEdge->cap; - - fcd[ifcd].v1 = v1; - fcd[ifcd].flow_st1 = pBNS->vert[v1].st_edge.flow; - fcd[ifcd].cap_st1 = pBNS->vert[v1].st_edge.cap; - - fcd[ifcd].v2 = v2; - fcd[ifcd].flow_st2 = pBNS->vert[v2].st_edge.flow; - fcd[ifcd].cap_st2 = pBNS->vert[v2].st_edge.cap; - - fcd[++ifcd].iedge = NO_VERTEX; /* mark the end of the fcd[] data */ - pEdge->pass |= 64; - - delta = f12 - flow; - - /* Remove current edge flow from st-edges */ - /* -- seem to be a bug -- - pBNS->vert[v1].st_edge.flow = ((pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK)-delta) | (pBNS->vert[v1].st_edge.flow & ~EDGE_FLOW_ST_MASK); - pBNS->vert[v2].st_edge.flow = ((pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK)-delta) | (pBNS->vert[v2].st_edge.flow & ~EDGE_FLOW_ST_MASK); - */ - - /* Replacement to the above 2 lines 01-16-2002 */ - /* Remove old edge flow from the flow of the adjacent vertices' st-edges */ - - pBNS->vert[v1].st_edge.flow = ( ( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v1].st_edge.flow & ~EDGE_FLOW_ST_MASK ); - pBNS->vert[v2].st_edge.flow = ( ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v2].st_edge.flow & ~EDGE_FLOW_ST_MASK ); - - /* Sdded 01-16-2002: reduce st-cap if new flow > 0 */ - /* Remove new edge flow from the cap of the adjacent vertices' st-edges */ - pBNS->vert[v1].st_edge.cap = ( ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) - flow ) | ( pBNS->vert[v1].st_edge.cap & ~EDGE_FLOW_ST_MASK ); - pBNS->vert[v2].st_edge.cap = ( ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) - flow ) | ( pBNS->vert[v2].st_edge.cap & ~EDGE_FLOW_ST_MASK ); - - /* delete current edge flow and capacity */ - pEdge->flow = ( pEdge->flow & ~EDGE_FLOW_MASK ); - pEdge->cap = ( pEdge->cap & ~EDGE_FLOW_MASK ); - nDots = 2 * delta; - } - - return nDots; -} - - -/**************************************************************************** -bAddNewVertex( ... ) - -Connect new (fictitious, temporary) vertex to nVertDoubleBond by a new edge -Add radical (set st-cap=1) to the new vertex, set cap=1 to the new edge -Add radical (set st-cap=1) to nVertSingleBond -Find augmenting path connecting new vertex to nVertSingleBond -This corresponds to moving H-atom from nVertSingleBond to nVertDoubleBond -****************************************************************************/ -int bAddNewVertex( BN_STRUCT *pBNS, - int nVertDoubleBond, - int nCap, - int nFlow, - int nMaxAdjEdges, - int *nDots ) -{ - Vertex vlast = pBNS->num_vertices - 1; - Vertex vnew = pBNS->num_vertices; - Vertex v2 = nVertDoubleBond; - BNS_VERTEX *pVert2 = pBNS->vert + v2; /* pointer to an old vertex */ - BNS_VERTEX *pNewVert = pBNS->vert + vnew; /* pointer to a new vertex */ - - EdgeIndex iedge = pBNS->num_edges; - BNS_EDGE *pEdge = pBNS->edge + iedge; /* pointer to a new edge */ - - if (iedge >= pBNS->max_edges || vnew >= pBNS->max_vertices) - { - return BNS_VERT_EDGE_OVFL; /* edges or vertices overflow */ - } - if (( pBNS->vert[vlast].iedge - pBNS->iedge ) + pBNS->vert[vlast].max_adj_edges + nMaxAdjEdges >= pBNS->max_iedges) - { - return BNS_VERT_EDGE_OVFL; /* iedges overflow */ - } - if (pVert2->num_adj_edges >= pVert2->max_adj_edges || nMaxAdjEdges <= 0) - { - return BNS_VERT_EDGE_OVFL; /* neighbors overflow */ - } - - /* Fill out the new edge, set its cap and flow, connect */ - /* memset( pEdge, 0, sizeof(*pEdge) ); */ - pEdge->cap = pEdge->cap0 = nCap; - pEdge->flow = pEdge->flow0 = nFlow; - pEdge->pass = 0; - pEdge->neighbor1 = v2; - pEdge->neighbor12 = v2 ^ vnew; - pEdge->forbidden = 0; - - /* Fill out the new vertex */ - /* memset( pNewVert, 0, sizeof(*pNewVert) ); */ - pNewVert->max_adj_edges = nMaxAdjEdges; - pNewVert->num_adj_edges = 0; - pNewVert->st_edge.cap0 = pNewVert->st_edge.cap = nCap; - pNewVert->st_edge.flow0 = pNewVert->st_edge.flow = nFlow; - pNewVert->st_edge.pass = 0; /* add initialization; added 2006-03-25 */ - pNewVert->iedge = pBNS->vert[vlast].iedge + pBNS->vert[vlast].max_adj_edges; - pNewVert->type = BNS_VERT_TYPE_TEMP; - *nDots += nCap - nFlow; - - pEdge->neigh_ord[v2 > vnew] = pVert2->num_adj_edges; - pEdge->neigh_ord[v2 < vnew] = pNewVert->num_adj_edges; - - /* Connect new edge to v2 */ - pVert2->iedge[pVert2->num_adj_edges++] = iedge; - /* Connect new edge to vnew */ - pNewVert->iedge[pNewVert->num_adj_edges++] = iedge; - - /* Fix v2 flow and cap */ - *nDots -= (int) pVert2->st_edge.cap - (int) pVert2->st_edge.flow; - pVert2->st_edge.flow += nFlow; - if (pVert2->st_edge.cap < pVert2->st_edge.flow) - { - pVert2->st_edge.cap = pVert2->st_edge.flow; - } - *nDots += (int) pVert2->st_edge.cap - (int) pVert2->st_edge.flow; - - pBNS->num_edges++; - pBNS->num_vertices++; - - return vnew; -} - - -/****************************************************************************/ -int AddNewEdge( BNS_VERTEX *p1, - BNS_VERTEX *p2, - BN_STRUCT *pBNS, - int nEdgeCap, - int nEdgeFlow ) -{ - int ip1 = (int) ( p1 - pBNS->vert ); - int ip2 = (int) ( p2 - pBNS->vert ); - int ie = pBNS->num_edges; - BNS_EDGE *e = pBNS->edge + ie; - - /* Debug: check bounds */ - if (ip1 >= pBNS->max_vertices || ip1 < 0 || - ip2 >= pBNS->max_vertices || ip2 < 0 || - ie >= pBNS->max_edges || ie < 0 || - ( p1->iedge - pBNS->iedge ) < 0 || - ( p1->iedge - pBNS->iedge ) + p1->max_adj_edges > pBNS->max_iedges || - ( p2->iedge - pBNS->iedge ) < 0 || - ( p2->iedge - pBNS->iedge ) + p2->max_adj_edges > pBNS->max_iedges || - p1->num_adj_edges >= p1->max_adj_edges || - p2->num_adj_edges >= p2->max_adj_edges) - { - return BNS_VERT_EDGE_OVFL; - } - - /* Clear the edge */ - memset( e, 0, sizeof( *e ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - - /* Connect */ - e->neighbor1 = inchi_min( ip1, ip2 ); - e->neighbor12 = ip1 ^ ip2; - p1->iedge[p1->num_adj_edges] = ie; - p2->iedge[p2->num_adj_edges] = ie; - e->neigh_ord[ip1 > ip2] = p1->num_adj_edges++; - e->neigh_ord[ip1 < ip2] = p2->num_adj_edges++; - e->cap = e->cap0 = nEdgeCap; - e->flow = e->flow0 = nEdgeFlow; - p1->st_edge.flow += nEdgeFlow; - p2->st_edge.flow += nEdgeFlow; - if (p1->st_edge.cap < p1->st_edge.flow) - { - p1->st_edge.cap = p1->st_edge.flow; - } - if (p2->st_edge.cap < p2->st_edge.flow) - { - p2->st_edge.cap = p2->st_edge.flow; - } - pBNS->num_edges++; - - return ie; -} - - -/****************************************************************************/ -BNS_IEDGE GetEdgeToGroupVertex( BN_STRUCT *pBNS, Vertex v1, AT_NUMB type ) -{ - if (v1 < pBNS->num_atoms) - { - Vertex v2; - BNS_EDGE *pEdge1; - BNS_VERTEX *pVert1 = pBNS->vert + v1; - int i = pVert1->num_adj_edges - 1; - - while (0 <= i) - { - pEdge1 = pBNS->edge + pVert1->iedge[i]; - v2 = pEdge1->neighbor12 ^ v1; - if (pBNS->vert[v2].type == type) - { - return IS_FORBIDDEN( pEdge1->forbidden, pBNS ) ? NO_VERTEX : pVert1->iedge[i]; - } - i--; - } - return NO_VERTEX; /* not found t-group */ - } - else - { - if (v1 < pBNS->num_vertices) - { - return NO_VERTEX; - } - } - - return BNS_VERT_EDGE_OVFL; -} - - -/****************************************************************************/ -Vertex GetGroupVertex( BN_STRUCT *pBNS, Vertex v1, AT_NUMB type ) -{ - if (v1 < pBNS->num_atoms) - { - Vertex v2; - BNS_EDGE *pEdge1; - BNS_VERTEX *pVert1 = pBNS->vert + v1; - int i = pVert1->num_adj_edges - 1; - - AT_NUMB type2; - - if (type == BNS_VERT_TYPE_ENDPOINT) - { - type2 = BNS_VERT_TYPE_TGROUP; - } - else - { - if (type == BNS_VERT_TYPE_C_POINT) - { - type2 = BNS_VERT_TYPE_C_GROUP; - } - else - { - type2 = 0; - } - } - - if (( pVert1->type & type ) == type) - { - while (0 <= i) - { - pEdge1 = pBNS->edge + pVert1->iedge[i]; - v2 = pEdge1->neighbor12 ^ v1; - if (pBNS->vert[v2].type == type2) - { - if (IS_FORBIDDEN( pEdge1->forbidden, pBNS )) - { - return NO_VERTEX; - } - return v2; - } - i--; - } - } - return BNS_BOND_ERR; /* not found t-group */ - } - else - { - if (v1 < pBNS->num_vertices) - { - return NO_VERTEX; - } - } - - return BNS_VERT_EDGE_OVFL; -} - - -/****************************************************************************/ -int bAddStCapToAVertex( BN_STRUCT *pBNS, - Vertex v1, - Vertex v2, - VertexFlow *nOldCapVertSingleBond, - int *nDots, - int bAdjacentDonors ) -{ - BNS_VERTEX *pVert1 = pBNS->vert + v1; - BNS_VERTEX *pVert; - BNS_EDGE *pEdge; - Vertex v; - int i, n; - VertexFlow nNewCap; - - /* Change v1: increment its st-cap */ - n = 0; - nOldCapVertSingleBond[n++] = pVert1->st_edge.cap; - /*if ( pVert1->st_edge.cap == pVert1->st_edge.flow ) {*/ - pVert1->st_edge.cap++; - *nDots += 1; - - /*}*/ - /* increment caps of adjacent edges if - (1) the neighbor has st-cap != 0 and - (2) (edge cap==0) OR (nSumEdgeCap < pVert1->st_edge.cap && pVert->st_edge.flow > pVert1->st_edge.cap) - */ - if (!( pVert1->type & BNS_VERT_TYPE_ANY_GROUP )) - { - /* - AT_NUMB nSumEdgeCap = 0; - for ( i = 0; i < pVert1->num_adj_edges; i ++ ) { - pEdge = pBNS->edge + pVert1->iedge[i]; - nSumEdgeCap += pEdge->cap; - } - */ - /* do not increment caps of t-group or c-group edges */ - for (i = 0; i < pVert1->num_adj_edges; i++) - { - pEdge = pBNS->edge + pVert1->iedge[i]; - nOldCapVertSingleBond[n++] = pEdge->cap; /* save edge cap */ - v = pEdge->neighbor12 ^ v1; - if (v == v2 && !bAdjacentDonors) - { - continue; - } - pVert = pBNS->vert + v; - if (pVert->type & BNS_VERT_TYPE_ANY_GROUP) - continue; - nNewCap = inchi_min( pVert->st_edge.cap, pVert1->st_edge.cap ); - nNewCap = inchi_min( nNewCap, MAX_BOND_EDGE_CAP ); - pEdge->cap = nNewCap; /* change edge cap */ - /* - if ( pVert->st_edge.cap > 0 && !pEdge->cap ) { - pEdge->cap ++; - } else - if ( pVert->st_edge.flow > pVert1->st_edge.cap && - pEdge->cap < MAX_BOND_EDGE_CAP && - nSumEdgeCap < pVert1->st_edge.cap ) { - pEdge->cap ++; - } - */ - } - } - - return n; /* number of elements in nOldCapVertSingleBond[*] */ -} - - -#define BNS_CHK_ALTP_NO_ALTPATH 0 -#define BNS_CHK_ALTP_SAME_TGROUP 1 -#define BNS_CHK_ALTP_SAME_VERTEX 2 -#define BNS_CHK_ALTP_SET_SUCCESS 4 - - -/****************************************************************************/ -int bSetBnsToCheckAltPath( BN_STRUCT *pBNS, - int nVertDoubleBond, - int nVertSingleBond, - AT_NUMB type, - int path_type, - ALT_PATH_CHANGES *apc, - BNS_FLOW_CHANGES *fcd, - int *nDots ) -{ - - if (!pBNS->vert[nVertDoubleBond].st_edge.flow && - - !( path_type == ALT_PATH_MODE_REM2H_CHG || - path_type == ALT_PATH_MODE_ADD2H_CHG || - path_type == ALT_PATH_MODE_REM2H_TST || - path_type == ALT_PATH_MODE_ADD2H_TST ) - ) - { - return BNS_CHK_ALTP_NO_ALTPATH; - } - else - { - Vertex vNew; - Vertex v1 = nVertSingleBond; - Vertex v2 = nVertDoubleBond; - - BNS_VERTEX *pVert1 = pBNS->vert + v1; - BNS_VERTEX *pVert2 = pBNS->vert + v2; - int n, bAdjacentDonors = 0; - int ifcd = 0; - - Vertex t1 = NO_VERTEX; - Vertex t2 = NO_VERTEX; - int iapc; - - /*#if ( TEST_REMOVE_S_ATOMS == 1 )*/ /* && ALT_PATH_MODE_4_SALT == path_type */ - if (( *pBNS->pbTautFlags & TG_FLAG_TEST_TAUT2_SALTS ) && - ALT_PATH_MODE_4_SALT2 == path_type && - ( BNS_VERT_TYPE_ENDPOINT & type )) - { - /* - --------------------------------------------------------- - \ action | DB action (v2) | SB action (v1) | - vertex \ | accept H @ vertex | donate H @ vertex | - type \ | nVertDoubleBond | nVertSingleBond | - ----------------+-------------------+-------------------+ - -ZH (v1) | error | -ZH(.) | - (cap>0 on edge | | increment | - except v1-v2) | | st-cap on Z | - ----------------+-------------------+-------------------+ - =Z (v2) | =Z-(.) | error | - (st-flow>0) | add fict vertex | | - | with st-cap=1 | | - ----------------+-------------------+-------------------+ - endpoint | T(.) | T-(.) | - of t-group | increment | add fict vertex | - represented | st-cap on T | with st-cap=1 | - by fictitious | | | - vertex T | | | - --------------------------------------------------------- - */ - - int bSet_v1; /* indicator: v1 has been set */ - int bSet_v2; /* indicator: v2 has been set */ - int i; - - Vertex v1t = NO_VERTEX; - Vertex v2t = NO_VERTEX; - Vertex v1Act, v2Act; - Vertex v; - - memset( apc, 0, sizeof( *apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - fcd[ifcd].iedge = NO_VERTEX; - *nDots = 0; - - if (v1 == v2) - { - return BNS_CHK_ALTP_SAME_VERTEX; - } - - /* Check whether v1 has neighbors adjacent to multiple bonds */ - for (i = 0, n = 0; i < pVert1->num_adj_edges; i++) - { - v = ( pBNS->edge + pVert1->iedge[i] )->neighbor12 ^ v1; /* v is adjacent to v1 */ - if (v == v2) - { - continue; /* ignore connection to v2 */ - } - n += ( pBNS->vert[v].st_edge.cap > 0 ); - } - if (!n) - { - return BNS_CHK_ALTP_NO_ALTPATH; /* the vertex cannot have flow */ - } - - v1Act = v1; - v2Act = v2; - - /* find t-group that contains v1 */ - if (( pVert1->type & type ) == type) - { - v1t = GetGroupVertex( pBNS, v1, type ); - if (IS_BNS_ERROR( v1t )) - { - return v1t; - } - if (v1t != NO_VERTEX) - { - v1Act = v1t; - } - } - /* Find t-group that contains v2 */ - if (( pVert2->type & type ) == type) - { - v2t = GetGroupVertex( pBNS, v2, type ); - if (IS_BNS_ERROR( v2t )) - { - return v2t; - } - if (v2t != NO_VERTEX) - { - v2Act = v2t; - } - } - if (v1t != NO_VERTEX && v1t == v2t) - { - return BNS_CHK_ALTP_SAME_TGROUP; - } - - bSet_v1 = bSet_v2 = 0; - /* create new edges adjacent to v1t or v2 */ - iapc = 0; - if (v1t != NO_VERTEX) - { - /* Create new edge and vertex, connect to v1t */ - vNew = bAddNewVertex( pBNS, v1t, 1, 0, 1, nDots ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[iapc] = vNew; - apc->bSetNew[iapc] = 1; - bSet_v1 = 1; - iapc++; - } - if (v2t == NO_VERTEX) - { - /* Create new edge and vertex, connect to v2 */ - vNew = bAddNewVertex( pBNS, v2, 1, 0, 1, nDots ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[iapc] = vNew; - apc->bSetNew[iapc] = 1; - bSet_v2 = 1; - iapc++; - } - - /* Add st-cap to v1 and/or v2t */ - iapc = 0; - if (!bSet_v1) - { - /* Add st-cap to v1 */ - if (v1t != NO_VERTEX) /* djb-rwth: addressing coverity CID #499551 -- condition properly written */ - { - return BNS_BOND_ERR; - } - n = bAddStCapToAVertex( pBNS, v1, v2Act, apc->nOldCapsVert[iapc], nDots, 0 ); - apc->bSetOldCapsVert[iapc] = n; - apc->vOldVert[iapc] = v1; - iapc++; - } - if (!bSet_v2) - { - /* Add st-cap to v2t */ - if (v2t == NO_VERTEX) - { - return BNS_BOND_ERR; - } - n = bAddStCapToAVertex( pBNS, v2t, v1Act, apc->nOldCapsVert[iapc], nDots, 0 ); - apc->bSetOldCapsVert[iapc] = n; - apc->vOldVert[iapc] = v2t; - iapc++; - } - if (*nDots < 0 || *nDots % 2) - { - return BNS_SET_ALTP_ERR; - } - return BNS_CHK_ALTP_SET_SUCCESS; - } - - /* ( *pBNS->pbTautFlags & TG_FLAG_TEST_TAUT2_SALTS ) */ - - /*#endif*/ - - /* ( TEST_REMOVE_S_ATOMS == 1 && ALT_PATH_MODE_4_SALT == path_type ) */ - - if (path_type == ALT_PATH_MODE_REM2H_CHG || - path_type == ALT_PATH_MODE_ADD2H_CHG || - path_type == ALT_PATH_MODE_REM2H_TST || - path_type == ALT_PATH_MODE_ADD2H_TST) - { - /* added 2004-03-18 */ - - int bDonors = ( path_type == ALT_PATH_MODE_REM2H_CHG ) || ( path_type == ALT_PATH_MODE_REM2H_TST ); - - int bSet_v1; /* indicator: v1 has been set */ - int bSet_v2; /* indicator: v2 has been set */ - int i, cap = 1; - Vertex v1t = NO_VERTEX; - Vertex v2t = NO_VERTEX; - Vertex v1Act, v2Act; - Vertex v; - - memset( apc, 0, sizeof( *apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - fcd[ifcd].iedge = NO_VERTEX; - *nDots = 0; - /* - if ( v1 == v2 ) { - return BNS_CHK_ALTP_SAME_VERTEX; - } - */ - - /* Check whether v1 and v2 have proper neighbors */ - for (i = 0, n = bAdjacentDonors = 0; i < pVert1->num_adj_edges; i++) - { - v = ( pBNS->edge + pVert1->iedge[i] )->neighbor12 ^ v1; /* v is adjacent to v1 */ - /* do not ignore connection to v2 - if ( v == v2 ) - continue; - */ - n += bDonors ? ( pBNS->vert[v].st_edge.cap > 0 ) - : ( ( pBNS->edge + pVert1->iedge[i] )->flow > 0 ); - bAdjacentDonors += bDonors ? ( v == v2 ) && ( ( pBNS->edge + pVert1->iedge[i] )->flow < MAX_BOND_EDGE_CAP ) : 0; - /* two donors connected by a single or double bond */ - } - - if (!n && !bAdjacentDonors) - { - return BNS_CHK_ALTP_NO_ALTPATH; /* the vertex cannot have flow */ - } - for (i = 0, n = bAdjacentDonors = 0; i < pVert2->num_adj_edges; i++) - { - v = ( pBNS->edge + pVert2->iedge[i] )->neighbor12 ^ v2; /* v is adjacent to v2 */ - /* do not ignore connection to v1 - if ( v == v1 ) - continue; - */ - n += bDonors ? ( pBNS->vert[v].st_edge.cap > 0 ) : ( ( pBNS->edge + pVert2->iedge[i] )->flow > 0 ); - bAdjacentDonors += bDonors ? ( v == v1 ) && ( ( pBNS->edge + pVert2->iedge[i] )->flow < MAX_BOND_EDGE_CAP ) : 0; - /* two donors connected by a single or double bond */ - } - - if (!n && !bAdjacentDonors) - { - return BNS_CHK_ALTP_NO_ALTPATH; /* the vertex cannot have flow */ - } - - v1Act = v1; - v2Act = v2; - - /* Find t-group that contains v1 */ - if (( pVert1->type & type ) == type) - { - v1t = GetGroupVertex( pBNS, v1, type ); - if (BNS_BOND_ERR == v1t) - { - v1t = NO_VERTEX; - } - else - { - if (IS_BNS_ERROR( v1t )) - { - return v1t; - } - else - { - if (v1t != NO_VERTEX) - { - v1Act = v1t; - } - } - } - } - - /* Find t-group that contains v2 */ - if (( pVert2->type & type ) == type) - { - v2t = GetGroupVertex( pBNS, v2, type ); - if (BNS_BOND_ERR == v2t) - { - v2t = NO_VERTEX; - } - else - { - if (IS_BNS_ERROR( v2t )) - { - return v2t; - } - else - { - if (v2t != NO_VERTEX) - { - v2Act = v2t; - } - } - } - } - - if (v1t != NO_VERTEX && v1t == v2t) - { - cap = 2; /* same t-group */ - } - - /* bAddNewVertex: (bDonors != 0) == (vit != NO_VERTEX), i=1,2 */ - bSet_v1 = bSet_v2 = 0; - /* create new edges adjacent to v1t or v2 */ - iapc = 0; - if (( bDonors != 0 ) == ( v1t != NO_VERTEX )) - { - /* Create new edge and vertex, connect to v1Act */ - vNew = bAddNewVertex( pBNS, v1Act, cap, 0, 1, nDots ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[iapc] = vNew; - apc->bSetNew[iapc] = 1; - bSet_v1 = 1; - iapc++; - } - if (( bDonors != 0 ) == ( v2t != NO_VERTEX ) && cap == 1) - { - /* Create new edge and vertex, connect to v2Act; do not do it if cap==2 */ - vNew = bAddNewVertex( pBNS, v2Act, cap, 0, 1, nDots ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[iapc] = vNew; - apc->bSetNew[iapc] = 1; - bSet_v2 = 1; - iapc++; - } - else - { - if (( bDonors != 0 ) == ( v2t != NO_VERTEX )) - { - bSet_v2 = 1; - } - } - - /* Add st-cap to v1 and/or v2t */ - iapc = 0; - /* If cap=2 then just increment st_cap 2 times */ - if (!bSet_v1) - { - /* Add st-cap to v1 */ - if (( bDonors != 0 ) == ( v1t != NO_VERTEX )) - { - return BNS_BOND_ERR; - } - n = bAddStCapToAVertex( pBNS, v1Act, v2Act, apc->nOldCapsVert[iapc], nDots, bAdjacentDonors ); - apc->bSetOldCapsVert[iapc] = n; - apc->vOldVert[iapc] = v1Act; - iapc++; - } - if (!bSet_v2) - { - /* Add st-cap to v2t */ - if (( bDonors != 0 ) == ( v2t != NO_VERTEX )) - { - return BNS_BOND_ERR; - } - n = bAddStCapToAVertex( pBNS, v2Act, v1Act, apc->nOldCapsVert[iapc], nDots, bAdjacentDonors ); - apc->bSetOldCapsVert[iapc] = n; - apc->vOldVert[iapc] = v2Act; - iapc++; - } - if (*nDots < 0 || *nDots % 2) - { - return BNS_SET_ALTP_ERR; - } - return BNS_CHK_ALTP_SET_SUCCESS; - } - - if (path_type == ALT_PATH_MODE_REM_PROTON) - { - /* added 2004-03-05 */ - if (v1 >= 0 && v2 >= 0 && - ( pVert1->type & BNS_VERT_TYPE_ANY_GROUP ) && - ( pVert2->type & BNS_VERT_TYPE_ANY_GROUP )) - { - /* Create new edge and vertex, connect to v2 */ - if (( pBNS->vert[v1].type & BNS_VERT_TYPE_C_GROUP ) && - ( pBNS->vert[v1].st_edge.flow == 2 * pBNS->vert[v1].num_adj_edges )) - { - /* so far in a charge group max edge flow = 1 2004-03-08 */ - return BNS_CHK_ALTP_NO_ALTPATH; - } - memset( apc, 0, sizeof( *apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - fcd[ifcd].iedge = NO_VERTEX; - *nDots = 0; - iapc = 0; - - vNew = bAddNewVertex( pBNS, v2, 1, 0, 1, nDots ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[iapc] = vNew; - apc->bSetNew[iapc] = 1; - /*iapc ++;*/ - /* add st-cap (dot) to v1 */ - n = bAddStCapToAVertex( pBNS, v1, v2, apc->nOldCapsVert[iapc], nDots, 0 ); - apc->bSetOldCapsVert[iapc] = n; - apc->vOldVert[iapc] = v1; - iapc++; - return BNS_CHK_ALTP_SET_SUCCESS; - } - } - -#if ( NEUTRALIZE_ENDPOINTS == 1 ) /* { */ - - *nDots = 0; - memset( apc, 0, sizeof( *apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - fcd[ifcd].iedge = NO_VERTEX; - - if (type & BNS_VERT_TYPE_ENDPOINT) - { - BNS_IEDGE iedge; - AT_NUMB type2; - int ret2; - /* prohibit charge movement */ - type2 = BNS_VERT_TYPE_C_GROUP; - iedge = GetEdgeToGroupVertex( pBNS, v1, type2 ); - if (iedge != NO_VERTEX) - { - /* Set flow=1 on an edge to a c-group vertex to make sure - there is no positive charge when moving tautomeric H-atoms */ - ret2 = bSetFlowToCheckOneBond( pBNS, iedge, 1, fcd + ifcd ); - if (IS_BNS_ERROR( ret2 )) - { - return ret2; - } - *nDots += ret2; - while (fcd[ifcd].iedge != NO_VERTEX) - { - ifcd++; - } - } - - iedge = GetEdgeToGroupVertex( pBNS, v2, type2 ); - - if (iedge != NO_VERTEX) - { - /* Set flow=1 on an edge to a c-group vertex to make sure - there is no positive charge when moving tautomeric H-atoms */ - - ret2 = bSetFlowToCheckOneBond( pBNS, iedge, 1, fcd + ifcd ); - - if (IS_BNS_ERROR( ret2 )) - { - return ret2; - } - *nDots += ret2; - while (fcd[ifcd].iedge != NO_VERTEX) - { - ifcd++; - } - } - - /* Set hydrogen counts */ - type2 = BNS_VERT_TYPE_TGROUP; - iedge = GetEdgeToGroupVertex( pBNS, v1, type2 ); - if (iedge != NO_VERTEX) - { - /* Set flow=1 on an edge to a t-group vertex to make sure there is - a moveable hydrogen atom or (-) on v1 when moving tautomeric H-atoms */ -#if ( FIX_H_CHECKING_TAUT == 1 ) - ret2 = bSetFlowToCheckOneBond( pBNS, iedge, 1, fcd + ifcd ); - if (IS_BNS_ERROR( ret2 )) - { - return ret2; - } - *nDots += ret2; - while (fcd[ifcd].iedge != NO_VERTEX) - { - ifcd++; - } -#else - t1 = pBNS->edge[iedge].neighbor12 ^ v1; -#endif - } - - iedge = GetEdgeToGroupVertex( pBNS, v2, type2 ); - if (iedge != NO_VERTEX) - { - /* Set flow=0 on an edge to a t-group vertex to make sure there is - no moveable hydrogen atom or (-) on v2 when moving tautomeric H-atoms */ -#if ( FIX_H_CHECKING_TAUT == 1 ) - ret2 = bSetFlowToCheckOneBond( pBNS, iedge, 0, fcd + ifcd ); - if (IS_BNS_ERROR( ret2 )) - { - return ret2; - } - *nDots += ret2; - while (fcd[ifcd].iedge != NO_VERTEX) - { - ifcd++; - } -#else - t2 = pBNS->edge[iedge].neighbor12 ^ v2; -#endif - } - -#if ( FIX_H_CHECKING_TAUT == 1 ) -#else - if (t1 == t2 && t1 != NO_VERTEX) - { - return BNS_CHK_ALTP_SAME_TGROUP; - } -#endif - - iapc = 0; - /* Create new edge and vertex with cap=1 at v2 and/or t1 */ - if (t1 != NO_VERTEX) - { - /* Create new edge and vertex, connect to t1 */ - vNew = bAddNewVertex( pBNS, t1, 1/*cap*/, 0/*flow*/, 1/*max_adj_edges*/, nDots ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[iapc] = vNew; - apc->bSetNew[iapc] = 1; - iapc++; - } - if (t2 == NO_VERTEX) - { - /* Create new edge and vertex, connect to v2 */ - vNew = bAddNewVertex( pBNS, v2, 1/*cap*/, 0/*flow*/, 1/*max_adj_edges*/, nDots ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[iapc] = vNew; - apc->bSetNew[iapc] = 1; - iapc++; - } - - /* Add st-cap to v1 and/or v2t */ - iapc = 0; - if (t1 == NO_VERTEX) - { - /* Add st-cap to v1 */ - n = bAddStCapToAVertex( pBNS, v1, (Vertex) ( t2 == NO_VERTEX ? v2 : t2 ), apc->nOldCapsVert[iapc], nDots, 0 ); /* djb-rwth: addressing coverity CID #499501 -- condition works as expected for t2 == -2 */ - apc->bSetOldCapsVert[iapc] = n; - apc->vOldVert[iapc] = v1; - iapc++; - } - if (t2 != NO_VERTEX) - { - /* Add st-cap to t2 */ - n = bAddStCapToAVertex( pBNS, t2, (Vertex) ( t1 == NO_VERTEX ? v1 : t1 ), apc->nOldCapsVert[iapc], nDots, 0 ); - apc->bSetOldCapsVert[iapc] = n; - apc->vOldVert[iapc] = t2; - iapc++; - } - } - else - { - /* Create new edge and vertex, connect to v2 */ - vNew = bAddNewVertex( pBNS, v2, 1 /* cap*/, 0 /* flow */, 1 /* max_adj_edges */, nDots ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[0] = vNew; - apc->bSetNew[0] = 1; - - /* add st-cap to v1 */ - n = bAddStCapToAVertex( pBNS, v1, v2, apc->nOldCapsVert[0], nDots, 0 ); - apc->bSetOldCapsVert[0] = n; - apc->vOldVert[0] = v1; - } -#else /* } NEUTRALIZE_ENDPOINTS == 0 {*/ - - *nDots = 0; - memset( apc, 0, sizeof( *apc ) ); - fcd[ifcd].iedge = NO_VERTEX; - - /* Create new edge and vertex, connect to v2 */ - vNew = bAddNewVertex( pBNS, v2, 1 /* cap*/, 0 /* flow */, 1 /* max_adj_edges */, nDots, 0 ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[0] = vNew; - apc->bSetNew[0] = 1; - - /* Add st-cap to v1 */ - n = bAddStCapToAVertex( pBNS, v1, v2, apc->nOldCapsVert[0], nDots ); - apc->bSetOldCapsVert[0] = n; - apc->vOldVert[0] = v1; -#endif /* } NEUTRALIZE_ENDPOINTS */ - - if (*nDots < 0 || *nDots % 2) - { - return BNS_SET_ALTP_ERR; - } - return BNS_CHK_ALTP_SET_SUCCESS; - } - - /*return BNS_CHK_ALTP_NO_ALTPATH;*/ -} - - -/****************************************************************************/ -int bRestoreBnsAfterCheckAltPath( BN_STRUCT *pBNS, - ALT_PATH_CHANGES *apc, - int bChangeFlow ) - /* int nVertDoubleBond, int nVertSingleBond, int nNewVertex, AT_NUMB *nOldCapVertSingleBond */ -{ - BNS_EDGE *pEdge; - Vertex vNew; - Vertex vOld; - BNS_VERTEX *pOldVert; - BNS_VERTEX *pNewVert; - int i, j, n; /* djb-rwth: removing redundant variables */ - - /* djb-rwth: removing redundant code */ - - if (bChangeFlow & BNS_EF_UPD_H_CHARGE) - { - /* Remove new temp. vertices and edges connectong them to the structure */ - for (i = sizeof( apc->bSetNew ) / sizeof( apc->bSetNew[0] ) - 1; 0 <= i; i--) - { - if (apc->bSetNew[i]) - { - vNew = apc->vNewVertex[i]; - pNewVert = pBNS->vert + vNew; - for (j = 0; j < pNewVert->num_adj_edges; j++) - { - pEdge = pBNS->edge + pNewVert->iedge[j]; - vOld = pEdge->neighbor12 ^ vNew; - pOldVert = pBNS->vert + vOld; - pOldVert->st_edge.flow -= pEdge->flow; - pOldVert->st_edge.cap -= pEdge->flow; - /* disconnect new edge from pOldVert */ - pOldVert->iedge[--pOldVert->num_adj_edges] = 0; - /* clear the new edge */ - memset( pEdge, 0, sizeof( *pEdge ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - /* and decrement the total number of edges */ - pBNS->num_edges--; - } - /* Clear the new vertex */ - memset( pNewVert, 0, sizeof( *pNewVert ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - /* and decrement the total number of vertices - (new vertice ids are contiguous) */ - pBNS->num_vertices--; - /* djb-rwth: removing redundant code */ - } - } - - /* Restore changed caps of old vertices */ - for (i = sizeof( apc->bSetOldCapsVert ) / sizeof( apc->bSetOldCapsVert[0] ) - 1; - 0 <= i; - i--) - { - if ((n = apc->bSetOldCapsVert[i])) /* djb-rwth: addressing LLVM warning */ - { - pOldVert = pBNS->vert + apc->vOldVert[i]; - if (pOldVert->st_edge.flow <= apc->nOldCapsVert[i][0]) - { - pOldVert->st_edge.cap = apc->nOldCapsVert[i][0]; - n--; - /* djb-rwth: removing redundant code */ - for (j = 0; j < n && j < pOldVert->num_adj_edges; j++) - { - pEdge = pBNS->edge + pOldVert->iedge[j]; - pEdge->cap = apc->nOldCapsVert[i][j + 1]; - } - } - } - } - } - else - { - /* Restore changed caps of old vertices */ - for (i = sizeof( apc->bSetOldCapsVert ) / sizeof( apc->bSetOldCapsVert[0] ) - 1; 0 <= i; i--) - { - if ((n = apc->bSetOldCapsVert[i])) /* djb-rwth: addressing LLVM warning */ - { - pOldVert = pBNS->vert + apc->vOldVert[i]; - pOldVert->st_edge.cap = apc->nOldCapsVert[i][0]; - n--; - /* djb-rwth: removing redundant code */ - for (j = 0; j < n && j < pOldVert->num_adj_edges; j++) - { - pEdge = pBNS->edge + pOldVert->iedge[j]; - pEdge->cap = apc->nOldCapsVert[i][j + 1]; - } - } - } - - /* Remove new temp. vertices and edges connectong them to the structure */ - for (i = sizeof( apc->bSetNew ) / sizeof( apc->bSetNew[0] ) - 1; 0 <= i; i--) - { - if (apc->bSetNew[i]) - { - vNew = apc->vNewVertex[i]; - pNewVert = pBNS->vert + vNew; - for (j = 0; j < pNewVert->num_adj_edges; j++) - { - pEdge = pBNS->edge + pNewVert->iedge[j]; - vOld = pEdge->neighbor12 ^ vNew; - pOldVert = pBNS->vert + vOld; - /* disconnect new edge from pOldVert */ - pOldVert->iedge[--pOldVert->num_adj_edges] = 0; - /* clear the new edge */ - memset( pEdge, 0, sizeof( *pEdge ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - /* and decrement the total number of edges */ - pBNS->num_edges--; - } - /* Clear the new vertex */ - memset( pNewVert, 0, sizeof( *pNewVert ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - /* and decrement the total number of vertices (new vertice ids are contiguous */ - pBNS->num_vertices--; - /* djb-rwth: removing redundant code */ - } - } - } - - return 0; -} - - -/****************************************************************************/ -int bExistsAnyAltPath( CANON_GLOBALS *pCG, - BN_STRUCT *pBNS, - BN_DATA *pBD, - inp_ATOM *at, - int num_atoms, - int nVert2, - int nVert1, - int path_type ) -{ - int nRet1, nRet2; - - nRet1 = bExistsAltPath( pCG, pBNS, pBD, NULL, at, num_atoms, nVert2, nVert1, path_type ); - - if (nRet1 > 0) - { - return nRet1; - } - - nRet2 = bExistsAltPath( pCG, pBNS, pBD, NULL, at, num_atoms, nVert1, nVert2, path_type ); - - if (nRet2 > 0) - { - return nRet2; - } - if (IS_BNS_ERROR( nRet1 )) - { - return nRet1; - } - if (IS_BNS_ERROR( nRet2 )) - { - return nRet2; - } - - return 0; -} - - -#define ALT_PATH_TAUTOM 1 -#define ALT_PATH_CHARGE 2 -#define ALT_PATH_4_SALT 3 - - -/****************************************************************************/ -int bIsBnsEndpoint( BN_STRUCT *pBNS, int v ) -{ - int i, vt; - BNS_VERTEX *pVert; /* vertices */ - BNS_EDGE *pEdge; /* edges */ - - if (0 <= v && v < pBNS->num_atoms && ( pVert = pBNS->vert + v ) && ( pVert->type & BNS_VERT_TYPE_ENDPOINT )) - { - for (i = pVert->num_adj_edges - 1; 0 <= i; i--) - { - pEdge = pBNS->edge + pVert->iedge[i]; - vt = pEdge->neighbor12 ^ v; - if (pBNS->vert[vt].type & BNS_VERT_TYPE_TGROUP) - { - return !IS_FORBIDDEN( pEdge->forbidden, pBNS ); - } - } - } - - return 0; -} - - -#if ( BNS_RAD_SEARCH == 1 ) - - -/****************************************************************************/ -int bRadChangesAtomType( BN_STRUCT *pBNS, - BN_DATA *pBD, - Vertex v, - Vertex v_1, - Vertex v_2 ) -{ - - EdgeIndex iuv; - Vertex v_O, v_ChgOrH; - - /* The previous atom along the path: should be a terminal atom */ - if (v_1 == NO_VERTEX) - { - v_1 = GetPrevVertex( pBNS, v, pBD->SwitchEdge, &iuv ); - } - v_O = v_1 / 2 - 1; - - if (v_O < 0 || v_O >= pBNS->num_atoms) - { - return 0; - } - - /* Make sure v_O is a terminal atom: its second neighbor is not an atom */ - if (pBNS->vert[pBNS->edge[pBNS->vert[v_O].iedge[1]].neighbor12 ^ v_O].type & BNS_VERT_TYPE_ATOM) - { - return 0; - } - - /* The next to previous vertex vertex along the path: should be a Charge or Taut group vertex */ - if (v_2 == NO_VERTEX) - { - v_2 = GetPrevVertex( pBNS, v_1, pBD->SwitchEdge, &iuv ); - } - - v_ChgOrH = v_2 / 2 - 1; - if (v_ChgOrH < pBNS->num_atoms) - { - return 0; - } - - /* Make sure v_ChgOrH is a charge or taut_group */ - if (pBNS->vert[v_ChgOrH].type & ( BNS_VERT_TYPE_TGROUP | BNS_VERT_TYPE_C_GROUP )) - { - return 1; - } - - return 0; -} - - -/****************************************************************************/ -int RegisterRadEndpoint( BN_STRUCT *pBNS, BN_DATA *pBD, Vertex u ) -{ - EdgeIndex iuv; - int i, num_found; - Vertex v, w; - Vertex u_last, v2; - switch (pBD->bRadSrchMode) - { - case RAD_SRCH_NORM: - /* Go backwards along alt path and stop at the 1st found atom (not a fictitious vertex) */ - /* we need only vertices where a radical may be moved, therefore exclude u%2=1 (odd) vertices */ - /* atom number = u/2-1; u = 0 or 1 is 's' or 't' vertices, respectively, they are not atoms */ - num_found = 0; - while (u > Vertex_t && ( u % 2 || u / 2 > pBNS->num_atoms )) - { - u = GetPrevVertex( pBNS, u, pBD->SwitchEdge, &iuv ); - } - w = u / 2 - 1; /* Check whether u is a radical endpoint */ - if (Vertex_t < u && w < pBNS->num_atoms && - pBNS->vert[w].st_edge.cap == ( pBNS->vert[w].st_edge.flow & EDGE_FLOW_ST_MASK )) - { - /* u is an atom; it is not a radical atom */ - /* now search for the starting radical atom by following the path back from u */ - v = u_last = u; - while (v > Vertex_t) - { - u = v; - v = GetPrevVertex( pBNS, u, pBD->SwitchEdge, &iuv ); /* Radical endpoint */ - } - /* Check whether u is a radical atom */ - if (!( u % 2 ) && Vertex_t < u && - ( u = u / 2 - 1 ) < pBNS->num_atoms && - pBNS->vert[u].st_edge.cap > ( pBNS->vert[u].st_edge.flow & EDGE_FLOW_ST_MASK )) - { - /* at pBNS->vert[u] we have found the radical that originated the path */ - /* pBD->RadEndpoints[2k] is the radical, pBD->RadEndpoints[2k+1] is the farthest atom */ - /* to which the radical may be moved (farthest reachable atom) */ - - /* add *all* atoms that may receive radical from u_rad */ - /* exception: at2 in: ==(+/-/H)---at1==at2(possible rad endpoint) if pBNS->type_TACN */ - for (v = u_last; v > Vertex_t; v = GetPrevVertex( pBNS, v, pBD->SwitchEdge, &iuv )) - { - if (!( v % 2 ) && ( v2 = v / 2 - 1 ) < pBNS->num_atoms && - pBNS->vert[v2].st_edge.cap == ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK )) - { - /* Check exception */ - if (pBNS->type_TACN && - bRadChangesAtomType( pBNS, pBD, v, NO_VERTEX, NO_VERTEX )) - { - continue; - } - /* Add */ - for (i = 0; i < pBD->nNumRadEndpoints; i += 2) - { - /* Check whether this pair, (u,w), has already been saved */ - if (u == pBD->RadEndpoints[i] && - v2 == pBD->RadEndpoints[i + 1]) - { - break; - } - } - if (i >= pBD->nNumRadEndpoints) - { - /* Add new (u,w) pair */ - if (pBD->nNumRadEndpoints + 2 <= pBD->max_num_vertices) - { - /* add */ - pBD->RadEndpoints[pBD->nNumRadEndpoints++] = u; /* radical */ - pBD->RadEndpoints[pBD->nNumRadEndpoints++] = v2; /* endpoint */ - num_found++; - /*return 1;*/ /* registered */ - } - else - { - return BNS_VERT_EDGE_OVFL; - } - } - } - } - if (num_found) - { - return 1; - } - } - } - break; - - case RAD_SRCH_FROM_FICT: - /* Find the nearest atom accessible from a fictitious vertex */ - /* go backwards along alt path and stop at the 1st found atom (not a fictitious vertex) */ - - v = u; - w = NO_VERTEX; /* the nearest atom -- radical-endpoint */ - u = NO_VERTEX; /* fictitious vertex carrying a radical */ - - while (v > Vertex_t) - { - u = v; - if (!( v % 2 ) && v / 2 <= pBNS->num_atoms && - pBNS->vert[v / 2 - 1].st_edge.cap - pBNS->vert[v / 2 - 1].st_edge.flow < 2) - { - w = v; /* vertex w is atom that may be singlet or doublet but not triplet */ - } - v = GetPrevVertex( pBNS, u, pBD->SwitchEdge, &iuv ); - } - v = u / 2 - 1; /* vertex u may be the radical from which the path originated; w is the nearest atom */ - if (w == NO_VERTEX || u == NO_VERTEX || w % 2 || u == w || v < pBNS->num_atoms || - pBNS->vert[v].st_edge.cap == pBNS->vert[v].st_edge.flow || - ( w = w / 2 - 1 ) >= pBNS->num_atoms) - { - break; /* reject */ - } - u = v; - /* At pBNS->vert[u] we have found the radical that originated the path, w is the nearest atom */ - for (i = 0; i < pBD->nNumRadEndpoints; i += 2) - { - if (u == pBD->RadEndpoints[i] && - w == pBD->RadEndpoints[i + 1]) - { - break; /* this pair has already been stored */ - } - } - if (i >= pBD->nNumRadEndpoints) - { - /* A new pair has been found */ - if (pBD->nNumRadEndpoints + 2 <= pBD->max_num_vertices) - { - /* Add */ - pBD->RadEndpoints[pBD->nNumRadEndpoints++] = u; /* radical */ - pBD->RadEndpoints[pBD->nNumRadEndpoints++] = w; /* endpoint */ - return 1; /* registered */ - } - else - { - return BNS_VERT_EDGE_OVFL; - } - } - break; - } - - return 0; /* rejected */ -} - - -/****************************************************************************/ -int cmp_rad_endpoints( const void *a1, const void *a2 ) -{ - /* Vertex radical_vertex, radical_endpoint */ - const Vertex *p1 = (const Vertex *) a1; - const Vertex *p2 = (const Vertex *) a2; - - if (p1[0] < p2[0]) - { - return -1; - } - if (p1[0] > p2[0]) - { - return 1; - } - if (p1[1] < p2[1]) - { - return -1; - } - if (p1[1] > p2[1]) - { - return 1; - } - - return 0; -} - - -/****************************************************************************/ -int RemoveRadEndpoints( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at ) -{ - BNS_EDGE *e; - EdgeIndex ie; - BNS_VERTEX *p1, *p2; - Vertex v1, v2; - int i, delta, rad; - - for (i = pBD->nNumRadEdges - 1; 0 <= i; i--) - { - ie = pBD->RadEdges[i]; - if (ie < 0 || ie >= pBNS->num_edges) - { - goto error_exit; - } - e = pBNS->edge + ie; - v1 = e->neighbor1; - v2 = e->neighbor12 ^ v1; /* v2 > v1 <=> v2 was added later */ - if (ie + 1 != pBNS->num_edges || - v1 < 0 || v1 >= pBNS->num_vertices || - v2 < 0 || v2 >= pBNS->num_vertices) - { - goto error_exit; - } - p1 = pBNS->vert + v1; - p2 = pBNS->vert + v2; - - if (p2->iedge[p2->num_adj_edges - 1] != ie || - p1->iedge[p1->num_adj_edges - 1] != ie) - { - goto error_exit; - } - - p2->num_adj_edges--; - p1->num_adj_edges--; - p2->iedge[p2->num_adj_edges] = 0; - p1->iedge[p1->num_adj_edges] = 0; - p2->st_edge.flow -= e->flow; - p1->st_edge.flow -= e->flow; - - if (!p2->num_adj_edges && v2 >= pBNS->num_atoms) - { - if (v2 + 1 != pBNS->num_vertices) - { - goto error_exit; - } - memset( p2, 0, sizeof( *p2 ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - pBNS->num_vertices--; - } - - if (!p1->num_adj_edges && v1 >= pBNS->num_atoms) - { - if (v1 + 1 != pBNS->num_vertices) - { - goto error_exit; - } - memset( p1, 0, sizeof( *p1 ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - pBNS->num_vertices--; - } - - if (at && v1 < pBNS->num_atoms) - { - delta = p1->st_edge.cap - p1->st_edge.flow; - rad = at[v1].radical; - switch (delta) - { - case 0: - if (rad == RADICAL_DOUBLET) - { - rad = 0; - } - break; - case 1: - if (rad != RADICAL_DOUBLET) - { - rad = RADICAL_DOUBLET; - } - } - at[v1].radical = rad; - } - memset( e, 0, sizeof( *e ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - pBNS->num_edges--; - } - pBD->nNumRadEdges = 0; - pBD->nNumRadicals = 0; - pBD->bRadSrchMode = RAD_SRCH_NORM; - return 0; - -error_exit: - - return BNS_PROGRAM_ERR; -} - - -/****************************************************************************/ -int RestoreRadicalsOnly( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at ) -{ - BNS_EDGE *e; - EdgeIndex ie; - BNS_VERTEX *p1, *p2; - Vertex v1, v2; - int i, delta, rad; - int p1_num_adj_edges, p2_num_adj_edges; - - for (i = pBD->nNumRadEdges - 1; 0 <= i; i--) - { - ie = pBD->RadEdges[i]; - if (ie < 0 || ie >= pBNS->num_edges) - { - goto error_exit; - } - e = pBNS->edge + ie; - v1 = e->neighbor1; /* atom */ - v2 = e->neighbor12 ^ v1; /* v2 > v1 <=> v2 was added later */ - if (v1 < 0 || v1 >= pBNS->num_atoms || - v2 < pBNS->num_atoms || v2 >= pBNS->num_vertices) - { - goto error_exit; - } - p1 = pBNS->vert + v1; - p2 = pBNS->vert + v2; - - p1_num_adj_edges = e->neigh_ord[0]; - p2_num_adj_edges = e->neigh_ord[1]; - - if (p2->iedge[p2_num_adj_edges] != ie || - p1->iedge[p1_num_adj_edges] != ie) - { - goto error_exit; - } - - if (at && v1 < pBNS->num_atoms) - { - delta = p1->st_edge.cap - p1->st_edge.flow + e->flow; - rad = at[v1].radical; - switch (delta) - { - case 0: - if (rad == RADICAL_DOUBLET) - rad = 0; - break; - case 1: - if (rad != RADICAL_DOUBLET) - rad = RADICAL_DOUBLET; - } - at[v1].radical = rad; - } - } - return 0; - -error_exit: - - return BNS_PROGRAM_ERR; -} - - -/****************************************************************************/ -int SetRadEndpoints( BN_STRUCT *pBNS, BN_DATA *pBD, BRS_MODE bRadSrchMode ) -{ - int ret, i, j, k, delta; /* djb-rwth: removing redundant variables */ - BNS_VERTEX *pRad, *pEndp; - Vertex wRad, vRad, vEndp, nNumRadicals; - int nDots = 0 /* added initialization, 2006-03 */, nNumEdges; - - if (pBNS->tot_st_cap <= pBNS->tot_st_flow) - { - return 0; - } - - pBD->nNumRadEndpoints = 0; - pBD->nNumRadEdges = 0; - pBD->bRadSrchMode = bRadSrchMode; - pBNS->alt_path = pBNS->altp[0]; - pBNS->bChangeFlow = 0; - ret = BalancedNetworkSearch( pBNS, pBD, BNS_EF_RAD_SRCH ); - ReInitBnData( pBD ); - ReInitBnStructAltPaths( pBNS ); - if (!ret && pBD->nNumRadEndpoints >= 2) - { - /* Sort by radical locations */ - qsort( pBD->RadEndpoints, pBD->nNumRadEndpoints / 2, 2 * sizeof( pBD->RadEndpoints[0] ), cmp_rad_endpoints ); - /* djb-rwth: removing redundant code */ - nNumRadicals = 0; - - /* Create new vertices (type=BNS_VERT_TYPE_TEMP) and edges with flow=cap=1 */ - /* connecting the new vertices radical vertices */ - for (i = 0; i < pBD->nNumRadEndpoints; i = j) - { - wRad = pBD->RadEndpoints[i]; - pRad = pBNS->vert + wRad; - delta = pRad->st_edge.cap - ( pRad->st_edge.flow & EDGE_FLOW_ST_MASK ); - if (delta <= 0) - { - delta = 1; - } - nNumEdges = 0; - for (j = i; j < pBD->nNumRadEndpoints && wRad == pBD->RadEndpoints[j]; j += 2) - { - nNumEdges++; - } - /* Add new aux vertex to the radical atom/vertex */ - vRad = bAddNewVertex( pBNS, wRad, delta, delta, nNumEdges + 1, &nDots ); - if (IS_BNS_ERROR( vRad )) - { - ret = vRad; - goto error_exit; - } - pRad = pBNS->vert + vRad; - pBD->RadEdges[pBD->nNumRadEdges++] = pRad->iedge[pRad->num_adj_edges - 1]; - /* Replace references to vertex wRad with vRad */ - for (k = i, nNumEdges = 0; k < j; k += 2) /* djb-rwth: ignoring LLVM warning: variable used */ - { - pBD->RadEndpoints[k] = vRad; - } - nNumRadicals++; - } - /* All vRad vertex indices should be in the range vFirstNewVertex...vFirstNewVertex+nNumRadicals-1 */ - /* connect new vertices to the radical endpoints thus replacing radicals with even-length alternating cycles */ - for (i = 0; i < pBD->nNumRadEndpoints; i = j) - { - vRad = pBD->RadEndpoints[i]; - pRad = pBNS->vert + vRad; - for (j = i; j < pBD->nNumRadEndpoints && vRad == pBD->RadEndpoints[j]; j += 2) - { - /* Connect vew vertex pRad to radical endpoints */ - vEndp = pBD->RadEndpoints[j + 1]; - pEndp = pBNS->vert + vEndp; - ret = AddNewEdge( pRad, pEndp, pBNS, 1, 0 ); - if (IS_BNS_ERROR( ret )) - { - goto error_exit; - } - pBD->RadEdges[pBD->nNumRadEdges++] = ret; - } - } - pBD->nNumRadicals = nNumRadicals; - return nNumRadicals; /* done */ - } - - return 0; /* nothing to do */ - -error_exit: - RemoveRadEndpoints( pBNS, pBD, NULL ); - - return ret; -} - - -#define MAX_NUM_RAD 256 - - -/****************************************************************************/ -int SetRadEndpoints2( CANON_GLOBALS *pCG, - BN_STRUCT *pBNS, - BN_DATA *pBD, - BRS_MODE bRadSrchMode ) -{ - int ret = 0, i, j, k, n, delta = 1; /* djb-rwth: removing redundant variables */ - BNS_VERTEX *pRad, *pEndp; - Vertex wRad, vRad, vEndp, nNumRadicals; - Vertex vRadList[MAX_NUM_RAD], vRadEqul[MAX_NUM_RAD]; - int nNumRad = 0; - int edge_flow; - int nDots = 0 /* added initialization, 2006-03 */, nNumEdges; - NodeSet VertSet; - - if (pBNS->tot_st_cap <= pBNS->tot_st_flow) - { - return 0; - } - - /* Find all radicals: their vertices have st_cap-st_flow=delta */ - /* save radical atom numbers in vRadList[] and remove radical by making st_cap=st_flow */ - for (i = 0; i < pBNS->num_atoms; i++) - { - if (pBNS->vert[i].st_edge.cap - delta == ( pBNS->vert[i].st_edge.flow & EDGE_FLOW_ST_MASK )) - { - if (nNumRad < MAX_NUM_RAD) - { - pBNS->vert[i].st_edge.cap -= delta; - pBNS->tot_st_cap -= delta; - vRadList[nNumRad] = i; /* radical position; i > j <=> vRadList[i] > vRadList[j] */ - vRadEqul[nNumRad] = nNumRad; /* the smallest radical atom that has reachable - * atoms in common with this radical atom - * always keep vRadEqul[nNumRad] <= nNumRad */ - nNumRad++; - } - } - } - - if (pBNS->tot_st_cap - pBNS->tot_st_flow > nNumRad) - { - return BNS_CAP_FLOW_ERR; /* extra st_cap on non-atoms or program error */ - } - - memset( &VertSet, 0, sizeof( VertSet ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - - /* Find reachable atoms by enabling each radical separately */ - for (j = 0; j < nNumRad; j++) - { - i = vRadList[j]; - pBD->nNumRadEndpoints = 0; - pBD->nNumRadEdges = 0; - pBD->bRadSrchMode = bRadSrchMode; - pBNS->alt_path = pBNS->altp[0]; - pBNS->bChangeFlow = 0; - pBNS->vert[i].st_edge.cap += delta; /* enable single radical */ - pBNS->tot_st_cap += delta; - ret = BalancedNetworkSearch( pBNS, pBD, BNS_EF_RAD_SRCH ); /* find reachable atoms */ - ReInitBnData( pBD ); - ReInitBnStructAltPaths( pBNS ); - pBD->bRadSrchMode = RAD_SRCH_NORM; - pBNS->vert[i].st_edge.cap -= delta; /* disable single radical */ - pBNS->tot_st_cap -= delta; - if (IS_BNS_ERROR( ret )) - { - goto error_exit; - } - else - { - if (ret) - { - ret = BNS_RADICAL_ERR; /* found augmenting path: should not happen since only one radical was enabled */ - goto error_exit; - } - } - if (!ret && pBD->nNumRadEndpoints >= 2) - { - /* Sort by: primary_key=radical locations, secondary_key=radical endoint */ - - qsort( pBD->RadEndpoints, pBD->nNumRadEndpoints / 2, 2 * sizeof( pBD->RadEndpoints[0] ), cmp_rad_endpoints ); - - if (pBD->RadEndpoints[0] != i || pBD->RadEndpoints[pBD->nNumRadEndpoints - 2] != i) - { - ret = BNS_RADICAL_ERR; /* more than one radical vertex */ - goto error_exit; - } - if (nNumRad > 1) - { - /* If more than one radical then save reachable atoms in bitmaps to allow */ - /* faster finding whether same atoms are reachable by two or more radicals */ - /* Later merge such sets */ - if (NULL == VertSet.bitword) - { - SetBitCreate( pCG ); - if (!NodeSetCreate( pCG, &VertSet, pBNS->num_atoms, nNumRad )) - { - ret = BNS_OUT_OF_RAM; /* out of RAM */ - goto error_exit; - } - } - - NodeSetFromRadEndpoints( pCG, &VertSet, j, pBD->RadEndpoints, pBD->nNumRadEndpoints ); - - /* Do not allow any radical center be treated as a reachable atom: */ - - RemoveFromNodeSet( pCG, &VertSet, j, vRadList, nNumRad ); - } - } - } - - /* Restore radical st_cap so that st_cap-st_flow=delta */ - for (j = 0; j < nNumRad; j++) - { - i = vRadList[j]; - pBNS->vert[i].st_edge.cap += delta; - pBNS->tot_st_cap += delta; - } - - /* Merge lists that have common radical endpoints */ - /* defect: if vertex sets i and j do not intersect they will be compared 2 times */ - /* total up to nNumRad*(nNumRad-1)/2 calls to DoNodeSetsIntersect() */ - if (nNumRad > 1) - { - for (i = 0; i < nNumRad; i++) - { - if (vRadEqul[i] != i) - { - continue; - } - do - { - n = 0; - for (j = i + 1; j < nNumRad; j++) - { - if (vRadEqul[j] != j) - { - continue; - } - if (DoNodeSetsIntersect( &VertSet, i, j )) - { - AddNodeSet2ToNodeSet1( &VertSet, i, j ); - vRadEqul[j] = i; /* Set j was copied to set i; i < j */ - n++; - } - } - } while (n); - } - /* Fill out pBD->RadEndpoints[] */ - for (i = 0, n = 0; i < nNumRad; i++) - { - if (i == vRadEqul[i]) - { - if (!IsNodeSetEmpty( &VertSet, i )) - { - /* Store equivalent radicals */ - for (j = i + 1; j < nNumRad; j++) - { - if (i == vRadEqul[j]) - { - pBD->RadEndpoints[n++] = vRadList[i]; - pBD->RadEndpoints[n++] = -vRadList[j] - 2; /* equivalent radical, alvays not zero */ - } - } - /* Store endpoints */ - n = AddNodesToRadEndpoints( pCG, &VertSet, i, pBD->RadEndpoints, vRadList[i], n, pBD->max_len_Pu_Pv ); - if (n < 0) - { - ret = BNS_RADICAL_ERR; /* pBD->RadEndpoints overflow */ - goto error_exit; - } - } - else - { - pBD->RadEndpoints[n++] = vRadList[i]; - pBD->RadEndpoints[n++] = -1; /* immobile radical, only one edge to add */ - } - } - } - pBD->nNumRadEndpoints = n; - NodeSetFree( pCG, &VertSet ); - } - else - { - if (nNumRad == 1 && !pBD->nNumRadEndpoints) - { - /* 2006-07-30: a single radical; no possible endpoint found */ - for (i = 0, n = 0; i < nNumRad; i++) - { - pBD->RadEndpoints[n++] = vRadList[i]; - pBD->RadEndpoints[n++] = -1; /* immobile radical, only one edge to add */ - } - pBD->nNumRadEndpoints = n; - } - } - - if (!ret && pBD->nNumRadEndpoints >= 2) - { - /* Already sorted by radical locations */ - /* djb-rwth: removing redundant code */ - nNumRadicals = 0; - /************************************************************************** - * Create new vertices (type=BNS_VERT_TYPE_TEMP) and edges with flow=cap=1 - * connecting the new vertices radical vertices - * - * - * Original structure: atom A is a radical center A==B--C*--D==E - * A*--B==C--D==E atoms C and E are reachable: A==B--C===D--E* - * - * Resultant temporary structure: - * A---B==C--D==E - * || / / - * || / / The additional new vertex (*) and its - * || / / 3 edges replace the radical with alternating - * || / / circuits that allow same bond changes - * || / / as moving the radical to atoms C or E. - * ||// "Double bonds" here have edge cap=1, flow=1 - * (*) "Single bonds" have edge cap=1, flow=0 - * - * The "equivalent radical centers" (which have at least one reachable atom - * in common) are connected to (*) with "double bonds" (edge cap=1, flow=1). - * Reachable non-radical atoms are connected by edges with cap=1, flow=0 - * After running BNS to find alt.path a "double bond" from (*) may move - * to another atom thus muving the radical. - * - * Number of additional (*) vertices = number of sets of - * "equivalent radical centers". - * Each such a set may include one or more radical centers. - * - * The radicals will be re-created in RemoveRadEndpoints() - ***************************************************************************/ - for (i = 0; i < pBD->nNumRadEndpoints; i = j) - { - wRad = pBD->RadEndpoints[i]; - pRad = pBNS->vert + wRad; - delta = pRad->st_edge.cap - ( pRad->st_edge.flow & EDGE_FLOW_ST_MASK ); - if (delta <= 0) - { - delta = 1; - } - nNumEdges = 0; - for (j = i; j < pBD->nNumRadEndpoints && wRad == pBD->RadEndpoints[j]; j += 2) - { - nNumEdges += ( pBD->RadEndpoints[j + 1] != -1 ); /* immobile radicals have one edge only */ - } - /* Add new aux vertex to the radical atom/vertex making st_cap-st_flow=0 */ - /* in case of immobile radical there will be no additional eddges since nNumEdges=0 */ - vRad = bAddNewVertex( pBNS, wRad, delta, delta, nNumEdges + 1, &nDots ); - if (IS_BNS_ERROR( vRad )) - { - ret = vRad; - goto error_exit; - } - pRad = pBNS->vert + vRad; - pBD->RadEdges[pBD->nNumRadEdges++] = pRad->iedge[pRad->num_adj_edges - 1]; - /* replace references to vertex wRad with vRad */ - for (k = i, nNumEdges = 0; k < j; k += 2) /* djb-rwth: ignoring LLVM warning: variable used */ - { - pBD->RadEndpoints[k] = vRad; - } - nNumRadicals++; - } - /* All vRad vertex indices should be in the range vFirstNewVertex...vFirstNewVertex+nNumRadicals-1 */ - /* connect new vertices to the radical endpoints thus replacing radicals with even-length alternating cycles */ - for (i = 0; i < pBD->nNumRadEndpoints; i = j) - { - vRad = pBD->RadEndpoints[i]; - pRad = pBNS->vert + vRad; - for (j = i; j < pBD->nNumRadEndpoints && vRad == pBD->RadEndpoints[j]; j += 2) - { - /* connect vew vertex pRad to radical endpoints */ - vEndp = pBD->RadEndpoints[j + 1]; - if (vEndp == -1) - continue; - if (vEndp < 0) - { - edge_flow = 1; - vEndp = -vEndp - 2; /* equivalent radical centers */ - } - else - { - edge_flow = 0; - } - pEndp = pBNS->vert + vEndp; - ret = AddNewEdge( pRad, pEndp, pBNS, 1, edge_flow ); - if (IS_BNS_ERROR( ret )) - { - goto error_exit; - } - pBD->RadEdges[pBD->nNumRadEdges++] = ret; - } - } - pBD->nNumRadicals = nNumRadicals; - return nNumRadicals; /* done */ - } - return 0; /* nothing to do */ - -error_exit: - RemoveRadEndpoints( pBNS, pBD, NULL ); - NodeSetFree( pCG, &VertSet ); - - return ret; -} - - -#else -/****************************************************************************/ -int SetRadEndpoints( BN_STRUCT *pBNS, BN_DATA *pBD, BRS_MODE bRadSrchMode ) -{ - return 0; -} -int RemoveRadEndpoints( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at ) -{ - return 0; -} -int SetRadEndpoints2( CANON_GLOBALS *pCG, BN_STRUCT *pBNS, BN_DATA *pBD, BRS_MODE bRadSrchMode ) -{ - return 0; -} -#endif - - -/**************************************************************************** -bExistsAltPath( ... ) - -Return value ret bits if not IS_BNS_ERROR(ret): - -ret & 1 => Success -ret & 2 => Bonds changed to Alt -(ret & ~3) >> 2 => nDelta: number of removed dots -****************************************************************************/ -int bExistsAltPath( CANON_GLOBALS *pCG, - BN_STRUCT *pBNS, - BN_DATA *pBD, - BN_AATG *pAATG, - inp_ATOM *at, - int num_atoms, - int nVertDoubleBond, - int nVertSingleBond, - int path_type ) -{ - ALT_PATH_CHANGES apc; - int ret, ret_val, bError, bSuccess, bChangeFlow = 0, nDots, nDelta, bDoMarkChangedBonds = 1; - int bAdjustRadicals = 0; - AT_NUMB type; - BNS_FLOW_CHANGES fcd[4 * BNS_MAX_NUM_FLOW_CHANGES + 1]; - ENDPOINT_INFO eif; -#if ( KETO_ENOL_TAUT == 1 ) - ENDPOINT_INFO eif2; -#endif - - /* Initialize */ - switch (path_type) - { - case ALT_PATH_MODE_TAUTOM: - /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = BNS_EF_CHNG_RSTR; - if (!at[nVertSingleBond].endpoint && - ( !nGetEndpointInfo( at, nVertSingleBond, &eif ) || !eif.cDonor )) - { - return 0; - } - if (!at[nVertDoubleBond].endpoint && - ( !nGetEndpointInfo( at, nVertDoubleBond, &eif ) || !eif.cAcceptor )) - { - return 0; - } - break; - -#if ( TAUT_PT_22_00 == 1 ) - case ALT_PATH_MODE_TAUTOM_PT_22_00: - /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = BNS_EF_CHNG_RSTR; - if (!at[nVertSingleBond].endpoint && - (!nGetEndpointInfo_PT_22_00(at, nVertSingleBond, &eif) || !eif.cDonor)) - return 0; - if (!at[nVertDoubleBond].endpoint && - (!nGetEndpointInfo_PT_22_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) - return 0; - break; -#endif - -#if ( TAUT_PT_16_00 == 1 ) - case ALT_PATH_MODE_TAUTOM_PT_16_00: - /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = BNS_EF_CHNG_RSTR; - if (!at[nVertSingleBond].endpoint && - (!nGetEndpointInfo_PT_16_00(at, nVertSingleBond, &eif) || !eif.cDonor)) - return 0; - if (!at[nVertDoubleBond].endpoint && - (!nGetEndpointInfo_PT_16_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) - return 0; - break; -#endif - -#if ( TAUT_PT_06_00 == 1 ) - case ALT_PATH_MODE_TAUTOM_PT_06_00: - /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = BNS_EF_CHNG_RSTR; - if (!at[nVertSingleBond].endpoint && - (!nGetEndpointInfo_PT_06_00(at, nVertSingleBond, &eif) || !eif.cDonor)) - return 0; - if (!at[nVertDoubleBond].endpoint && - (!nGetEndpointInfo_PT_06_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) - return 0; - break; -#endif - -#if ( TAUT_PT_39_00 == 1 ) - case ALT_PATH_MODE_TAUTOM_PT_39_00: - /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = BNS_EF_CHNG_RSTR; - if (!at[nVertSingleBond].endpoint && - (!nGetEndpointInfo_PT_39_00(at, nVertSingleBond, &eif) || !eif.cDonor)) - return 0; - if (!at[nVertDoubleBond].endpoint && - (!nGetEndpointInfo_PT_39_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) - return 0; - break; -#endif - -#if ( TAUT_PT_13_00 == 1 ) - case ALT_PATH_MODE_TAUTOM_PT_13_00: - /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = BNS_EF_CHNG_RSTR; - if (!at[nVertSingleBond].endpoint && - (!nGetEndpointInfo_PT_13_00(at, nVertSingleBond, &eif) || !eif.cDonor)) - return 0; - if (!at[nVertDoubleBond].endpoint && - (!nGetEndpointInfo_PT_13_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) - return 0; - break; -#endif - -#if ( TAUT_PT_18_00 == 1 ) - case ALT_PATH_MODE_TAUTOM_PT_18_00: - /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = BNS_EF_CHNG_RSTR; - if (!at[nVertSingleBond].endpoint && - (!nGetEndpointInfo_PT_18_00(at, nVertSingleBond, &eif) || !eif.cDonor)) - return 0; - if (!at[nVertDoubleBond].endpoint && - (!nGetEndpointInfo_PT_18_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) - return 0; - break; -#endif - - -#if ( KETO_ENOL_TAUT == 1 ) - case ALT_PATH_MODE_TAUTOM_KET: - /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = BNS_EF_CHNG_RSTR; - - if (!at[nVertSingleBond].endpoint && - ( !nGetEndpointInfo_KET( at, nVertSingleBond, &eif ) || !eif.cDonor )) - { - return 0; - } - if (!at[nVertDoubleBond].endpoint && - ( !nGetEndpointInfo_KET( at, nVertDoubleBond, &eif2 ) || !eif2.cAcceptor )) - { - return 0; - } - /* - if ( eif.cKetoEnolCode + eif2.cKetoEnolCode != 3 ) - return 0; - */ - break; - -#endif - case ALT_PATH_MODE_CHARGE: - /* Find alt path allowing to move (+). Purpose: establish "charge groups", - mark alt. bonds due to (+) charge movement */ - type = BNS_VERT_TYPE_C_POINT; - bChangeFlow = ( BNS_EF_CHNG_RSTR | BNS_EF_ALTR_BONDS ); - break; - - case ALT_PATH_MODE_4_SALT: - case ALT_PATH_MODE_4_SALT2: - /* Find alt paths allowing to move (-) and H between "acidic oxygen atoms". - Purpose: mark alt bonds due to this "long range" tautomerism. */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = ( BNS_EF_CHNG_RSTR | BNS_EF_ALTR_BONDS ); - if (!bIsBnsEndpoint( pBNS, nVertSingleBond ) /* !at[nVertSingleBond].endpoint*/ && - ( !nGetEndpointInfo( at, nVertSingleBond, &eif ) || !eif.cDonor )) - { - return 0; - } - if (!bIsBnsEndpoint( pBNS, nVertDoubleBond ) /* !at[nVertDoubleBond].endpoint*/ && - ( !nGetEndpointInfo( at, nVertDoubleBond, &eif ) || !eif.cAcceptor )) - { - return 0; - } - memset( &apc, 0, sizeof( apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - break; - - case ALT_PATH_MODE_REM2H_CHG: - bChangeFlow |= BNS_EF_ALTR_BONDS; /* fall through */ - case ALT_PATH_MODE_REM2H_TST: - bChangeFlow |= BNS_EF_CHNG_RSTR; - type = BNS_VERT_TYPE_ENDPOINT; - /* Allow non-tautomeric donors or any tautomeric atom */ - if (!bIsBnsEndpoint( pBNS, nVertSingleBond ) /* not linked to a t-group or the edge forbidden */ && - ( !nGetEndpointInfo( at, nVertSingleBond, &eif ) || !eif.cDonor )) /* not a donor */ - { - return 0; - } - if (!bIsBnsEndpoint( pBNS, nVertDoubleBond ) /* not connected to a t-group */ && - ( !nGetEndpointInfo( at, nVertDoubleBond, &eif ) || !eif.cDonor )) - { - return 0; - } - memset( &apc, 0, sizeof( apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - break; - - case ALT_PATH_MODE_ADD2H_CHG: - bChangeFlow |= BNS_EF_ALTR_BONDS; /* fall through */ - case ALT_PATH_MODE_ADD2H_TST: - bChangeFlow |= BNS_EF_CHNG_RSTR; - type = BNS_VERT_TYPE_ENDPOINT; - /* Allow non-tautomeric acceptors or any tautomeric atom */ - if (!bIsBnsEndpoint( pBNS, nVertSingleBond ) /* !at[nVertSingleBond].endpoint*/ && - ( !nGetEndpointInfo( at, nVertSingleBond, &eif ) || !eif.cAcceptor )) - { - return 0; - } - if (!bIsBnsEndpoint( pBNS, nVertDoubleBond ) /* !at[nVertSingleBond].endpoint*/ && - ( !nGetEndpointInfo( at, nVertDoubleBond, &eif ) || !eif.cAcceptor )) - { - return 0; - } - break; - - case ALT_PATH_MODE_REM_PROTON: - /* alt path is between the t-group (nVertDoubleBond) and - the (+)-charge group (nVertSingleBond) */ - type = 0; - /*bDoMarkChangedBonds = 0;*/ - bChangeFlow = ( BNS_EF_SAVE_ALL | BNS_EF_UPD_H_CHARGE ) | BNS_EF_ALTR_NS; /* added BNS_EF_ALTR_NS: set non-stereo altern non-ring bonds 2004-07-02*/ - break; - default: - type = 0; - bChangeFlow = BNS_EF_CHNG_RSTR; - break; - } - - bError = 0; - bSuccess = 0; - nDelta = 0; - - ret = SetRadEndpoints2( pCG, pBNS, pBD, RAD_SRCH_NORM ); - if (IS_BNS_ERROR( ret )) - { - return ret; - } - - /* Set BNS to check alt path */ - ret = bSetBnsToCheckAltPath( pBNS, nVertDoubleBond, nVertSingleBond, type, path_type, &apc, fcd, &nDots ); - switch (ret) - { - case BNS_CHK_ALTP_NO_ALTPATH: - ret = RemoveRadEndpoints( pBNS, pBD, NULL ); - return ret; - case BNS_CHK_ALTP_SAME_TGROUP: - bSuccess = 1; - goto reinit_BNS; - case BNS_CHK_ALTP_SAME_VERTEX: - ret = RemoveRadEndpoints( pBNS, pBD, NULL ); - return ret ? ret : 1; /* very strange ... set a breakpoint here */ - case BNS_CHK_ALTP_SET_SUCCESS: - break; /* actually check the existence of the altpath */ - case BNS_CANT_SET_BOND: - goto reinit_BNS; - default: - ret_val = RemoveRadEndpoints( pBNS, pBD, NULL ); /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - if (IS_BNS_ERROR( ret )) - { - return ret; - } - return BNS_PROGRAM_ERR; - } - - bAdjustRadicals = ( ( bChangeFlow & BNS_EF_UPD_RAD_ORI ) && !( bChangeFlow & BNS_EF_RSTR_FLOW ) ); - - /***************************************************************** - * nDots = 2 for ALT_PATH_CHARGE (checking moveable positive charges) - * Now nDots for ALT_PATH_TAUTOM or ALT_PATH_4_SALT can be greater - * because some of the bonds are effectively removed and dots - * (vertex st-caps) may be added - * -- to make sure there is no (+) charge on a tautomeric endpoint - * -- to fix positions of moveable tautomeric attachements - * (H and (-)-charges) at the ends of an alt path - */ - - /* Run BNS */ - - ret = RunBalancedNetworkSearch( pBNS, pBD, bChangeFlow ); - - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - else if (ret > 0) - { - if (2 * ret >= nDots) - { - nDelta = 2 * ret - nDots; /* non-zero means augmentation created another alt. path -- between radicals */ - if (pAATG && pAATG->nMarkedAtom) - { - if (pAATG->nAtTypeTotals && ( bChangeFlow & BNS_EF_UPD_H_CHARGE )) - { - memset( pAATG->nMarkedAtom, 0, num_atoms * sizeof( pAATG->nMarkedAtom[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - /* Mark atoms that have charge or H changed, check their input types (that is, before changes), - and subtract their input charge/H from nAtTypeTotals */ - SubtractOrChangeAtHChargeBNS( pBNS, at, num_atoms, pAATG->nAtTypeTotals, pAATG->nMarkedAtom, NULL, 1 ); - /* ZChange charges and/or H, update t_group_info, do not check types or change nAtTypeTotals */ - /* Atom types will be checked and nAtTypeTotals will be changed in - AddChangedAtHChargeBNS() later */ - SubtractOrChangeAtHChargeBNS( pBNS, at, num_atoms, NULL, NULL, pAATG->t_group_info, 0 ); - } - else - { - if (!pAATG->nAtTypeTotals) - { - bDoMarkChangedBonds = MarkAtomsAtTautGroups( pBNS, num_atoms, pAATG, nVertSingleBond, nVertDoubleBond ); - if (bDoMarkChangedBonds < 0) - { - bError = bDoMarkChangedBonds; - bDoMarkChangedBonds = 0; - } - } - } - } - if (bDoMarkChangedBonds) - { - /* Mark bonds that were changed to configure bond testing */ - ret_val = bSetBondsAfterCheckOneBond( pBNS, fcd, -1, at, num_atoms, bChangeFlow ); - if (IS_BNS_ERROR( ret_val )) - { - bError = ret_val; - } - /*ret = SetBondsRestoreBnStructFlow( pBNS, at, num_atoms, bChangeFlow );*/ - /* mark all other changed bonds */ - ret = SetBondsFromBnStructFlow( pBNS, at, num_atoms, bChangeFlow ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - else - { - if (!( ret & 1 ) && !( ret_val & 1 )) - { - bSuccess = 1; - } - else - { - if ((( ( ret & 1 ) || ( ret_val & 1 ) ) && - ( bChangeFlow & BNS_EF_ALTR_BONDS )) || ( bChangeFlow & BNS_EF_UPD_H_CHARGE )) /* djb-rwth: addressing LLVM warning */ - { - /* Some bonds have been changed to alternating */ - bSuccess = 3; - } - else - { - bError = BNS_BOND_ERR; - } - } - } - if (!bError && pAATG && pAATG->nMarkedAtom && ( bChangeFlow & BNS_EF_UPD_H_CHARGE )) - { - /* Update radicals to avoid errors in atom type check in AddChangedAtHChargeBNS() */ - if (bAdjustRadicals) - { - ret_val = RestoreRadicalsOnly( pBNS, pBD, at ); - if (IS_BNS_ERROR( ret_val )) - { - bError = ret_val; - } - } - /* Check atom types of marked atoms and add charge/H changes to nAtTypeTotals */ - /* Changing atoms were marked in the 1st call to SubtractOrChangeAtHChargeBNS(..., 1) above */ - AddChangedAtHChargeBNS( at, num_atoms, pAATG->nAtTypeTotals, pAATG->nMarkedAtom ); - if (bChangeFlow & BNS_EF_CHNG_FLOW) - { - /* Eliminate ambiguities in already changed flow: - replace (+)--N==(-) with (+)==N--(-) (both represent neutral N) */ - EliminatePlusMinusChargeAmbiguity( pBNS, num_atoms ); - } - } - } - } - - ret = RestoreBnStructFlow( pBNS, bChangeFlow & BNS_EF_CHNG_RSTR ); - - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - } - -reinit_BNS: - - /* --- Reinitialize to repeat the calculations --- */ - bRestoreBnsAfterCheckAltPath( pBNS, &apc, bChangeFlow & BNS_EF_UPD_H_CHARGE ); - bRestoreFlowAfterCheckOneBond( pBNS, fcd ); - ret_val = RemoveRadEndpoints( pBNS, pBD, bAdjustRadicals ? at : NULL ); - ReInitBnStructAltPaths( pBNS ); - - return bError ? bError : ret_val ? ret_val : ( bSuccess + 4 * nDelta ); -} - - -/****************************************************************************/ -BN_STRUCT* AllocateAndInitBnStruct( inp_ATOM *at, - int num_atoms, - int nMaxAddAtoms, - int nMaxAddEdges, - int max_altp, - int *pNum_changed_bonds ) -{ - BN_STRUCT *pBNS = NULL; - BNS_VERTEX *vert; - - int neigh, num_changed_bonds = 0; - U_CHAR bond_type, bond_mark; - - int i, j, k, n_edges, num_bonds, num_edges, f1, f2, edge_cap, edge_flow, st_flow; /* djb-rwth: removing redundant variables */ - int tot_st_cap, tot_st_flow; - int max_tg, max_edges, max_vertices, len_alt_path, max_iedges, num_altp; -#if ( BNS_RAD_SEARCH == 1 ) - int num_rad = 0; - - nMaxAddEdges += 1; -#endif -#if ( FIX_NUM_TG == 1 ) - max_tg = inchi_max( num_atoms / 2, 5 ); -#else - max_tg = num_atoms; -#endif - num_changed_bonds = 0; - - for (i = 0, num_bonds = 0; i < num_atoms; i++) - { - /*(@nnuk : Nauman Ullah Khan) */ - LOG_NO_ARGS("\n################# (L8916:ichi_bns.c) ###################\n"); - LOG_MULT_ARGS("Number of changed bonds (Start): %d\n", num_changed_bonds); - LOG_NO_ARGS("\n########################################################\n"); - - num_bonds += at[i].valence; -#if ( BNS_RAD_SEARCH == 1 ) - num_rad += ( at[i].radical == RADICAL_DOUBLET ); -#endif - } - /* Each atom has enough edges to belong to a tautomeric group + nMaxAddEdges */ - /* number of atoms is large enough to accommodate max. possible number of t-groups + nMaxAddAtoms */ - /* max_altp cannot be larger than BN_MAX_ALTP = 16 */ - num_edges = ( num_bonds /= 2 ); - /* +1 for a super-tautomeric group */ - max_vertices = num_atoms + nMaxAddAtoms + max_tg + 1; - /* +max_tg for edges between t-groups and super-tautomeric group */ - max_edges = num_edges + ( nMaxAddEdges + NUM_KINDS_OF_GROUPS )*max_vertices + max_tg; -#if ( BNS_RAD_SEARCH == 1 ) - if (num_rad) - { - max_vertices *= 2; - max_edges *= 2; - } -#endif - max_iedges = 2 * max_edges; - len_alt_path = max_vertices + iALTP_HDR_LEN + 1; /* may overflow if an edge is traversed in 2 directions */ - - if (!( pBNS = (BN_STRUCT *) inchi_calloc( 1, sizeof( BN_STRUCT ) ) ) || - !( pBNS->edge = (BNS_EDGE *) inchi_calloc( max_edges, sizeof( BNS_EDGE ) ) ) || - !( pBNS->vert = (BNS_VERTEX *) inchi_calloc( max_vertices, sizeof( BNS_VERTEX ) ) ) || - !( pBNS->iedge = (BNS_IEDGE *) inchi_calloc( max_iedges, sizeof( BNS_IEDGE ) ) )) - { - return DeAllocateBnStruct( pBNS ); - } - /* Alt path init */ - for (num_altp = 0; num_altp < max_altp && num_altp < BN_MAX_ALTP; num_altp++) - { - if (!( pBNS->altp[num_altp] = (BNS_ALT_PATH*) inchi_calloc( len_alt_path, sizeof( BNS_ALT_PATH ) ) )) - { - return DeAllocateBnStruct( pBNS ); - } - ALTP_ALLOCATED_LEN( pBNS->altp[num_altp] ) = len_alt_path; - pBNS->len_alt_path = len_alt_path; /* ??? duplication ??? */ - /* re-init */ - ALTP_DELTA( pBNS->altp[num_altp] ) = 0; - ALTP_START_ATOM( pBNS->altp[num_altp] ) = NO_VERTEX; - ALTP_END_ATOM( pBNS->altp[num_altp] ) = NO_VERTEX; - ALTP_PATH_LEN( pBNS->altp[num_altp] ) = 0; - } - pBNS->alt_path = NULL; - pBNS->num_altp = 0; - pBNS->max_altp = num_altp; - - /* Fill vertices (no connectivity) */ - pBNS->vert[0].iedge = pBNS->iedge; - for (i = 0; i < num_atoms; i++) - { - k = pBNS->vert[i].max_adj_edges = at[i].valence + ( nMaxAddEdges + NUM_KINDS_OF_GROUPS ); - pBNS->vert[i + 1].iedge = pBNS->vert[i].iedge + k; - } - pBNS->num_atoms = num_atoms; /* number of real atoms */ - pBNS->num_added_atoms = 0; - pBNS->num_t_groups = 0; /* number of added t-groups */ - pBNS->num_c_groups = 0; - pBNS->nMaxAddAtoms = nMaxAddAtoms; - pBNS->nMaxAddEdges = nMaxAddEdges; - - pBNS->num_vertices = num_atoms; /* current number of vertices, a sum of - pBNS->num_atoms - pBNS->num_t_groups - pBNS->num_added_atoms */ - pBNS->max_vertices = max_vertices; - - - pBNS->num_bonds = num_bonds; /* number of real edges (bonds) */ - pBNS->max_edges = max_edges; - pBNS->max_iedges = max_iedges; - - /* - To remove t-groups and added atoms: - In atoms i = 0..pBNS->num_atoms-1 - pBNS->vert[i].num_adj_edges = pBNS->vert[i].max_adj_edges - pBNS->nMaxAddEdges - NUM_KINDS_OF_GROUPS; - pBNS->num_vertices = pBNS->num_atoms; - pBNS->num_edges = pBNS->num_bonds; - pBNS->num_added_atoms = 0; - pBNS->num_t_groups = 0; - pBNS->num_added_edges = 0; - - ALTP_DELTA(pBNS->alt_path) = 0; - ALTP_START_ATOM(pBNS->alt_path) = NO_VERTEX; - ALTP_END_ATOM(pBNS->alt_path) = NO_VERTEX; - ALTP_PATH_LEN(pBNS->alt_path) = 0; - */ - - /* Fill edges and connectivity */ - tot_st_cap = tot_st_flow = 0; - for (i = 0, n_edges = 0; i < num_atoms; i++) - { - vert = &pBNS->vert[i]; - /* djb-rwth: removing redundant code */ - st_flow = 0; - /* djb-rwth: removing redundant code */ - for (j = 0; j < at[i].valence; j++) - { - neigh = at[i].neighbor[j]; - /* find this bond at the neighbor */ - for (k = 0; k < at[neigh].valence; k++) - { - if (at[neigh].neighbor[k] == i) - { - break; - } - } - bond_type = ( at[i].bond_type[j] & BOND_TYPE_MASK ); - bond_mark = ( at[i].bond_type[j] & ~BOND_TYPE_MASK ); - if (bond_type != BOND_SINGLE && bond_type != BOND_DOUBLE && - bond_type != BOND_TRIPLE /*&& bond_type != BOND_ALTERN*/) - { - /* Make Unknown or Alternating bonds single */ - bond_type = 1; - at[i].bond_type[j] = bond_mark | bond_type; - num_changed_bonds++; - } - if (neigh > i) - { - /* This is the first time we encounter this bond */ - f1 = MAX_AT_FLOW( at[i] ); - f2 = MAX_AT_FLOW( at[neigh] ); - edge_flow = bond_type - 1; - if (edge_flow > MAX_BOND_EDGE_CAP) - { - /* djb-rwth: removing redundant code */ - edge_flow = 0; /* BNS will determine flows (that is, bonds) */ - edge_cap = AROM_BOND_EDGE_CAP; - } - else - { -#if ( 0 && KETO_ENOL_TAUT == 1 ) /* ????? */ - edge_cap = inchi_max( f1, f2 ); -#else - edge_cap = inchi_min( f1, f2 ); -#endif - edge_cap = inchi_min( edge_cap, MAX_BOND_EDGE_CAP ); /* max capacity = 2 means up to triple bond */ - } - - pBNS->edge[n_edges].neighbor1 = (AT_NUMB) i; - pBNS->edge[n_edges].neighbor12 = (AT_NUMB) ( i ^ neigh ); - pBNS->edge[n_edges].flow = pBNS->edge[n_edges].flow0 = edge_flow; - pBNS->edge[n_edges].cap = pBNS->edge[n_edges].cap0 = edge_cap; - pBNS->edge[n_edges].neigh_ord[0] = j; - pBNS->edge[n_edges].neigh_ord[1] = k; - pBNS->edge[n_edges].pass = 0; - pBNS->edge[n_edges].forbidden = 0; - - vert->iedge[j] = pBNS->vert[neigh].iedge[k] = n_edges++; - } - else - { - /* This is the second time we encounter this bond. It was stored at */ - int iedge = pBNS->vert[neigh].iedge[k]; - edge_cap = pBNS->edge[iedge].cap; /* djb-rwth: ignoring LLVM warning: variable used */ - edge_flow = pBNS->edge[iedge].flow; - } - st_flow += edge_flow; - /* djb-rwth: removing redundant code */ - } - vert->num_adj_edges = j; - vert->st_edge.cap = - vert->st_edge.cap0 = MAX_AT_FLOW( at[i] ); - vert->st_edge.flow = - vert->st_edge.flow0 = st_flow; - vert->type = BNS_VERT_TYPE_ATOM; - tot_st_cap += vert->st_edge.cap; - tot_st_flow += vert->st_edge.flow; - } - *pNum_changed_bonds = num_changed_bonds / 2; - - pBNS->num_edges = n_edges; /* number of edges */ - pBNS->num_added_edges = 0; - - /*(@nnuk : Nauman Ullah Khan) */ - LOG_NO_ARGS("\n################# (L9108:ichi_bns.c) ################\n"); - for (i = 0, num_bonds = 0; i < num_atoms; i++) { - - LOG_MULT_ARGS("Element : %s, Number of changed bonds (End): %d\n", at[i].elname, *pNum_changed_bonds); - } - LOG_NO_ARGS("\n#####################################################\n"); - - pBNS->tot_st_cap = tot_st_cap; - pBNS->tot_st_flow = tot_st_flow; - - return pBNS; -} - - -/****************************************************************************/ -BN_STRUCT* DeAllocateBnStruct( BN_STRUCT *pBNS ) -{ - int i; - if (pBNS) - { - if (pBNS->edge) - { - inchi_free( pBNS->edge ); - } - for (i = 0; i < pBNS->max_altp && i < BN_MAX_ALTP; i++) - { - if (pBNS->altp[i]) - { - inchi_free( pBNS->altp[i] ); - } - } - if (pBNS->vert) - { - if (pBNS->vert[0].iedge) - { - inchi_free( pBNS->vert[0].iedge ); - } - inchi_free( pBNS->vert ); - } - inchi_free( pBNS ); - } - - return NULL; -} - - -/****************************************************************************/ -int ReInitBnStructAltPaths( BN_STRUCT *pBNS ) -{ - int i; - for (i = 0; i < pBNS->max_altp && i < BN_MAX_ALTP; i++) - { - if (pBNS->altp[i]) - { - ALTP_DELTA( pBNS->altp[i] ) = 0; - ALTP_PATH_LEN( pBNS->altp[i] ) = 0; - ALTP_START_ATOM( pBNS->altp[i] ) = NO_VERTEX; - ALTP_END_ATOM( pBNS->altp[i] ) = NO_VERTEX; - } - } - pBNS->alt_path = NULL; - pBNS->num_altp = 0; - return i; -} - - -/****************************************************************************/ -int ReInitBnStructAddGroups( CANON_GLOBALS *pCG, - BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - T_GROUP_INFO *tgi, - C_GROUP_INFO *cgi ) -{ - int ret; - /* strip all t-groups and c-groups */ - ret = ReInitBnStruct( pBNS, at, num_atoms, 0 ); - if (ret) - { - ret = BNS_REINIT_ERR; - goto exit_function; - } - /*#if ( MOVE_CHARGES == 1 )*/ - if (*pBNS->pbTautFlags & TG_FLAG_MOVE_POS_CHARGES) - { - /* Add c-groups */ - ret = AddCGroups2BnStruct( pCG, pBNS, at, num_atoms, cgi ); - if (IS_BNS_ERROR( ret )) - { - goto exit_function; - } - } - /*#endif*/ - /* Add t-groups */ - ret = AddTGroups2BnStruct( pCG, pBNS, at, num_atoms, tgi ); - if (IS_BNS_ERROR( ret )) - { - goto exit_function; - } - -exit_function: - - return ret; -} - - -/****************************************************************************/ -int ReInitBnStruct( BN_STRUCT *pBNS, - inp_ATOM *at, - int num_at, - int bRemoveGroupsFromAtoms ) -{ - int i, vfict, kfict, iedgefict, endpoint, centerpoint, iedge, k; - int ret = 0; - if (pBNS) - { - if (pBNS->vert && pBNS->edge) - { - /* Debug */ - for (k = 0, i = 0; k < pBNS->num_edges; k++) - { - if (pBNS->edge[k].pass) - { - i++; - } - } - ret += i * 100; - /* Restore flow and cap on edges to vertices connected to fictitious atoms */ - for (vfict = pBNS->num_atoms; vfict < pBNS->num_vertices; vfict++) - { - for (kfict = 0; kfict < pBNS->vert[vfict].num_adj_edges; kfict++) - { - iedgefict = pBNS->vert[vfict].iedge[kfict]; /* fictitious edge to the endpoint */ - endpoint = pBNS->edge[iedgefict].neighbor12 ^ vfict; /* the endpoint */ - /* To simlify restore cap and flow in ALL edges to the endpoint */ - if (bRemoveGroupsFromAtoms && endpoint < num_at) - { - at[endpoint].c_point = 0; - at[endpoint].endpoint = 0; - } - for (k = 0; k < pBNS->vert[endpoint].num_adj_edges; k++) - { - iedge = pBNS->vert[endpoint].iedge[k]; /* edge to endpoint */ - centerpoint = pBNS->edge[iedge].neighbor12 ^ endpoint; - pBNS->edge[iedge].cap = pBNS->edge[iedge].cap0; - pBNS->edge[iedge].flow = pBNS->edge[iedge].flow0; - pBNS->edge[iedge].pass = 0; -#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) - pBNS->edge[iedge].forbidden &= pBNS->edge_forbidden_mask; -#endif - pBNS->vert[centerpoint].st_edge.cap = pBNS->vert[centerpoint].st_edge.cap0; - pBNS->vert[centerpoint].st_edge.flow = pBNS->vert[centerpoint].st_edge.flow0; - } - pBNS->vert[endpoint].st_edge.cap = pBNS->vert[endpoint].st_edge.cap0; - pBNS->vert[endpoint].st_edge.flow = pBNS->vert[endpoint].st_edge.flow0; - pBNS->vert[endpoint].type &= BNS_VERT_TYPE_ATOM; - } - } - /* Reset number of neighbors */ - if (pBNS->num_edges > pBNS->num_bonds) - { - for (i = 0; i < pBNS->num_atoms; i++) - { - pBNS->vert[i].num_adj_edges = - pBNS->vert[i].max_adj_edges - pBNS->nMaxAddEdges - NUM_KINDS_OF_GROUPS; - } - } - } - else - { - ret += 2; - } - if (!pBNS->edge) - { - ret += 4; - } - if (!pBNS->iedge) - { - ret += 8; - } - - ReInitBnStructAltPaths( pBNS ); - - pBNS->num_vertices = pBNS->num_atoms; - pBNS->num_edges = pBNS->num_bonds; - pBNS->num_added_atoms = 0; - pBNS->num_t_groups = 0; - pBNS->num_c_groups = 0; - pBNS->num_added_edges = 0; - } - else - { - ret += 1; - } - - return ret; -} - - -/****************************************************************************/ -int CompTGroupNumber( const void *tg1, const void *tg2, void *p ) -{ - return (int) ( (const T_GROUP *) tg1 )->nGroupNumber - (int) ( (const T_GROUP *) tg2 )->nGroupNumber; -} - - -/****************************************************************************/ -int CompCGroupNumber( const void *cg1, const void *cg2, void *p ) -{ - return (int) ( (const C_GROUP *) cg1 )->nGroupNumber - (int) ( (const C_GROUP *) cg2 )->nGroupNumber; -} - - -/****************************************************************************/ -int AddTGroups2BnStruct( CANON_GLOBALS *pCG, - BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - T_GROUP_INFO *tgi ) -{ - int ret = 0; - /* ret = ReInitBnStruct( pBNS ); */ - if (tgi && tgi->num_t_groups && tgi->t_group) - { - int i, k, endpoint, centerpoint, fictpoint; - int num_tg = tgi->num_t_groups; - int num_edges = pBNS->num_edges; - int num_vertices = pBNS->num_vertices; - BNS_VERTEX *vert_ficpoint, *ver_ficpont_prev; /* fictitious vertex describing t-group */ - BNS_VERTEX *vert_endpoint; - BNS_EDGE *edge; /* edge between that vertex and the tautomeric endpoint */ - int nMaxTGroupNumber = 0; - ENDPOINT_INFO eif; - - /* Debug: check overflow */ - if (num_vertices + num_tg >= pBNS->max_vertices) - { - return BNS_VERT_EDGE_OVFL; - } - /* Find the largest t-group ID */ - for (i = 0; i < num_tg; i++) - { - if (tgi->t_group[i].nGroupNumber > nMaxTGroupNumber) - { - nMaxTGroupNumber = tgi->t_group[i].nGroupNumber; - } - } - /* Since t-group IDs may be not contiguous, clear all vertices that will be added. - all-zeroes-vertex will be ignored by the BNS - */ - memset( pBNS->vert + num_vertices, 0, nMaxTGroupNumber * sizeof( pBNS->vert[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - /* Make sure the last t-group has the largest t-group ID: - this is necessary to correctly add new edges - and vertices for testing augmenting paths */ -#if ( bRELEASE_VERSION != 1 ) - insertions_sort( pCG, tgi->t_group, num_tg, sizeof( tgi->t_group[0] ), CompTGroupNumber ); - for (i = 1; i < num_tg; i++) - { - if (1 != tgi->t_group[i].nGroupNumber - tgi->t_group[i - 1].nGroupNumber) - { - return BNS_BOND_ERR; - } - } -#else - if (nMaxTGroupNumber != tgi->t_group[num_tg - 1].nGroupNumber) - { - insertions_sort( pCG, tgi->t_group, num_tg, sizeof( tgi->t_group[0] ), CompTGroupNumber ); - } -#endif - /* Initialize new fictitious vertices */ - ver_ficpont_prev = pBNS->vert + num_vertices - 1; - - for (i = 0; i < num_tg; i++, ver_ficpont_prev = vert_ficpoint) - { - /* - vert_ficpoint-1 is the last vertex; - vert_ficpoint is the vertex that is being added - Note: nGroupNumber are not contiguous - */ - vert_ficpoint = pBNS->vert + num_vertices + tgi->t_group[i].nGroupNumber - 1; - vert_ficpoint->iedge = ver_ficpont_prev->iedge + ver_ficpont_prev->max_adj_edges; - vert_ficpoint->max_adj_edges = tgi->t_group[i].nNumEndpoints + BNS_ADD_EDGES + BNS_ADD_SUPER_TGROUP; - vert_ficpoint->num_adj_edges = 0; - vert_ficpoint->st_edge.flow = vert_ficpoint->st_edge.flow0 = 0; - vert_ficpoint->st_edge.cap = vert_ficpoint->st_edge.cap0 = 0; - vert_ficpoint->type = BNS_VERT_TYPE_TGROUP; - } - - for (endpoint = 0; endpoint < num_atoms; endpoint++) - { - if (!at[endpoint].endpoint) - { - continue; - } - fictpoint = at[endpoint].endpoint + num_vertices - 1; - vert_ficpoint = pBNS->vert + fictpoint; - vert_endpoint = pBNS->vert + endpoint; - /* Debug: check overflow */ - if (fictpoint >= pBNS->max_vertices || - num_edges >= pBNS->max_edges || - vert_ficpoint->num_adj_edges >= vert_ficpoint->max_adj_edges || - vert_endpoint->num_adj_edges >= vert_endpoint->max_adj_edges) - { - ret = BNS_VERT_EDGE_OVFL; - break; - } - /* Obtain donor/acceptor info */ - if (!nGetEndpointInfo(at, endpoint, &eif) -#if ( TAUT_PT_22_00 == 1 ) - && !((tgi->bTautFlags & TG_FLAG_PT_22_00) && nGetEndpointInfo_PT_22_00(at, endpoint, &eif)) -#endif -#if ( TAUT_PT_16_00 == 1 ) - && !((tgi->bTautFlags & TG_FLAG_PT_16_00) && nGetEndpointInfo_PT_16_00(at, endpoint, &eif)) -#endif -#if ( TAUT_PT_06_00 == 1 ) - && !((tgi->bTautFlags & TG_FLAG_PT_06_00) && nGetEndpointInfo_PT_06_00(at, endpoint, &eif)) -#endif -#if ( TAUT_PT_39_00 == 1 ) - && !((tgi->bTautFlags & TG_FLAG_PT_39_00) && nGetEndpointInfo_PT_39_00(at, endpoint, &eif)) -#endif -#if ( TAUT_PT_13_00 == 1 ) - && !((tgi->bTautFlags & TG_FLAG_PT_13_00) && nGetEndpointInfo_PT_13_00(at, endpoint, &eif)) -#endif -#if ( TAUT_PT_18_00 == 1 ) - && !((tgi->bTautFlags & TG_FLAG_PT_18_00) && nGetEndpointInfo_PT_18_00(at, endpoint, &eif)) -#endif - ) { -#if ( KETO_ENOL_TAUT == 1 ) - if (!( ( tgi->bTautFlags & TG_FLAG_KETO_ENOL_TAUT ) && - nGetEndpointInfo_KET( at, endpoint, &eif ) )) -#endif - { - ret = BNS_BOND_ERR; - break; - } - } - - vert_endpoint->type |= BNS_VERT_TYPE_ENDPOINT; - - /* Set capacity = 1 to the edges from the endpoint to the centerpoint(s) */ - for (k = 0; k < vert_endpoint->num_adj_edges; k++) - { - int iedge = vert_endpoint->iedge[k]; - if (!pBNS->edge[iedge].cap) - { - /* Single bond, possibly between endpoint and centerpoint */ - centerpoint = ( pBNS->edge[iedge].neighbor12 ^ endpoint ); - if (centerpoint < pBNS->num_atoms && - pBNS->vert[centerpoint].st_edge.cap >= 1) - { - int bond_type = ( at[endpoint].bond_type[k] & BOND_TYPE_MASK ); - if (bond_type == BOND_TAUTOM || - bond_type == BOND_ALTERN || - bond_type == BOND_ALT12NS || - bond_type == BOND_SINGLE) - { - pBNS->edge[iedge].cap = 1; - } - } - } - } - - /* Create a new edge connecting endpoint to the new fictitious t-group vertex vert_ficpoint */ - edge = pBNS->edge + num_edges; - edge->cap = 1; - edge->flow = 0; - edge->pass = 0; -#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) - edge->forbidden &= pBNS->edge_forbidden_mask; -#endif - /* Later include case when the charge change allows the endpoint to become tautomeric */ - /* mark endoint having moveable H atom with flow=1 */ - - /* -- old "no charges" version -- */ - /* if (at[endpoint].chem_bonds_valence == at[endpoint].valence) */ - /* -- the following line takes charges into account -- */ - if (eif.cDonor) /* means the endpoint has an H-atom to donate */ - { - /* increment edge flow */ - edge->flow++; - /* increment one vertex st-flow & cap */ - vert_ficpoint->st_edge.flow++; - vert_ficpoint->st_edge.cap++; - /* increment another vertex st-flow & cap */ - vert_endpoint->st_edge.flow++; - vert_endpoint->st_edge.cap++; - } - /* Connect edge to endpoint and fictpoint and increment the counters of neighbors and edges */ - edge->neighbor1 = endpoint; /* the smallest out of v1=endopoint and v2=num_vertices */ - edge->neighbor12 = endpoint ^ fictpoint; /* v1 ^ v2 */ - vert_endpoint->iedge[vert_endpoint->num_adj_edges] = num_edges; - vert_ficpoint->iedge[vert_ficpoint->num_adj_edges] = num_edges++; - edge->neigh_ord[0] = vert_endpoint->num_adj_edges++; - edge->neigh_ord[1] = vert_ficpoint->num_adj_edges++; - edge->cap0 = edge->cap; - edge->flow0 = edge->flow; - } - - pBNS->num_edges = num_edges; - pBNS->num_vertices += nMaxTGroupNumber; - pBNS->num_t_groups = num_tg; - } - - return ret; -} - - -/*#if ( MOVE_CHARGES == 1 )*/ /* { */ - - - /****************************************************************************/ -int AddCGroups2BnStruct( CANON_GLOBALS *pCG, - BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - C_GROUP_INFO *cgi ) -{ - int ret = 0; - /* ret = ReInitBnStruct( pBNS ); */ - if (cgi && cgi->num_c_groups && cgi->c_group) - { - int i, k, c_point, centerpoint, fictpoint; - int num_cg = cgi->num_c_groups; - int num_edges = pBNS->num_edges; - int num_vertices = pBNS->num_vertices; - BNS_VERTEX *vert_ficpoint, *ver_ficpont_prev; /* fictitious vertex describing charge c-group */ - BNS_VERTEX *vertex_cpoint; - BNS_EDGE *edge; /* edge between that vertex and the tautomeric c_point */ - int nMaxCGroupNumber = 0; - - /* Debug: check overflow */ - if (num_vertices + num_cg >= pBNS->max_vertices) - { - return BNS_VERT_EDGE_OVFL; - } - /* Find the largest t-group ID */ - for (i = 0; i < num_cg; i++) - { - if (cgi->c_group[i].nGroupNumber > nMaxCGroupNumber) - { - nMaxCGroupNumber = cgi->c_group[i].nGroupNumber; - } - } - /* Since t-group IDs may be not contiguous, clear all vertices that will be added. - all-zeroes-vertex will be ignored by the BNS - */ - memset( pBNS->vert + num_vertices, 0, nMaxCGroupNumber * sizeof( pBNS->vert[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - /* Make sure the last t-group has the largest t-group ID: - this is necessary to correctly add new edges and vertices for testing augmenting paths - */ -#if ( bRELEASE_VERSION != 1 ) - insertions_sort( cgi->c_group, num_cg, sizeof( cgi->c_group[0] ), CompCGroupNumber ); - for (i = 1; i < num_cg; i++) - { - if (1 != cgi->c_group[i].nGroupNumber - cgi->c_group[i - 1].nGroupNumber) - { - return BNS_BOND_ERR; - } - } -#else - if (nMaxCGroupNumber != cgi->c_group[num_cg - 1].nGroupNumber) - { - insertions_sort( pCG, cgi->c_group, num_cg, - sizeof( cgi->c_group[0] ), - CompCGroupNumber ); - } -#endif - /**************************************/ - /* initialize new fictitious vertices */ - /* representing c-point groups */ - /**************************************/ - ver_ficpont_prev = pBNS->vert + num_vertices - 1; - - for (i = 0; i < num_cg; i++, ver_ficpont_prev = vert_ficpoint) - { - /* - vert_ficpoint-1 is the last vertex; - vert_ficpoint is the being added vertex - Note: nGroupNumber are not contiguous - */ - vert_ficpoint = pBNS->vert + num_vertices + cgi->c_group[i].nGroupNumber - 1; - vert_ficpoint->iedge = ver_ficpont_prev->iedge + ver_ficpont_prev->max_adj_edges; - vert_ficpoint->max_adj_edges = cgi->c_group[i].num_CPoints + BNS_ADD_EDGES; - vert_ficpoint->num_adj_edges = 0; - vert_ficpoint->st_edge.flow = vert_ficpoint->st_edge.flow0 = 0; - vert_ficpoint->st_edge.cap = vert_ficpoint->st_edge.cap0 = 0; - vert_ficpoint->type = BNS_VERT_TYPE_C_GROUP; - } - - /************************************************/ - /* Connect c-points to the fictitious vertices */ - /* representing c-point groups; set caps, flows */ - /************************************************/ - for (c_point = 0; c_point < num_atoms; c_point++) - { - if (!at[c_point].c_point) - { - continue; - } - fictpoint = at[c_point].c_point + num_vertices - 1; /* c-group vertex index */ - vert_ficpoint = pBNS->vert + fictpoint; /* c-group vertex */ - vertex_cpoint = pBNS->vert + c_point; /* c_point vertex */ - /* Debug: check overflow */ - if (fictpoint >= pBNS->max_vertices || - num_edges >= pBNS->max_edges || - vert_ficpoint->num_adj_edges >= vert_ficpoint->max_adj_edges || - vertex_cpoint->num_adj_edges >= vertex_cpoint->max_adj_edges) - { - ret = BNS_VERT_EDGE_OVFL; - break; - } - vertex_cpoint->type |= BNS_VERT_TYPE_C_POINT; -#if ( FIX_CPOINT_BOND_CAP != 1 ) /* { */ - /* set capacity = 1 to the edges from the c_point to the centerpoint(s) */ - /* if their current capacity is zero */ - /* the centerpoint is any adjacent atom that is adjacent to a multiple bond */ - for (k = 0; k < vertex_cpoint->num_adj_edges; k++) - { - int iedge = vertex_cpoint->iedge[k]; - if (!pBNS->edge[iedge].cap) - { - /* single bond, possibly between c_point and centerpoint */ - centerpoint = ( pBNS->edge[iedge].neighbor12 ^ c_point ); - if (centerpoint < pBNS->num_atoms && - pBNS->vert[centerpoint].st_edge.cap >= 1) - { - int bond_type = ( at[c_point].bond_type[k] & BOND_TYPE_MASK ); - if (bond_type == BOND_TAUTOM || - bond_type == BOND_ALTERN || - bond_type == BOND_SINGLE) - { - pBNS->edge[iedge].cap = 1; - } - } - } - } -#endif /* } FIX_CPOINT_BOND_CAP */ - - /* Create a new edge connecting c_point to the new fictitious c-group vertex vert_ficpoint */ - edge = pBNS->edge + num_edges; - edge->cap = 1; - edge->flow = 0; - edge->pass = 0; -#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) - edge->forbidden &= pBNS->edge_forbidden_mask; -#endif - /* Mark edge to c-point having NO moveable charge with flow=1 */ - if (!CHARGED_CPOINT( at, c_point )) - { - /* Increment edge flow */ - edge->flow++; - /* Increment c-group vertex st-flow & cap */ - vert_ficpoint->st_edge.flow++; - vert_ficpoint->st_edge.cap++; - /* Increment c-point vertex st-flow & cap */ - vertex_cpoint->st_edge.flow++; - vertex_cpoint->st_edge.cap++; - } - -#if ( FIX_CPOINT_BOND_CAP == 1 ) /* { */ - - /* Set capacity = 1 to the edges from the c_point to the centerpoint(s) */ - /* if their current capacity is zero */ - /* the centerpoint is any adjacent atom that is adjacent to a multiple bond */ - for (k = 0; k < vertex_cpoint->num_adj_edges; k++) - { - int iedge = vertex_cpoint->iedge[k]; - VertexFlow nNewCap = vertex_cpoint->st_edge.cap; - centerpoint = ( pBNS->edge[iedge].neighbor12 ^ c_point ); - if (!pBNS->edge[iedge].cap) - { - /* Single bond, possibly between c_point and centerpoint */ - if (centerpoint < pBNS->num_atoms && - pBNS->vert[centerpoint].st_edge.cap >= 1) - { - nNewCap = inchi_min( pBNS->vert[centerpoint].st_edge.cap, nNewCap ); - nNewCap = inchi_min( nNewCap, MAX_BOND_EDGE_CAP ); - pBNS->edge[iedge].cap = nNewCap; - } -#if ( FIX_CPOINT_BOND_CAP2 == 1 ) /* multiple bond */ - else - if (centerpoint < pBNS->num_atoms && - edge->flow && pBNS->edge[iedge].cap < MAX_BOND_EDGE_CAP) - { - pBNS->edge[iedge].cap++; - } -#endif - } - } -#endif /* } FIX_CPOINT_BOND_CAP */ - - /* Connect edge to c_point and fictpoint and increment the counters of neighbors and edges */ - edge->neighbor1 = c_point; /* the smallest out of v1=endopoint and v2=num_vertices */ - edge->neighbor12 = c_point ^ fictpoint; /* v1 ^ v2 */ - vertex_cpoint->iedge[vertex_cpoint->num_adj_edges] = num_edges; - vert_ficpoint->iedge[vert_ficpoint->num_adj_edges] = num_edges++; - edge->neigh_ord[0] = vertex_cpoint->num_adj_edges++; - edge->neigh_ord[1] = vert_ficpoint->num_adj_edges++; - edge->cap0 = edge->cap; - edge->flow0 = edge->flow; - } - - pBNS->num_edges = num_edges; - pBNS->num_vertices += nMaxCGroupNumber; - pBNS->num_c_groups = num_cg; - } - - return ret; -} -/*#endif*/ /* } MOVE_CHARGES == 1 */ - - - - /****************************************************************************/ -void ClearAllBnDataVertices( Vertex *v, Vertex value, int size ) -{ - int i; - for (i = 0; i < size; i++) - { - v[i] = value; - } -} - - -/****************************************************************************/ -void ClearAllBnDataEdges( Edge *e, Vertex value, int size ) -{ - int i; - for (i = 0; i < size; i++) - { - e[i][0] = value; - } -} - - -/****************************************************************************/ -BN_DATA *DeAllocateBnData( BN_DATA *pBD ) -{ - if (pBD) - { - if (pBD->BasePtr) - { - inchi_free( pBD->BasePtr ); - } - if (pBD->SwitchEdge) - { - inchi_free( pBD->SwitchEdge ); - } - if (pBD->Tree) - { - inchi_free( pBD->Tree ); - } - if (pBD->ScanQ) - { - inchi_free( pBD->ScanQ ); - } - if (pBD->Pu) - { - inchi_free( pBD->Pu ); - } - if (pBD->Pv) - { - inchi_free( pBD->Pv ); - } -#if ( BNS_RAD_SEARCH == 1 ) - if (pBD->RadEndpoints) - { - inchi_free( pBD->RadEndpoints ); - } - if (pBD->RadEdges) - { - inchi_free( pBD->RadEdges ); - } -#endif - inchi_free( pBD ); - } - - return NULL; -} - - -/****************************************************************************/ -BN_DATA *AllocateAndInitBnData( int max_num_vertices ) -{ - BN_DATA *pBD = NULL; - int max_len_Pu_Pv; - max_num_vertices = 2 * max_num_vertices + 2; - max_len_Pu_Pv = max_num_vertices / 2 + 1; - max_len_Pu_Pv += max_len_Pu_Pv % 2; /* even length */ - if (!( pBD = (BN_DATA *) inchi_calloc( 1, sizeof( BN_DATA ) ) ) || - !( pBD->BasePtr = (Vertex *) inchi_calloc( max_num_vertices, sizeof( Vertex ) ) ) || - !( pBD->SwitchEdge = (Edge *) inchi_calloc( max_num_vertices, sizeof( Edge ) ) ) || - !( pBD->Tree = (S_CHAR *) inchi_calloc( max_num_vertices, sizeof( S_CHAR ) ) ) || - !( pBD->ScanQ = (Vertex *) inchi_calloc( max_num_vertices, sizeof( Vertex ) ) ) || - !( pBD->Pu = (Vertex *) inchi_calloc( max_len_Pu_Pv, sizeof( Vertex ) ) ) || -#if ( BNS_RAD_SEARCH == 1 ) - !( pBD->RadEndpoints = (Vertex *) inchi_calloc( max_len_Pu_Pv, sizeof( Vertex ) ) ) || - !( pBD->RadEdges = (EdgeIndex*) inchi_calloc( max_len_Pu_Pv, sizeof( EdgeIndex ) ) ) || -#endif - !( pBD->Pv = (Vertex *) inchi_calloc( max_len_Pu_Pv, sizeof( Vertex ) ) ) - ) - { - pBD = DeAllocateBnData( pBD ); - } - else - { - /* Initialize data */ - ClearAllBnDataEdges( pBD->SwitchEdge, NO_VERTEX, max_num_vertices ); - ClearAllBnDataVertices( pBD->BasePtr, NO_VERTEX, max_num_vertices ); - memset( pBD->Tree, TREE_NOT_IN_M, max_num_vertices ); /* djb-rwth: memset_s C11/Annex K variant? */ - pBD->QSize = -1; - pBD->max_len_Pu_Pv = max_len_Pu_Pv; - pBD->max_num_vertices = max_num_vertices; -#if ( BNS_RAD_SEARCH == 1 ) - pBD->nNumRadEndpoints = 0; -#endif - } - - return pBD; -} - - -/****************************************************************************/ -int ReInitBnData( BN_DATA *pBD ) -{ - int i, ret = 0; - Vertex u, v; - if (pBD) - { - if (!pBD->ScanQ) - { - ret += 2; - } - if (!pBD->BasePtr) - { - ret += 4; - } - if (!pBD->SwitchEdge) - { - ret += 8; - } - if (!pBD->Tree) - { - ret += 16; - } - if (!ret) - { - for (i = 0; i <= pBD->QSize; i++) - { - u = pBD->ScanQ[i]; - v = prim( u ); - pBD->BasePtr[u] = - pBD->BasePtr[v] = - pBD->SwitchEdge_Vert1( u ) = - pBD->SwitchEdge_Vert1( v ) = NO_VERTEX; - pBD->Tree[u] = - pBD->Tree[v] = TREE_NOT_IN_M; - } - } - pBD->QSize = -1; - if (!pBD->Pu) - { - ret += 32; - } - if (!pBD->Pv) - { - ret += 64; - } - } - else - { - ret += 1; - } - - return ret; -} - - -/****************************************************************************/ -int GetVertexDegree( BN_STRUCT* pBNS, Vertex v ) -{ - int i = v / 2 - 1; - if (i >= 0) - { - if (pBNS->vert[i].st_edge.cap > 0) - { - return pBNS->vert[i].num_adj_edges + 1; /* add 1 neighbor for s or t */ - } - else - { - return 0; /* since the edge s-v has zero capacity, we ignore vertex v */ - } - } - else - { - return pBNS->num_vertices; - } -} - - -/****************************************************************************/ -Vertex Get2ndEdgeVertex( BN_STRUCT* pBNS, Edge uv ) -{ - /* - Vertex ret; - */ - if (uv[1] >= 0) - { - /* -- debug -- - if ( uv[1] > pBNS->num_edges || uv[0] > 2*pBNS->num_vertices+3 ) { - int stop = 1; - } - ret = ((uv[0]-2) ^ (2*pBNS->edge[uv[1]].neighbor12+1)) + 2; - if ( ret > 2*pBNS->num_vertices+3 ) { - int stop = 1; - } - return ret; - -- end debug -- */ - - return ( ( uv[0] - 2 ) ^ ( 2 * pBNS->edge[uv[1]].neighbor12 + 1 ) ) + 2; - - /*short u = uv[0]-FIRST_INDX; */ - /*short t = 2*(((u / 2 - 1) ^ pBNS->edge[uv[1]].neighbor12) + 1) + ((u+1) & 1) + FIRST_INDX; */ - /*return t; */ - } - - if (uv[0] <= 1) - { - return -( 1 + uv[1] ); /* vertex1 is s or t, return x or y */ - } - else - { - return uv[0] % 2; /* vertex1 is x or y, return s or t; never happens? -- NSC 3737, 7634,... */ - } - -} - - -/****************************************************************************/ -Vertex GetVertexNeighbor( BN_STRUCT* pBNS, - Vertex v, - int neigh, - EdgeIndex *iedge ) -{ - /* neigh = 0 => the neighbor is s or t except case when v is s or t. */ - /* v= FIRST_INDX or FIRST_INDX+1: v is s or t respectively */ - int i, neighbor; - if (( i = v - 2 ) >= 0) - { - /* Neighbor of x or y */ - if (neigh) - { - neigh--; - /* x or y */ - *iedge = pBNS->vert[i / 2].iedge[neigh]; - if (!( pBNS->edge[*iedge].cap & EDGE_FLOW_MASK ) || IS_FORBIDDEN( pBNS->edge[*iedge].forbidden, pBNS )) - { - return NO_VERTEX; - } - neighbor = ( i ^ ( 2 * pBNS->edge[*iedge].neighbor12 + 1 ) ) + 2; /* parity opposite to v parity */ - } - else - { - /* neighbor of x or y is s or t */ - neighbor = ( v & 1 ); /* s or t, same parity as v */ - *iedge = -( neighbor + 1 ); - } - } - else - { - /* neighbor of s or t: x or y, same parity as v */ - if (!( pBNS->vert[neigh].st_edge.cap & EDGE_FLOW_ST_MASK )) - { - return NO_VERTEX; - } - neighbor = 2 * neigh + 2 + ( v & 1 ); /* parity same as the parity of v */ - *iedge = -( neighbor + 1 ); - } - - return neighbor; -} - - -/****************************************************************************/ -int GetEdgePointer( BN_STRUCT* pBNS, - Vertex u, - Vertex v, - EdgeIndex iuv, - BNS_EDGE **uv, - S_CHAR *s_or_t ) -{ - int i = u / 2 - 1; - int j = v / 2 - 1; - int bBackward = BNS_WRONG_PARMS; - *uv = NULL; - if (i >= 0) - { - /* u is an atom */ - if (j >= 0) - { - /* v is an atom */ - if (( u + v ) % 2) - { - *uv = pBNS->edge + iuv; - bBackward = ( u & 1 ); - *s_or_t = 0; - } - } - else - { - /* v is s or t */ - if (v >= 0 && !( ( u + v ) % 2 )) - { - *uv = (BNS_EDGE*) &pBNS->vert[i].st_edge; - bBackward = !( v & 1 ); - *s_or_t = v + 3; /* 3=> v=s, 4=> v=t */ - } - } - } - else - { - if (j >= 0) - { - /* u is s or t */ - if (u >= 0 && !( ( u + v ) % 2 )) - { - /* v is an atom */ - *uv = (BNS_EDGE*) &pBNS->vert[j].st_edge; - bBackward = ( u & 1 ); - *s_or_t = u + 1; /* 1=> u=s, 2=> u=t */ - } - } - } - - return bBackward; -} - - -/****************************************************************************/ -int AugmentEdge( BN_STRUCT* pBNS, - Vertex u, - Vertex v, - EdgeIndex iuv, - int delta, - S_CHAR bReverse, - int bChangeFlow ) -{ - int f, flow, ret = 0; - - BNS_ST_EDGE *pst_edge; - BNS_EDGE *pedge; - S_CHAR s_or_t; - int bBackward = GetEdgePointer( pBNS, u, v, iuv, &pedge, &s_or_t ); - if (!IS_BNS_ERROR( bBackward )) - { - if (bBackward) - { - delta = -delta; - } - - if (s_or_t) - { - pst_edge = (BNS_ST_EDGE *) pedge; - flow = pst_edge->flow; - f = ( flow & EDGE_FLOW_ST_MASK ) + delta; /* new flow */ - if (!delta) - { - /*((BNS_ST_EDGE *)pedge)->flow = pst_edge->flow & ~EDGE_FLOW_ST_PATH;*/ - pst_edge->flow = pst_edge->flow & ~EDGE_FLOW_ST_PATH; - } - else - { - int cap = pst_edge->cap; - if (f < 0 || f > cap) - { - ret = BNS_WRONG_PARMS; - } - else - { - if (!( bChangeFlow & BNS_EF_CHNG_FLOW )) - { - f -= delta; /* do not actually change the flow, only find the augmenting path */ - } - else - { - if (delta) - { - /*((BNS_ST_EDGE *)pedge)->pass ++;*/ - pst_edge->pass++; - } - } - flow = ( flow & ~( EDGE_FLOW_ST_PATH | EDGE_FLOW_ST_MASK ) ) + f; - /*((BNS_ST_EDGE *)pedge)->flow = flow;*/ - pst_edge->flow = flow; - /*((BNS_ST_EDGE *)pedge)->delta += delta; */ - if (bReverse) - { - /* u <- v; Note: in case of bReverse s_or_t has actually been determined - for the u' <- v' pair; therefore s and t should be switched - in order to correctly determine the 1st or the last atom - on the augmenting path. - */ - switch (s_or_t) - { - case 1: /* u = t: t<-v, v is the last vertex */ - ALTP_END_ATOM( pBNS->alt_path ) = v / 2 - 1; - break; - case 2: /* u = s: s<-v, error */ - ret = BNS_WRONG_PARMS; - break; - case 3: /* v = t: u<-t, error */ - ret = BNS_WRONG_PARMS; - break; - case 4: /* v = s: u<-s, u is the first vertex */ - ALTP_START_ATOM( pBNS->alt_path ) = u / 2 - 1; - ALTP_DELTA( pBNS->alt_path ) = delta; - break; - default: - ret = BNS_WRONG_PARMS; - break; - } - } - else - { - /* u -> v */ - switch (s_or_t) - { - case 1: /* u = s: s->v, v is the first vertex */ - ALTP_START_ATOM( pBNS->alt_path ) = v / 2 - 1; - ALTP_DELTA( pBNS->alt_path ) = delta; - break; - case 2: /* u = t: t->v, error */ - ret = BNS_WRONG_PARMS; - break; - case 3: /* v = s: u->s, error */ - ret = BNS_WRONG_PARMS; - break; - case 4: /* v = t: u->t, u is the last vertex */ - ALTP_END_ATOM( pBNS->alt_path ) = u / 2 - 1; - break; - default: - ret = BNS_WRONG_PARMS; - break; - } - } - } - } - } - else - { - f = ( pedge->flow & EDGE_FLOW_MASK ) + delta; - if (!delta) - { - pedge->flow &= ~EDGE_FLOW_PATH; - } - else - { - if (f < 0 || f > pedge->cap) - { - ret = BNS_WRONG_PARMS; - } - else - { - AT_NUMB iu = u / 2 - 1; - AT_NUMB iv = v / 2 - 1; - int indx; - if (!( bChangeFlow & BNS_EF_CHNG_FLOW )) - { - f -= delta; /* do not actually change the flow, only find the augmenting path */ - } - else - { - if (delta) - { - pedge->pass++; - } - } - pedge->flow = ( pedge->flow & ~( EDGE_FLOW_PATH | EDGE_FLOW_MASK ) ) | f; - if (ALTP_MAY_ADD( pBNS->alt_path )) - { - /* bReverse? u <- v : u -> v */ - indx = bReverse ? ( pedge->neighbor1 == iv ) : ( pedge->neighbor1 == iu ); - ALTP_CUR_THIS_ATOM_NEIGHBOR( pBNS->alt_path ) = pedge->neigh_ord[1 - indx]; - ALTP_CUR_NEXT_ATOM_NEIGHBOR( pBNS->alt_path ) = pedge->neigh_ord[indx]; - ALTP_NEXT( pBNS->alt_path ); - } - else - { - ALTP_OVERFLOW( pBNS->alt_path ) = 1; - ret = BNS_ALTPATH_OVFL; - } - } - } - } - return ret ? ret : f; - } - - return bBackward; -} - - -/**************************************************************************** -rescap_mark( ... ) - -Find residual capacity and mark the edge -as belonging to the augmenting path -****************************************************************************/ -int rescap_mark( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv ) -{ - BNS_ST_EDGE *pst_edge; - BNS_EDGE *pedge; - - int f, flow; - S_CHAR s_or_t; - int bBackward = GetEdgePointer( pBNS, u, v, iuv, &pedge, &s_or_t ); - - if (!IS_BNS_ERROR( bBackward )) - { - if (s_or_t) - { - pst_edge = (BNS_ST_EDGE *) pedge; - flow = pst_edge->flow; - f = ( flow & EDGE_FLOW_ST_MASK ); - if (!bBackward) - { - f = (int) pst_edge->cap - f; - } - if (flow & EDGE_FLOW_ST_PATH) - { - pBNS->bNotASimplePath++; - f /= 2; /* this is the second time we pass the same edge: reduce flow by a factor of 2 */ - } - else - { - pst_edge->flow |= EDGE_FLOW_ST_PATH; /* mark the edge */ - } - } - else - { - flow = pedge->flow; - f = flow & EDGE_FLOW_MASK; - if (!bBackward) - { - f = (int) pedge->cap - f; - } - if (flow & EDGE_FLOW_PATH) - { - f /= 2; /* this is the second time we pass the same edge: reduce flow by a factor of 2 */ - pBNS->bNotASimplePath++; - } - else - { - pedge->flow |= EDGE_FLOW_PATH; /* mark the edge */ - } - } - return f; - } - - return bBackward; -} - - -/**************************************************************************** -GetPrevVertex( ... ) - -Get previous vertex in the searched path -z is SwitchEdge_Vert2(y) != y. Go backward from z to y -****************************************************************************/ -Vertex GetPrevVertex( BN_STRUCT* pBNS, Vertex y, Edge *SwitchEdge, EdgeIndex *iuv ) -{ - Vertex w, z, x2, y2; /* djb-rwth: removing redundant variables */ - EdgeIndex iwy; - - w = SwitchEdge_Vert1( y ); - z = SwitchEdge_Vert2( y ); - iwy = SwitchEdge_IEdge( y ); - if (z == y) - { - *iuv = iwy; - return w; - } - x2 = prim( y ); - y2 = prim( z ); - /* djb-rwth: removing redundant code */ - while (y2 != NO_VERTEX) - { - w = SwitchEdge_Vert1( y2 ); - z = SwitchEdge_Vert2( y2 ); - iwy = SwitchEdge_IEdge( y2 ); - if (w == x2) - { - *iuv = iwy; - /*return z; */ - return ( y + z ) % 2 ? z : prim( z ); - } - /* djb-rwth: removing redundant code */ - /* - #ifdef _DEBUG - if ( n ) { - int stop = 1; - } - #endif - */ - if (w == y2) - { - return NO_VERTEX; - } - y2 = w; - } - - return y2; -} - - - -#define CHECK_TACN 1 - - -/**************************************************************************** -The purpose is to avoid paths - -(H-group)[u]---atom[v]---((-)-cgroup)[w], - -where atom[v] is not acidic and (-) and H are not interchangeable without -explicit bond tautomerism. - -It is important that acidic atoms are only O,S,Se,Te and should have -only one chemical bond. Only because of this an early rejection of -the vertex v (before it gets on SCANQ) is possible. - -CHECK_TACN == 1 prohibits replacing (-) on N with H unless H can be moved to N -along an alternating path from another heteroatom (t-group will be detected). -****************************************************************************/ - - -#if ( FIX_TACN_POSSIBLE_BUG == 1 ) /* { */ - - -/****************************************************************************/ -int bIgnoreVertexNonTACN_atom( BN_STRUCT* pBNS, Vertex u, Vertex v ) -{ -#define TYPE_T 1 /* t-group [also called H-group] */ -#define TYPE_CN 2 /* (-)c-group */ - int i, degree, ret, u_is_taut = 0, w_is_taut, num_allowed = 0, num_found_groups = 0; - Vertex w; - EdgeIndex ivw; - if (!pBNS->type_TACN || u <= 1 || v <= 1 || - ( pBNS->vert[v / 2 - 1].type & pBNS->type_TACN )) - { - return 0; /* add/remove H(+) is allowed for acidic atoms */ - } - if (!pBNS->type_T || !pBNS->type_CN) - { - return 0; /* should not happen */ - } - u_is_taut = ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) ? TYPE_T : - ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ? TYPE_CN : 0; - if (u_is_taut) - { - /* u is either t-group vertex or (-) c-group */ - degree = GetVertexDegree( pBNS, v ); - for (i = 0; i < degree; i++) - { - /* v = vert[u].neighbor[i]; */ - w = GetVertexNeighbor( pBNS, v, i, &ivw ); - if (w == NO_VERTEX || w <= 1) - { - continue; /* the atom has only single bonds or it is s or t, ignore it */ - } - if (w != u && ( ret = rescap( pBNS, v, w, ivw ) ) > 0) - { - num_allowed++; - w_is_taut = ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ? TYPE_CN : - ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) ? TYPE_T : 0; - if (( u_is_taut | w_is_taut ) == ( TYPE_T | TYPE_CN )) - { - num_found_groups++; - } - } - } - if (num_found_groups && num_allowed == 1) - { - return 1; /* reject */ - } - } - - return 0; -#undef TYPE_T -#undef TYPE_CN -} - - -#else /* } FIX_TACN_POSSIBLE_BUG { */ - - -/****************************************************************************/ -int bIgnoreVertexNonTACN_atom( BN_STRUCT* pBNS, Vertex u, Vertex v ) -{ - int i, degree, ret, u_is_taut = 0, num_allowed = 0, num_found_groups = 0; - Vertex w; - EdgeIndex ivw; - if (!pBNS->type_TACN || u <= 1 || v <= 1 || - ( pBNS->vert[v / 2 - 1].type & pBNS->type_TACN )) - { - return 0; /* add/remove H(+) is allowed for acidic atoms */ - } - if (!pBNS->type_T || !pBNS->type_CN) - { - return 0; /* should not happen */ - } - if (( u_is_taut = ( pBNS->vert[u / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) || - ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN )) - { - /* u is either t-group vertex or (-) c-group */ - degree = GetVertexDegree( pBNS, v ); - for (i = 0; i < degree; i++) - { - /* v = vert[u].neighbor[i]; */ - w = GetVertexNeighbor( pBNS, v, i, &ivw ); - if (w == NO_VERTEX || w <= 1) - { - continue; /* the atom has only single bonds or it is s or t, ignore it */ - } - if (w != u && ( ret = rescap( pBNS, v, w, ivw ) ) > 0) /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - { - num_allowed++; - if (( u_is_taut ? ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) : - ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) )) - { - num_found_groups++; - } - } - } - if (num_found_groups && num_allowed == 1) - { - return 1; /* reject */ - } - } - - return 0; -} - - - -#endif /* } FIX_TACN_POSSIBLE_BUG */ - - - -/**************************************************************************** -The purpose is to avoid paths -(H-group)[u]---atom[v]---((-)-cgroup)[w], - -where atom[v] is not acidic and (-) and H are not interchangeable without -explicit bond tautomerism. - -It is important that acidic atoms are only O,S,Se,Te and should have -only one chemical bond. Only because of this an early rejection of -the vertex v (before it gets on SCANQ) is possible. -****************************************************************************/ - - -#if ( FIX_TACN_POSSIBLE_BUG == 1 ) /* { */ - - -/****************************************************************************/ -int bIgnoreVertexNonTACN_group( BN_STRUCT* pBNS, - Vertex v, - Vertex w, - Edge *SwitchEdge ) -{ -#define TYPE_T 1 /* t-group [also called H-group] */ -#define TYPE_CN 2 /* (-)c-group */ - int u_is_taut = 0, w_is_taut = 0; - Vertex u; - EdgeIndex iuv; - if (v <= 1 || w <= 1) - return 0; -#if ( CHECK_TACN == 1 ) - if (!pBNS->type_TACN || - ( pBNS->vert[v / 2 - 1].type & pBNS->type_TACN )) - { - return 0; - } - if (!pBNS->type_T || !pBNS->type_CN) - { - return 0; /* should not happen */ - } -#endif - u = GetPrevVertex( pBNS, v, SwitchEdge, &iuv ); - /* - u = SwitchEdge_Vert1(v); - iuv = SwitchEdge_IEdge(v); - */ - if (u == NO_VERTEX || iuv < 0) - return 0; /* should not happen */ - /* check edge adjacency */ - if (pBNS->edge[iuv].neighbor1 != ( u / 2 - 1 ) && pBNS->edge[iuv].neighbor1 != v / 2 - 1 || - ( pBNS->edge[iuv].neighbor12 ^ ( u / 2 - 1 ) ) != ( v / 2 - 1 )) - { - return 0; /* !!! should not happen !!! */ - } - -#if ( CHECK_TACN == 1 ) - u_is_taut = ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) ? TYPE_T : - ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ? TYPE_CN : 0; - w_is_taut = ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) ? TYPE_T : - ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ? TYPE_CN : 0; - if (( u_is_taut | w_is_taut ) == ( TYPE_T | TYPE_CN )) - { - /* rescap must have already been checked */ - return 1; - } -#endif - - return 0; -#undef TYPE_T -#undef TYPE_CN -} - - -#else /* } FIX_TACN_POSSIBLE_BUG { */ - - -/****************************************************************************/ -int bIgnoreVertexNonTACN_group( BN_STRUCT* pBNS, - Vertex v, - Vertex w, - Edge *SwitchEdge ) -{ - int u_is_taut = 0, w_is_taut = 0; - Vertex u; - EdgeIndex iuv; - if (v <= 1 || w <= 1) - return 0; -#if ( CHECK_TACN == 1 ) - if (!pBNS->type_TACN || - ( pBNS->vert[v / 2 - 1].type & pBNS->type_TACN )) - { - return 0; - } - if (!pBNS->type_T || !pBNS->type_CN) - { - return 0; /* should not happen */ - } -#endif - u = GetPrevVertex( pBNS, v, SwitchEdge, &iuv ); - /* - u = SwitchEdge_Vert1(v); - iuv = SwitchEdge_IEdge(v); - */ - if (u == NO_VERTEX || iuv < 0) - { - return 0; /* should not happen */ - } - /* check edge adjacency */ - if ((pBNS->edge[iuv].neighbor1 != ( u / 2 - 1 ) && pBNS->edge[iuv].neighbor1 != v / 2 - 1) || - (( pBNS->edge[iuv].neighbor12 ^ ( u / 2 - 1 ) ) != ( v / 2 - 1 ))) /* djb-rwth: addressing LLVM warning */ - { - return 0; /* !!! should not happen !!! */ - } - -#if ( CHECK_TACN == 1 ) - if (( ( u_is_taut = ( pBNS->vert[u / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) || - ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ) && - ( ( w_is_taut = ( pBNS->vert[w / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) || - ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ) && - u_is_taut + w_is_taut == 1) - { - /* rescap must have already been checked */ - return 1; - } -#endif - - return 0; -} -#endif /* } FIX_TACN_POSSIBLE_BUG { */ - - - -#if ( FIX_KEEP_H_ON_NH_ANION == 1 ) - - -/**************************************************************************** -bIsRemovedHfromNHaion( ... ) - -Detect an attempt to remove H from -NH(-) to make =N(-); -all taut atoma except N are 'acidic' -****************************************************************************/ -int bIsRemovedHfromNHaion( BN_STRUCT* pBNS, Vertex u, Vertex v ) -{ - int i, u2, v2, vat2; - Vertex vtg, vat; - BNS_VERTEX *pvAT, *pvCN; - BNS_EDGE *pEdge; - if (!pBNS->type_TACN || u <= 1 || v <= 1 || - u % 2 || !( v % 2 ) /* the edge flow may only increase */) - { - return 0; - } - if (( pBNS->vert[u2 = u / 2 - 1].type & pBNS->type_TACN ) || - ( pBNS->vert[v2 = v / 2 - 1].type & pBNS->type_TACN )) - { - return 0; /* add/remove H is allowed for acidic atoms */ - } - if (!pBNS->type_T || !pBNS->type_CN) - { - return 0; /* should not happen */ - } - /* find which of u, v vertices is N and which is t-group */ - if (( ( pBNS->vert[u2].type & pBNS->type_T ) == pBNS->type_T ) && v2 < pBNS->num_atoms) - { - vtg = u; - vat = v; - } - else - { - if (( ( pBNS->vert[v2].type & pBNS->type_T ) == pBNS->type_T ) && u2 < pBNS->num_atoms) - { - vtg = v; - vat = u; - } - else - { - return 0; - } - } - - vat2 = vat / 2 - 1; - pvAT = pBNS->vert + vat2; /* atom */ - for (i = pvAT->num_adj_edges - 1; 0 <= i; i--) - { - pEdge = pBNS->edge + pvAT->iedge[i]; - pvCN = pBNS->vert + ( pEdge->neighbor12 ^ vat2 ); - if (( ( pvCN->type & pBNS->type_CN ) == pBNS->type_CN ) && pEdge->flow > 0) - { - return 1; /* detected */ - } - } - - return 0; -} -#endif - - -#if ( FIX_AVOID_ADP == 1 ) - -/**************************************************************************** -bIsAggressiveDeprotonation( ... ) - -Detect (tg)-N=A-A=A-A=N-(tg) -u v w -k = 5 4 3 2 1 0 1 2 -^ -odd number means ADP -****************************************************************************/ -int bIsAggressiveDeprotonation( BN_STRUCT* pBNS, - Vertex v, - Vertex w, - Edge *SwitchEdge ) -{ -#define TYPE_T 1 /* t-group [also called H-group] */ -#define TYPE_CN 2 /* (-)c-group */ -#define TYPE_AT 4 - int k, v2, u2, w2, u2_next, type0, type1, type2, type; - Vertex u, u_next; - EdgeIndex iuv; - - if (v <= 1 || w <= 1) - { - return 0; - } - - if (!pBNS->type_TACN || !pBNS->type_T || !pBNS->type_CN) - { - return 0; /* should not happen */ - } - - v2 = v / 2 - 1; - w2 = w / 2 - 1; - if (v2 >= pBNS->num_atoms || w2 < pBNS->num_atoms) - { - goto cross_edge; - } - - if (!( ( pBNS->vert[w2].type & pBNS->type_T ) == pBNS->type_T ) && - !( ( pBNS->vert[w2].type & pBNS->type_CN ) == pBNS->type_CN )) - { - goto cross_edge; - } - - /* v ia an atom, w is a t-group, v != w' */ - for (k = 0, u = v; 1 < ( u_next = u, u = GetPrevVertex( pBNS, u, SwitchEdge, &iuv ) ); k++) - { - u2 = u / 2 - 1; - if (u2 >= pBNS->num_atoms) - { - /* Moving backward along the alt path we have found a vertex - that is not an atom. Possibly it is a t- or (-)c-group */ - if (!( k % 2 )) - { - return 0; /* even vertex -- always okay */ - } - if (!( ( pBNS->vert[u2].type & pBNS->type_T ) == pBNS->type_T ) && - !( ( pBNS->vert[u2].type & pBNS->type_CN ) == pBNS->type_CN )) - { - /* not a t- or (-)c-group */ - return 0; - } - u2_next = u_next / 2 - 1; - if (!( pBNS->vert[v2].type & pBNS->type_TACN ) && - !( pBNS->vert[u2_next].type & pBNS->type_TACN )) - { - /* none of the atoms at the ends are N */ - return 0; - } - return 1; - } - } - - return 0; - -cross_edge: - - /***************************************************************************** - * v and w (v=w') are same vertex reached with opposite "phases". - * w cannot be (t) because this would have been detected earlier -- ??? - * (t)-A=A-A=A-A=A-(t) - * v - * 3 2 1 0 1 2 3 4 - * kv kw - * (kv + kw)%2 == 1 <==> aggressive deprotonation - *****************************************************************************/ - - if (v == prim( w )) - { - type0 = 0; - if (v2 >= pBNS->num_atoms) - { - type0 = ( ( pBNS->vert[v2].type & pBNS->type_T ) == pBNS->type_T ) ? TYPE_T : - ( ( pBNS->vert[v2].type & pBNS->type_CN ) == pBNS->type_CN ) ? TYPE_CN : 0; - } - } - - return 0; -} -#endif - - -/****************************************************************************/ -int rescap( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv ) -{ - BNS_ST_EDGE *pst_edge; - BNS_EDGE *pedge; - - int f; - S_CHAR s_or_t; - int bBackward = GetEdgePointer( pBNS, u, v, iuv, &pedge, &s_or_t ); - - if (!IS_BNS_ERROR( bBackward )) - { - - if (s_or_t) - { - pst_edge = (BNS_ST_EDGE *) pedge; - f = ( pst_edge->flow & EDGE_FLOW_ST_MASK ); - if (!bBackward) - { - f = (int) pst_edge->cap - f; - } - } - else - { - f = ( pedge->flow & EDGE_FLOW_MASK ); - if (!bBackward) - { - f = (int) pedge->cap - f; - } - } - return f; - } - - return bBackward; /* error */ -} - - -/**************************************************************************** -W.Kocay, D.Stone, -"An Algorithm for Balanced Flows", -The Journal of Combinatorial Mathematics and Combinatorial Computing, -vol. 19 (1995) pp. 3-31 - -W.Kocay, D.Stone, -"Balanced network flows", -Bulletin of the Institute of Combinatorics and its Applications, -vol. 7 (1993), pp. 17--32 - -N = a balanced network (bipartite directed graph) of: -n=2*V+2 vertices (incl. s (source) and t (target); -each other vertex i is included 2 times: -set X (x[i]) of V vertices (v) and a set Y (y[j]) of -V complementary vertices (v') so that x[i]' = y[i], x[i]''=x[i], and -m=2*E+2*V edges (each original undirected edge i-j is represented as -2 directed edges: x[i]->y[j] and x[j]->y[i]; plus -V edges s->x[i] and V edges y[j]->t) -v' = a complement vertex to v -v'u' = (uv)' = a complement edge to uv -rescap(uv) = cap(uv)-f(uv) if uv is a forward edge -= f(uv) if uv is a backward edge -(i) 0 <= f(uv) <= cap(uv) -(ii) f+(u) = f-(u) for all u in X, Y where f+(u) is a total flow out of u, -and f-(u) is a total flow into u -(iii) f(uv) = f((uv)') (balanced flow condition) - -S = a set of all s-searchable vertices -S- = all other vertices -if t in S, then N contains a valid augmenting path P, so that flow can be -augmented on both P and P' -if t not in S, then let K=[S,S-], the set of all edges directed from S to S-. -K is an edge-cut that has a special structure. -Let -A = {x[i], y[i] |x[i] not in S, y[i] in S} -B = {x[i], y[i] |x[i] in S, y[i] not in S} -C = {x[i], y[i] |x[i] in S, y[i] in S} -D = {x[i], y[i] |x[i] not in S, y[i] not in S} -N[C] = subgraph of N induced by C; -it consists of of a number of connected components C[i] -K[i] = those edges of K with one endpoint in C[i]. - -If t is in S- then - -i) Each C[i] = C[i]' -ii) There are no edges between C and D -iii) Each K[i] has odd capacity, it is called a balanced edge-cut. - -balcap(K) = cap(K) - odd(K), where odd(K) is the number of connected components in N[C]. -Name "odd(K)" is because each cap(K[i]) is odd. - -Max-Balanced-Flow-Min-Balanced-Cut Theorem: - -Let f be a balanced flow in N, and let K be any balanced edge-cut. -The value of a maximum balanced flow equals the capacity of a minimum -edge-cut, that is, val(f) = balcap(K) when f is maximum and K is minimum. - -****************************************************************************/ - - -/*******************************************************/ -/* */ -/* VERTEX NUMBERING */ -/* */ -/* Total number of atoms = n */ -/* Total number of vertices = 2*n+2 */ -/*******************************************************/ -/* */ -/* atom numbering starts from 0: */ -/* */ -/* atoms s t x0 y0 x1 y1 ... xi yi ...xn yn */ -/* vertices 0 1 2 3 4 5 ... 2i-2 2i-1 ...2n-2 2n-1 */ -/* */ -/* atom = vertex/2-1; if negative then s or t */ -/* */ -/* vertex = (atom + 1) * 2 + i; i=0 for x, i=1 for y */ -/* */ -/*******************************************************/ - -/*********************************************************************************/ -/* v' variable is called prim(v) for now */ -/*********************************************************************************/ - -/* -BalancedNetworkSearch( ... ) - -N has source s, target t, the mirror network M is constructed. -The tree T contains a valid sv-path for each v in T. Simultaneously, the complementary -tree T' is built as indicated in comments. The trees T and T' must have no edges or -vertices in common. Initially T will be built as in breadth-first-search, and T' will -be the complementary tree, it will contain the complementary valid v't-path. - -NB: this procedure is _not_ recursive - -*/ - - -/****************************************************************************/ -int BalancedNetworkSearch( BN_STRUCT* pBNS, BN_DATA *pBD, int bChangeFlow ) - -{ - Vertex *BasePtr = pBD->BasePtr; - Edge *SwitchEdge = pBD->SwitchEdge; - S_CHAR *Tree = pBD->Tree; - Vertex *ScanQ = pBD->ScanQ; - int QSize = pBD->QSize; - Vertex *Pu = pBD->Pu; - Vertex *Pv = pBD->Pv; - int max_len_Pu_Pv = pBD->max_len_Pu_Pv; - - /* added to translate into C */ - int i, k, degree, delta, ret = 0; - Vertex u, b_u, v, b_v, w; - EdgeIndex iuv; -#if ( BNS_RAD_SEARCH == 1 ) - int n, bRadSearch = ( BNS_EF_RAD_SRCH & bChangeFlow ) && pBD->RadEndpoints; - BRS_MODE bRadSrchMode = RAD_SRCH_NORM; - int bRadSearchPrelim = 0; - if (bRadSearch) - { - pBD->nNumRadEndpoints = 0; - bRadSrchMode = pBD->bRadSrchMode; - bRadSearchPrelim = pBNS->type_TACN && bRadSrchMode == RAD_SRCH_NORM; - } -#endif - - /* -- Always -- - Vertex_s = FIRST_INDX; - Vertex_t = Vertex_s+1; - */ - QSize = k = 0; /* put s on ScanQ = set S */ - ScanQ[QSize] = Vertex_s; - BasePtr[Vertex_t] = Vertex_s; - BasePtr[Vertex_s] = BLOSSOM_BASE; /* create initial blossom C(Vertex_s) with base s */ - Tree[Vertex_s] = TREE_IN_1; - - do - { - u = ScanQ[k]; /* select u from the head of ScanQ */ - /* since u is on the queue, it has a blossom C(U) with base b_u */ - b_u = FindBase( u, BasePtr ); - degree = GetVertexDegree( pBNS, u ); -#if ( BNS_RAD_SEARCH == 1 ) - n = 0; -#endif - for (i = 0; i < degree; i++) - { - /* v = vert[u].neighbor[i]; */ - v = GetVertexNeighbor( pBNS, u, i, &iuv ); - if (v == NO_VERTEX) - { - continue; /* the atom has only single bonds, ignore it */ - } -#if ( BNS_RAD_SEARCH == 1 ) - if (!k && bRadSrchMode == RAD_SRCH_FROM_FICT && v / 2 <= pBNS->num_atoms) - { - continue; /* start from fict. vertices only */ - } - if (bRadSearchPrelim && v / 2 > pBNS->num_atoms) - { - continue; /* during initial add/remove H allow radical movement only through real atoms */ - } -#endif - if ( /* PrevPt[u] != v ** avoid edges of T */ - ( SwitchEdge_Vert1( u ) != v || SwitchEdge_Vert2( u ) != u ) /* avoid edges of T */ - && ( ret = rescap( pBNS, u, v, iuv ) ) > 0) - { - /* Special treatment to prevent H<->(-) replacement on non-acidic atoms */ - /*----------------------------------------------------------------------*/ - if (pBNS->type_TACN) - { - if (bIgnoreVertexNonTACN_atom( pBNS, u, v )) - { - continue; - } - if (bIgnoreVertexNonTACN_group( pBNS, u, v, SwitchEdge )) - { - continue; - } -#if ( FIX_KEEP_H_ON_NH_ANION == 1 ) - if (bIsRemovedHfromNHaion( pBNS, u, v )) - { - continue; - } -#endif -#if ( FIX_AVOID_ADP == 1 ) - if (bIsAggressiveDeprotonation( pBNS, u, v, SwitchEdge )) - { - continue; - } -#endif - } - /*----------------------------------------------------------------------*/ - b_v = FindBase( v, BasePtr ); /* Notation: b_x is a base of x */ - - if (b_v == NO_VERTEX) - { - /* Originally 0 instead of NO_VERTEX */ - - /* Important note: following "A. Note of Implementing the Algorithm" from the - article by Kocay and Stone, all references to PrevPt[a] have been - replaced with SwitchEdge[a][0]=SwitchEdge_Vert1(a); to be on a safe side - the check whether (SwitchEdge_Vert2(a)==a) has been added. - */ - - /* v is not yet in T or T' -- add it to T and M */ - /*PrevPt[v] = u; ** this effectively adds v to T and v' to T' */ - - QSize++; - ScanQ[QSize] = v; - TREE_MARK( v, TREE_IN_1 ); /* mark v s-reachable (in T) */ - TREE_MARK( prim( v ), TREE_IN_2 ); /* mark v' in T' */ - - /* Switch Edges: If u in T then Pu (a valid su-path) can be constructed - by successfully executing u=PrevPt[u] until u=s. - For vertices in T' the situation is different. - Suppose uv and v'u' are added to a mirror network M creating a blossom: - - s T (Note: in the code v' is prim(v), - T / \ u' is prim(u), etc.) - / ... - w=x1 - / \ u in T, v in T' - u=y2 v'=y3 - \ / <--- two added edges uv and (uv)'=v'u' - -------- X ------------intersection of the edges ------------------------ - / \ <--- (the edges intersection in the picture is shown as X) - u'=x2 v=x3 u' it T', v' in T - \ / - T' w'=y1 - \ ... - \ / - t T' - - Vertices v and u' now become s-reachable; - The valid paths to v and u' must use the edges uv and v'u' respectively. - - For each vertex z in S we define a switch-edge that allows a valid sz-path - to be constructed, SwitchEdge[v]=uv and SwitchEdge[u']=v'u'. (We don't - know the direction of the edge uv, it may be (u,v) or (v,u). In either case, - the complementary edge is indicated by v'u'). - - Vertex w' also becomes s-reachable when uv is added to M, and a valid sw'-path - must use one of uv and v'u'. Therefore we choose one of them, say uv (see below - the rule of choosing the switch-edge), and define SwitchEdge[w'] = uv. - - When the addition of an edge uv to M causes a vertex z to become s-reachable - (where z was previously non-reachable), z is placed on the ScanQ, that is, into S. - The edge uv is said to be a switch-edge for z. - - Rule: We choose the the order of the vertices uv to be such that the valid sz-path - consists of a valid su-path, followed by edge uv, followed by a valid vz-path. - - For vertices z in T we can take SwitchEdge[z]=yz where y=PrevPt[z] since - it is the edge yz that allows z to be s-reachable. - For vertices z not in S we take SwitchEdge[z]=NONE. - - */ - - /* v is not yet in T or T' -- add it to T and M */ - SwitchEdge_Vert1( v ) = u; /* this effectively adds uv and v'u' to M */ - SwitchEdge_IEdge( v ) = iuv; - - BasePtr[prim( v )] = v; - BasePtr[v] = BLOSSOM_BASE; /* create a trivial blossom C(v) with base v */ -#if ( BNS_RAD_SEARCH == 1 ) - n++; -#endif - } - - else if (TREE_IS_S_REACHABLE( prim( v ) ) /*Is_s_Reachable(prim(v)*/ - /* if v' is reachable, an st-path is given by P(u)-uv-P'(v') */ - /*&& PrevPt[prim(u)] != prim(v) ** avoid edges of T' */ - && ( SwitchEdge_Vert1( prim( u ) ) != prim( v ) || SwitchEdge_Vert2( prim( u ) ) != prim( u ) ) /* avoid edges of T' */ - && b_u != b_v - && !( pBNS->type_TACN && bIgnoreVertexNonTACN_group( pBNS, prim( v ), u, SwitchEdge ) ) -#if ( FIX_KEEP_H_ON_NH_ANION == 1 ) - && !( pBNS->type_TACN && bIsRemovedHfromNHaion( pBNS, prim( v ), u ) ) -#endif - ) - { -#if ( BNS_RAD_SEARCH == 1 ) - n++; -#endif - /* There is now a valid sv-path via u avoiding b_v (unless v==b_v) - => u, v, u', and v' now all become part of the same connected component of M[C] */ - - if (b_u < 0) /* djb-rwth: fixing coverity CID #499578 */ - { - return BNS_WRONG_PARMS; - } - - w = MakeBlossom( pBNS, ScanQ, &QSize, Pu, Pv, max_len_Pu_Pv, SwitchEdge, BasePtr, u, v, iuv, b_u, b_v, Tree ); - /* this constructed the new blossom and returned its base */ - - if (IS_BNS_ERROR( w )) - { - pBD->QSize = QSize; - return w; /* error */ - } - - b_u = w; /* the new base of C(u) */ - if (prim( w ) == Vertex_t) - { - /* t is now s-reachable, a valid augmenting path P exists in M */ - delta = FindPathCap( pBNS, SwitchEdge, Vertex_s, Vertex_t, 10000 ); /* compute the residual capacity of P + P' */ - if (IS_BNS_ERROR( delta )) - { - pBD->QSize = QSize; - return delta; /* error */ - } -#if ( ALLOW_ONLY_SIMPLE_ALT_PATH == 1 ) - if (pBNS->bNotASimplePath || abs( delta ) > 1) - { - delta = 0; - } -#endif - if (delta) - { - pBNS->bChangeFlow |= ( bChangeFlow & BNS_EF_CHNG_FLOW ); - } - ret = PullFlow( pBNS, SwitchEdge, Vertex_s, Vertex_t, delta, 0, bChangeFlow ); /* augment on a pair of valid st-paths */ - pBD->QSize = QSize; - return - ( IS_BNS_ERROR( ret ) ? ret : delta ); - } - } - } - - else if (IS_BNS_ERROR( ret )) - { - pBD->QSize = QSize; - return ret; /* error */ - } - } - -#if ( BNS_RAD_SEARCH == 1 ) - if (bRadSearch && !n) - { - /* The BNS stopped at u */ - n = RegisterRadEndpoint( pBNS, pBD, u ); - if (IS_BNS_ERROR( n )) - { - pBD->QSize = QSize; - return n; - } - } -#endif - - k++; /* advance ScanQ */ - } while (k <= QSize); - - - /* if this point is reached, no valid augmenting path exists, ScanQ contains - the set S of all s-reachable vertices and K=[S,S-] is a minimum balanced edge-cut */ - /* ClearFlowMarks( vert, num_vert); */ - - pBD->QSize = QSize; - - return 0; -} - - -/* -Blossoms. - -The vertices of a mirror network M consist T U T'. Intersection T ^ T' is empty. - -The edges of M consist of switch-edges and their complements because edges -are added in complementary pairs, one of which is always a switch-edge. - -The base of every blossom is in T. -Let C(i) be a blossom with base b_i. Since C(i)=C(i)', C(i) contains vertices of T and T'. -Since every valid sv-path to v in C(i) contains b_i, b_i is the first s-reachable vertex of C(i). - -Suppose the mirror network M contains a valid sz-path P(z) to all vertices z in ScanQ. -Every vertex of P(z) is s-reachable therefore its vertices are all in blossoms or -trivial blossoms. - -Let z be an s-reachable vertex and P(z) be a valid path in M. -Then every valid sz-path in M contains exactly the same sequence of blossom bases as P(z). - -*/ - - - -/*********************************************************************** -BasePtr[u] = -2 NO_VERTEX u is not a blossom --1 BLOSSOM_BASE u is the base of its blossom -v a vertex closer to the base -************************************************************************/ -Vertex FindBase( Vertex u, Vertex *BasePtr ) -{ - if (BasePtr[u] == NO_VERTEX) - { - return NO_VERTEX; - } - else if (BasePtr[u] == BLOSSOM_BASE) - { - return u; - } - else - { - Vertex b; - b = FindBase( BasePtr[u], BasePtr ); - BasePtr[u] = b; /* path compression */ - return b; - } - -} - - -/**************************************************************************** -Returns index of the last path element and the path -****************************************************************************/ -int FindPathToVertex_s( Vertex x, - Edge *SwitchEdge, - Vertex *BasePtr, - Vertex *Path, - int MaxPathLen ) -{ - /* x is the base of a blossom, construct a valid Path of blossom bases to s */ - int i = 0; - Path[i] = x; - while (x != Vertex_s) - { - x = FindBase( SwitchEdge_Vert1( x ), BasePtr ); - if (++i < MaxPathLen) - { - Path[i] = x; - } - else - { - return BNS_WRONG_PARMS; - } - } - - return i; -} - - - -/**************************************************************************** -Make a blossom -****************************************************************************/ -Vertex MakeBlossom( BN_STRUCT* pBNS, - Vertex *ScanQ, - int *pQSize, - Vertex *Pu, - Vertex *Pv, - int max_len_Pu_Pv, - Edge *SwitchEdge, - Vertex *BasePtr, - Vertex u, - Vertex v, - EdgeIndex iuv, - Vertex b_u, - Vertex b_v, - S_CHAR *Tree ) -{ - /* In order to find the base of the new blossom, the paths - P(u) and P(v') are constructed and compared in order to - find the last blossom base they have in common which - is reachable on a valid path. - - Edge uv connects two blossoms, their bases are b_u and b_v. - */ - Vertex w, z; - int len_Pu, len_Pv; - int i, j, k; - EdgeIndex izw; - - len_Pu = FindPathToVertex_s( b_u, SwitchEdge, BasePtr, Pu, max_len_Pu_Pv ); - if (IS_BNS_ERROR( len_Pu )) - { - return len_Pu; - } - len_Pv = FindPathToVertex_s( b_v, SwitchEdge, BasePtr, Pv, max_len_Pu_Pv ); - if (IS_BNS_ERROR( len_Pv )) - { - return len_Pv; - } - i = len_Pu; - j = len_Pv; - /* Initially Pu[i] and Pv[j] both equal to s, but their first elements are different */ - /* Find the last blossom base common to Pu and Pv */ - while (i >= 0 && j >= 0 && Pu[i] == Pv[j]) - { - /* Was (Pu[i]==Pv[j] && i>=0 && j>=0) => tested Pu[-1], Pv[-1] <- pointed by W.Ihlenfeldt 08-26-2004*/ - i--; - j--; - } - i++; - w = Pu[i]; /* w is the last common vertex */ - z = SwitchEdge_Vert1( w ); - izw = SwitchEdge_IEdge( w ); - /* now extend the blossom if rescap(zw) >= 2 */ - while (w != Vertex_s && rescap( pBNS, z, w, izw ) >= 2) - { - i++; - w = Pu[i]; - z = SwitchEdge_Vert1( w ); - izw = SwitchEdge_IEdge( w ); - } - /* w is the base of the new blossom */ - /* first follow the path Pu from w to b_u */ - for (k = i - 1; k >= 0; k--) - { - z = Pu[k]; /* z is the base of the blossom */ - BasePtr[z] = w; - BasePtr[prim( z )] = w; /* w is the new base of the blossom */ - /* z and z' may already be part of a blossom that is being - swallowed into a larger blossom. - We don't want to change the switch edge in that case. - */ - - if (!TREE_IS_ON_SCANQ( prim( z ) ) /*!IsInScanQ(prim(z)) */) - { - SwitchEdge_Vert1( prim( z ) ) = prim( v ); /* set the switch edge of z' */ - /* SwitchEdge[prim(z)][1] = prim(u); */ - SwitchEdge_IEdge( prim( z ) ) = iuv; - ( *pQSize )++; - ScanQ[*pQSize] = prim( z ); /* add z' to ScanQ */ - TREE_MARK( prim( z ), TREE_IN_2BLOSS ); /* mark z' s-reachable */ - } - } - /* Now follow the path Pv */ - for (k = j; k >= 0; k--) /* djb-rwth: converting for loop into while loop to avoid LLVM warning */ - { - z = Pv[k]; /* z is the base of the blossom */ - BasePtr[z] = w; - BasePtr[prim( z )] = w; /* w is the new base of the blossom */ - /* z and z' may already be part of a blossom that is being - swallowed into a larger blossom. - We don't want to change the switch edge in that case. - */ - - if (!TREE_IS_ON_SCANQ( prim( z ) ) /*!IsInScanQ(prim(z)) */) - { - SwitchEdge_Vert1( prim( z ) ) = u; /* set the switch edge of z' */ - /* SwitchEdge[prim(z)][1] = v; */ - SwitchEdge_IEdge( prim( z ) ) = iuv; - ( *pQSize )++; - ScanQ[*pQSize] = prim( z ); /* add z' to ScanQ */ - TREE_MARK( prim( z ), TREE_IN_2BLOSS ); /* mark z' s-reachable */ - } - } - - if (!TREE_IS_ON_SCANQ( prim( w ) ) /* !IsInScanQ(prim(w))*/) - { /* add w' to the blossom */ - SwitchEdge_Vert1( prim( w ) ) = u; /* set the switch edge of w' */ - /* SwitchEdge[prim(w)][1] = v; */ - SwitchEdge_IEdge( prim( w ) ) = iuv; - ( *pQSize )++; - ScanQ[*pQSize] = prim( w ); /* add w' to ScanQ */ - TREE_MARK( prim( w ), TREE_IN_2BLOSS ); /* mark w' s-reachable */ - } - - return w; -} - - -/**************************************************************************** -When t is found to be s-reachable, a valid st-path P is known to exist. -Its complementary path P' is also valid. Once the residual capacity -delta(P) is known, the flow is augmented by calling PullFlow(s,t,delta). -It constructs the path P by using the switch-edges. -Let uv=SwitchEdge[t]. -Then P is given by a valid su-path, followed by the edge uv, followed by -a valid vt-path. -PullFlow is a recursive procedure that constructs the path and its complement. - -Let wz=SwitchEdge[y]. PullFlow(x, y, delta) uses the xw- and zy-portions of P -(see below). Since it must also augment on P' simultaneously, the zy-portion -is replaced by the y'z'-portion. - -x y' -| | P: x--w--z--y -P | | P' P': y'-z'-w'-x' -| o -o \ -/ w' z \ -/ o----\ /----o / -\ / \ / \ / -\/ X \/ -/\ / \ /\ -/ \ w / \ z' / \ -\ o---- ----o / Using a switch-edge wz and w'z' -\ / to construct P and P' -o o -| | -| | -x' y - - -****************************************************************************/ - - - -/* PullFlow( ... ) - -Augment the flow by delta on all edges on a path P -between x and y in the order of the path; -AugmentEdge( pBNS, w, z, iwz, delta, 0 ) means the path is in w->z direction -AugmentEdge( pBNS, w, z, iwz, delta, 1 ) means the path is in w<-z direction - -Unlike PullFlow in the paper by Kocay & Stone, here the augmentation -starts at "s", proceeds sequentially through the path end terminates at "t". -Since we do not really need the complement path, PullFlow ignores it. -*/ - - -/****************************************************************************/ -int PullFlow( BN_STRUCT *pBNS, - Edge *SwitchEdge, - Vertex x, - Vertex y, - int delta, - S_CHAR bReverse, - int bChangeFlow ) -{ - Vertex w, z; - EdgeIndex iwz; - int ret = 0; - - w = SwitchEdge_Vert1( y ); - z = SwitchEdge_Vert2( y ); - iwz = SwitchEdge_IEdge( y ); - if (bReverse) - { - /* P consists of a path from x to w, then wz, then a path from z to y. */ - /* z may equal y, in which case z is just PrevPt[y] */ - if (z != y) - { - ret = PullFlow( pBNS, SwitchEdge, prim( y ), prim( z ), delta, (S_CHAR) ( 1 - bReverse ), bChangeFlow ); /* augment between z and y */ - } - if (!IS_BNS_ERROR( ret )) - { - ret = AugmentEdge( pBNS, w, z, iwz, delta, bReverse, bChangeFlow ); - } - /* Do not augment the complementary path: AugmentEdge( prim(z), prim(w), vert, delta); */ - /* w may equal x, in which case there is no need to call PullFlow(x, w) */ - if (w != x && !IS_BNS_ERROR( ret )) - { - ret = PullFlow( pBNS, SwitchEdge, x, w, delta, bReverse, bChangeFlow ); /* augment between x and w */ - } - } - else - { - /* P consists of a path from x to w, then wz, then a path from z to y. */ - /* w may equal x, in which case there is no need to call PullFlow(x, w) */ - if (w != x && !IS_BNS_ERROR( ret )) - { - ret = PullFlow( pBNS, SwitchEdge, x, w, delta, bReverse, bChangeFlow ); /* augment between x and w */ - } - if (!IS_BNS_ERROR( ret )) - { - ret = AugmentEdge( pBNS, w, z, iwz, delta, bReverse, bChangeFlow ); - } - /* z may equal y, in which case z is just PrevPt[y] */ - if (z != y && !IS_BNS_ERROR( ret )) - { - ret = PullFlow( pBNS, SwitchEdge, prim( y ), prim( z ), delta, (S_CHAR) ( 1 - bReverse ), bChangeFlow ); /* augment between z and y */ - } - } - - return ret; -} - - -/**************************************************************************** -Before augmenting on the two paths, it is necessary to find delta(P). -This can be done by following the paths and computing the minimum -residual capacity of all edges on P. An edge on both P and P' counts -for only half of its actual residual capacity, since augmentng on P by -delta will simutaneously reduce its capacity on P' by delta. -The path P can only be followed by using the switch-edges, as in PullFlow(...). -FindPathCap( x, y, delta ) is a recursive procedure that finds the residual -capacity on the portion of P between x and y. delta is the minimum capacity -found so far along the path. -****************************************************************************/ - - -/**************************************************************************** -Find the minimum residual capacity of all edges -between x and y in a valid st-path P. -delta is the minimum found so far -the vertices occur in order s,...,x,...,y,...,t along P -the vertices occur in order s,...,y',...,x',...,t along P' -****************************************************************************/ -int FindPathCap( BN_STRUCT* pBNS, Edge *SwitchEdge, Vertex x, Vertex y, int delta ) -{ - - Vertex w, z, iwz; - int cap, delta2; - - /* static int level; - if ( level ++ > 50 ) - { - #ifdef _DEBUG - int stop = 1; - #else - ; - #endif - } - */ - - w = SwitchEdge_Vert1( y ); - z = SwitchEdge_Vert2( y ); /* wz is on the path P */ - iwz = SwitchEdge_IEdge( y ); /* edge index */ - - /* Rescap_mark() detects edges passed 2 times and reduces rescap */ - cap = rescap_mark( pBNS, w, z, iwz ); - - if (IS_BNS_ERROR( cap )) - { - /* level --; */ - return cap; - } - if (cap < delta) - { - delta = cap; - } - /* P consists of a path from x to w, then wz, then a path from z to y */ - if (w != x) - { - delta2 = FindPathCap( pBNS, SwitchEdge, x, w, delta ); - delta = inchi_min( delta2, delta ); - } - if (z != y) - { - delta2 = FindPathCap( pBNS, SwitchEdge, prim( y ), prim( z ), delta ); - delta = inchi_min( delta2, delta ); - } - /* level --; */ - - return delta; -} - - -/* -BT = bond types -*/ - - -#define BT_ALTERN_BOND 1 /* 1-2, possibly stereo */ -#define BT_OTHER_ALTERN_BOND 2 /* 1-3, 2-3, 1-2-3 alternating non-stereo non-taut bonds */ - -#define BT_ALTERN_NS_BOND 4 - -#define BT_TAUTOM_BOND 8 - -#define BT_ALTERN_UNKN_BOND 16 - -#define BT_IGNORE_BOND 0 - -#define BT_NONSTEREO_MASK (BT_TAUTOM_BOND|BT_ALTERN_NS_BOND) - -#define BT_ALT_BOND_MASK (BT_ALTERN_BOND|BT_OTHER_ALTERN_BOND) - -#define BT_NONTAUT_BOND_MASK (BT_ALTERN_BOND|BT_OTHER_ALTERN_BOND|BT_ALTERN_NS_BOND) - -/* BNS members redefinitions for finding non-stereo bonds */ -/* BNS_EDGE */ -#define nBlockNumberAltBns flow /* internal variable of the DFS traversal: mark traversed bonds */ -#define nNumAtInBlockAltBns cap -#define nBondTypeInpAltBns pass /* 0=>cannot be stereo at all, 1=>alt or taut non-stereo, 2=>can be stereo */ -#define nBondNonStereoAltBns cap /* 1=>found to be non-stereogenic although BondTypeInp=2; 0=>as in BondTypeInp */ - -#if ( BNS_MARK_ONLY_BLOCKS == 1 ) /* { */ -/* BNS_VERTEX */ -#define bCutVertexAltBns st_edge.cap0 /* cut-vertex flag */ -#define nRingSystemAltBns st_edge.cap /* ordering number of a ring system */ -#define nNumAtInRingSystemAltBns st_edge.flow0 /* number of vertices in a ring system */ -#define nBlockSystemAltBns st_edge.flow /* result of the DFS traversal: even cirquit must be within one block */ - -#endif /* } */ - -#define valenceAltBns num_adj_edges - - -/****************************************************************************/ -int MarkRingSystemsAltBns( BN_STRUCT* pBNS, int bUnknAltAsNoStereo ) -{ - AT_NUMB *nStackAtom = NULL; - int nTopStackAtom; - AT_NUMB *nRingStack = NULL; - int nTopRingStack; /* was AT_NUMB */ - AT_NUMB *nBondStack = NULL; - int nTopBondStack; - AT_NUMB *nDfsNumber = NULL; - AT_NUMB *nLowNumber = NULL; - S_CHAR *cNeighNumb = NULL; - AT_NUMB nDfs; - AT_NUMB nNumAtInRingSystem; - int i, j, u, w, start, nNumRingSystems; /* djb-rwth: removing redundant variables */ - BNS_VERTEX *at = pBNS->vert; - BNS_EDGE *bond = pBNS->edge; - int num_atoms = pBNS->num_atoms; - int num_edges = pBNS->num_bonds; - - /* Allocate arrays */ - nStackAtom = (AT_NUMB *) inchi_malloc( num_atoms * sizeof( nStackAtom[0] ) ); - nRingStack = (AT_NUMB *) inchi_malloc( num_atoms * sizeof( nRingStack[0] ) ); - nDfsNumber = (AT_NUMB *) inchi_malloc( num_atoms * sizeof( nDfsNumber[0] ) ); - nLowNumber = (AT_NUMB *) inchi_malloc( num_atoms * sizeof( nLowNumber[0] ) ); - nBondStack = num_edges ? ( (AT_NUMB *) inchi_malloc( num_edges * sizeof( nBondStack[0] ) ) ) : (AT_NUMB *) ( NULL ); /* special case: no bonds 2006-03 */ - cNeighNumb = (S_CHAR *) inchi_malloc( num_atoms * sizeof( cNeighNumb[0] ) ); - - /* Check allocation */ - if (!nStackAtom || !nRingStack || !nDfsNumber || !nLowNumber || (!nBondStack && num_edges) || !cNeighNumb - ) /* djb-rwth: addressing LLVM warning */ - { - nNumRingSystems = CT_OUT_OF_RAM; /* program error */ /* */ - goto exit_function; - } - - /******************************************** - * - * Find Cut-vertices & Blocks - * - * 1\ /5 has 3 blocks (maximal subgraphs that - * Example: | >3--4< | are nonseparable by deleting a single vertex): - * 2/ \6 (1,2,3, has 3 bonds), (3,4, has 1 bond), and (4,5,6, has 3 bonds) - * - * Cut-vertices or articulation points are - * intersections of the blocks: points 3 and 4. - ********************************************/ - - /******************************************************** - - RingSystemAlt are atoms connected by alternating bonds - (as must be indicated in bIsAltBond()): - - BOND_ALTERN - BOND_ALT_123 - BOND_ALT_13 - BOND_ALT_23 - - Since other bonds may be present, we possibly need - to restart to move to another component - *********************************************************/ - - nNumRingSystems = 0; - memset( nDfsNumber, 0, num_atoms * sizeof( nDfsNumber[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - - for (start = 0; start < num_atoms; start++) - { - if (nDfsNumber[start]) - { - continue; - } - for (i = 0; i < at[start].valenceAltBns; i++) - { - if (bond[at[start].iedge[i]].nBondTypeInpAltBns & BT_ALTERN_BOND) - goto found_alt; - } - continue; - - found_alt: - - /* Initiation */ - u = start; /* start atom */ - nDfs = 0; - nTopStackAtom = -1; - nTopRingStack = -1; - nTopBondStack = -1; - memset( cNeighNumb, 0, num_atoms * sizeof( cNeighNumb[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - /* Push the start atom on the stack */ - nLowNumber[u] = nDfsNumber[u] = ++nDfs; - nStackAtom[++nTopStackAtom] = (AT_NUMB) u; - nRingStack[++nTopRingStack] = (AT_NUMB) u; - - /* djb-rwth: removing redundant code */ - - do - { - /* advance */ - /*while ( (int)at[i=nStackAtom[nTopStackAtom]].valenceAltBns > (j = (int)cNeighNumb[i]) )*/ - /* replaced due to missing sequence point */ - while (i = (int) nStackAtom[nTopStackAtom], j = (int) cNeighNumb[i], (int) at[i].valenceAltBns > j) - { - cNeighNumb[i] ++; - if (!( bond[w = at[i].iedge[j]].nBondTypeInpAltBns & BT_ALT_BOND_MASK )) - { - continue; - } - u = (int) ( bond[at[i].iedge[j]].neighbor12 ^ i ); - if (!nDfsNumber[u] && nBondStack) /* djb-rwth: fixing a NULL pointer dereference */ - { - /* tree edge, 1st visit -- advance */ - nStackAtom[++nTopStackAtom] = (AT_NUMB) u; - nRingStack[++nTopRingStack] = (AT_NUMB) u; - nBondStack[++nTopBondStack] = (AT_NUMB) w; - nLowNumber[u] = nDfsNumber[u] = ++nDfs; - /* djb-rwth: removing redundant code */ - } - else - { - if (!nTopStackAtom || u != (int) nStackAtom[nTopStackAtom - 1]) - { /* may comment out ? */ - /* back edge: u is not a predecessor of i */ - if ((nDfsNumber[u] < nDfsNumber[i]) && nBondStack) /* djb-rwth: fixing a NULL pointer dereference */ - { - /* Back edge, 1st visit: u is ancestor of i. Save and compare */ - nBondStack[++nTopBondStack] = (AT_NUMB) w; - if (nLowNumber[i] > nDfsNumber[u]) - { - nLowNumber[i] = nDfsNumber[u]; - } - } - } - } - } - cNeighNumb[i] = 0; - - /* Back up */ - if (i != start) - { - u = (int) nStackAtom[nTopStackAtom - 1]; /* predecessor of i */ - if (nLowNumber[i] >= nDfsNumber[u]) - { - /* Output the block; the block was entered through its first bond u->i */ - nNumRingSystems++; - /*at[u].nBlockSystemAltBns = nNumRingSystems;*/ /* mark the atom */ - nNumAtInRingSystem = 1; - /* - if ( u != start || nNumStartChildren > 1 ) { - at[u].bCutVertexAltBns += 1; // mark cut-vertex (articulation point) - } - */ - while (nTopRingStack >= 0) - { - j = nRingStack[nTopRingStack--]; - /*at[j].nBlockSystemAltBns = nNumRingSystems;*/ /* mark the atom */ - nNumAtInRingSystem++; - if (i == j) - { - break; - } - } - while (nTopBondStack >= 0) - { - w = nBondStack[nTopBondStack--]; - bond[w].nBlockNumberAltBns = nNumRingSystems; /* mark the bond */ - bond[w].nNumAtInBlockAltBns = nNumAtInRingSystem; - if ((i == bond[w].neighbor1 && u == ( i ^ bond[w].neighbor12 )) || - (u == bond[w].neighbor1 && i == ( u ^ bond[w].neighbor12 ))) /* djb-rwth: addressing LLVM warning */ - { - break; - } - } - } - else - { - if (nLowNumber[u] > nLowNumber[i]) - { - /* inherit */ - nLowNumber[u] = nLowNumber[i]; - } - } - } - } while (--nTopStackAtom >= 0); - } - -#if ( BNS_MARK_ONLY_BLOCKS != 1 ) /* { */ - - /******************************************** - * - * Find Ring Systems - * Including chain atoms X: A-X-B, where the bonds (of any kind) are bridges. - * - ********************************************/ - - /* Initiation */ - nNumRingSystems = 0; - for (start = 0; start < num_atoms; start++) - { - if (at[start].nRingSystemAltBns) - { - continue; - } - for (i = 0; i < at[start].valenceAltBns; i++) - { - if (bond[at[start].iedge[i]].nBondTypeInpAltBns & BT_ALT_BOND_MASK) - { - goto found_alt2; - } - } - continue; - - found_alt2: - u = start; /* start atom */ - nDfs = 0; - nTopStackAtom = -1; - nTopRingStack = -1; - memset( nDfsNumber, 0, num_atoms * sizeof( nDfsNumber[0] ) ); - memset( cNeighNumb, 0, num_atoms * sizeof( cNeighNumb[0] ) ); - /* push the start atom on the stack */ - nLowNumber[u] = nDfsNumber[u] = ++nDfs; - nStackAtom[++nTopStackAtom] = (AT_NUMB) u; - nRingStack[++nTopRingStack] = (AT_NUMB) u; - - do - { - /* advance */ - advance_ring: - /*if ( (int)at[i=nStackAtom[nTopStackAtom]].valenceAltBns > (j = (int)cNeighNumb[i]) )*/ - /* replaced due to missing sequence point */ - if (i = (int) nStackAtom[nTopStackAtom], j = (int) cNeighNumb[i], (int) at[i].valenceAltBns > j) - { - cNeighNumb[i] ++; - if (!( bond[at[i].iedge[j]].nBondTypeInpAltBns & BT_ALTERN_BOND )) - { - goto advance_ring; - } - u = (int) ( bond[at[i].iedge[j]].neighbor12 ^ i ); - if (!nDfsNumber[u]) - { - /* tree edge, 1st visit -- advance */ - nStackAtom[++nTopStackAtom] = (AT_NUMB) u; - nRingStack[++nTopRingStack] = (AT_NUMB) u; - nLowNumber[u] = nDfsNumber[u] = ++nDfs; - } - else - { - if (!nTopStackAtom || u != (int) nStackAtom[nTopStackAtom - 1]) - { - /* back edge: u is not a predecessor of i */ - if (nDfsNumber[u] < nDfsNumber[i]) - { - /* Back edge, 1st visit: u is ancestor of i. Compare */ - if (nLowNumber[i] > nDfsNumber[u]) - { - nLowNumber[i] = nDfsNumber[u]; - } - } - } - } - goto advance_ring; - } - else - { - cNeighNumb[i] = 0; - } - - /* Back up */ - if (nDfsNumber[i] == nLowNumber[i]) - { - /* Found a ring system */ - nNumRingSystems++; - - /* Unwind nRingStack[] down to i */ - - /* Count atoms in a ring system */ - for (nNumAtInRingSystem = 0, j = nTopRingStack; 0 <= j; j--) - { - nNumAtInRingSystem++; - if (i == (int) nRingStack[j]) - { - break; - } - } - while (nTopRingStack >= 0) - { - j = (int) nRingStack[nTopRingStack--]; - at[j].nRingSystemAltBns = (AT_NUMB) nNumRingSystems; /* ring system id */ - at[j].nNumAtInRingSystemAltBns = nNumAtInRingSystem; - if (i == j) - { - /* Reached atom on the top of nStackAtom[] stack */ - break; - } - } - } - else - { - if (nTopStackAtom > 0) - { - j = (int) nStackAtom[nTopStackAtom - 1]; - /* inherit nLowNumber */ - if (nLowNumber[j] > nLowNumber[i]) - { - nLowNumber[j] = nLowNumber[i]; - } - } - } - } while (--nTopStackAtom >= 0); - } - -#endif /* } BNS_MARK_ONLY_BLOCKS != 1 */ - -exit_function: - if (nStackAtom) - { - inchi_free( nStackAtom ); - } - if (nRingStack) - { - inchi_free( nRingStack ); - } - if (nDfsNumber) - { - inchi_free( nDfsNumber ); - } - if (nLowNumber) - { - inchi_free( nLowNumber ); - } - if (nBondStack) - { - inchi_free( nBondStack ); - } - if (cNeighNumb) - { - inchi_free( cNeighNumb ); - } - - return nNumRingSystems; -} - - -/****************************************************************************/ -int ReInitBnStructForAltBns( BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - int bUnknAltAsNoStereo ) -{ - Vertex v, v2; - int ret, bond_type, num_to_test, j; - BNS_EDGE *pBond; - BNS_VERTEX *pAtom; - - /* Strip all t-groups and c-groups */ - num_to_test = 0; - if (bUnknAltAsNoStereo) - { - for (j = 0; j < pBNS->num_edges; j++) - { - pBNS->edge[j].pass = 0; - } - } - - ret = ReInitBnStruct( pBNS, at, num_atoms, 0 ); - - if (ret || pBNS->num_atoms != num_atoms || pBNS->num_vertices != num_atoms || pBNS->num_bonds != pBNS->num_edges) - { - ret = BNS_REINIT_ERR; - goto exit_function; - } - - /* Eliminate bonds and fix st-caps */ - for (v = 0; v < num_atoms; v++) - { - pAtom = pBNS->vert + v; - for (j = 0; j < pAtom->valenceAltBns; j++) - { - pBond = pBNS->edge + pAtom->iedge[j]; - if (pBond->neighbor1 == v) - { - bond_type = ( at[v].bond_type[j] & BOND_TYPE_MASK ); - v2 = pBond->neighbor12 ^ v; - if (at[v].endpoint || at[v2].endpoint) - { - bond_type = 0; /* any bond to an endpoint considered non-stereogenic */ - } -#if ( FIX_EITHER_DB_AS_NONSTEREO == 1 ) - if (bUnknAltAsNoStereo) - { - if (bond_type == BOND_ALTERN && at[v].bond_stereo[j] == STEREO_DBLE_EITHER) - { - bond_type = 0; /* treat unknown (Either) ALT bond as non-stereo */ - } - } -#endif - switch (bond_type) - { - - case BOND_ALTERN: - pBond->nBondTypeInpAltBns = BT_ALTERN_BOND; - num_to_test++; - break; - - case BOND_ALT_123: - case BOND_ALT_13: - case BOND_ALT_23: - pBond->nBondTypeInpAltBns = BT_OTHER_ALTERN_BOND; - break; - - case BOND_TAUTOM: - pBond->nBondTypeInpAltBns = BT_TAUTOM_BOND; - break; - - case BOND_ALT12NS: - pBond->nBondTypeInpAltBns = BT_ALTERN_NS_BOND; - break; - - case 0: - case BOND_SINGLE: - case BOND_DOUBLE: - case BOND_TRIPLE: - pBond->nBondTypeInpAltBns = BT_IGNORE_BOND; - break; - - default: - pBond->nBondTypeInpAltBns = BT_IGNORE_BOND; - break; - } - pBond->nBondNonStereoAltBns = 0; /* djb-rwth: addressing GCC warning -- operations on pBond->cap might be undefined */ - pBond->nBlockNumberAltBns = 0; - pBond->nNumAtInBlockAltBns = 0; - -#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) - pBond->forbidden &= pBNS->edge_forbidden_mask; -#endif - } - } - pAtom->bCutVertexAltBns = - pAtom->nRingSystemAltBns = - pAtom->nNumAtInRingSystemAltBns = - pAtom->nBlockSystemAltBns = 0; - } - - return num_to_test; - -exit_function: - - return ret; -} - - -/****************************************************************************/ -int MarkNonStereoAltBns( BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - int bUnknAltAsNoStereo ) -{ - int num_bonds = pBNS->num_bonds; - int ret; - int ibond, ib1, ib2; - BNS_EDGE *pBond; - Vertex iat1, iat2; - - ret = 0; - - if (pBNS->num_atoms != num_atoms || pBNS->num_vertices != num_atoms || pBNS->num_bonds != pBNS->num_edges) - { - ret = BNS_REINIT_ERR; - goto exit_function; - } - if (bUnknAltAsNoStereo) - { - for (ibond = 0; ibond < num_bonds; ibond++) - { - pBond = pBNS->edge + ibond; - if (pBond->nBondTypeInpAltBns != BT_ALTERN_BOND && pBond->nBondTypeInpAltBns != BT_IGNORE_BOND) - { - continue; - } - iat1 = pBond->neighbor1; - iat2 = pBond->neighbor12 ^ iat1; - ib1 = pBond->neigh_ord[0]; - ib2 = pBond->neigh_ord[1]; - if ( /* alt bond non-adjacent to a taut. endpoint: */ - ( pBond->nBondTypeInpAltBns == BT_ALTERN_BOND && - pBond->nNumAtInBlockAltBns <= 3 ) /* non-ring bond */ || - /* alt bond adjacent to a taut. endpoint: */ - ( pBond->nBondTypeInpAltBns == BT_IGNORE_BOND && - ( at[iat1].bond_type[ib1] & BOND_TYPE_MASK ) == BOND_ALTERN ) - ) - { - if (( at[iat1].bond_type[ib1] & BOND_TYPE_MASK ) == BOND_ALTERN) - { - /* bond_type = BOND_ALT12NS; */ - at[iat1].bond_stereo[ib1] = - at[iat2].bond_stereo[ib2] = STEREO_DBLE_EITHER; - ret++; - } - } - } - } - else - { - for (ibond = 0; ibond < num_bonds; ibond++) - { - pBond = pBNS->edge + ibond; - if (pBond->nBondTypeInpAltBns != BT_ALTERN_BOND && pBond->nBondTypeInpAltBns != BT_IGNORE_BOND) - { - continue; - } - iat1 = pBond->neighbor1; - iat2 = pBond->neighbor12 ^ iat1; - ib1 = pBond->neigh_ord[0]; - ib2 = pBond->neigh_ord[1]; - if ( /* alt bond non-adjacent to a taut. endpoint: */ - ( pBond->nBondTypeInpAltBns == BT_ALTERN_BOND && - pBond->nNumAtInBlockAltBns <= 3 ) /* non-ring bond */ || - /* alt bond adjacent to a taut. endpoint: */ - ( pBond->nBondTypeInpAltBns == BT_IGNORE_BOND && - ( at[iat1].bond_type[ib1] & BOND_TYPE_MASK ) == BOND_ALTERN ) - ) - { - at[iat1].bond_type[ib1] = - at[iat2].bond_type[ib2] = BOND_ALT12NS; - ret++; - } - } - } - -exit_function: - - return ret; -} - - -#if ( READ_INCHI_STRING == 1 ) -/*****************************************************************************/ -#ifndef RI_ERR_ALLOC -/* from ichirvrs.h */ -#define RI_ERR_ALLOC (-1) -#define RI_ERR_SYNTAX (-2) -#define RI_ERR_PROGR (-3) -#endif - - -/**************************************************************************** -Check if atom bonded to charged atom -****************************************************************************/ -int bHasChargedNeighbor( inp_ATOM *at, int iat ) -{ - int i; - for (i = 0; i < at[iat].valence; i++) - { - if (at[(int) at[iat].neighbor[i]].charge) - { - return 1; - } - } - - return 0; -} - - -/**************************************************************************** -Add or remove protons - -*num_protons_to_add = nToBeRemovedByNormFromRevrs - -nToBeRemovedByNormFromRevrs > 0: less protons should be allowed to be -added by the Normalization of the Reconstructed Structure -nToBeRemovedByNormFromRevrs < 0: prepare more H(+) to be removed by -the InChI Normalization of the Reconstructed Structure - -OrigStruct -> NormOrig + n(orig)*H(+) -RevrStruct -> NormRevr + n(revr)*H(+) -nToBeRemovedByNormFromRevrs = n(orig) - n(revr) [each may be negative] - -n(orig) > n(revr) or nToBeRemovedByNormFromRevrs > 0 means: ------------------------------------------------------------ -- Too many protons were added by the Normalization to the Reconstructed Structure -(a) n(revr) < 0 => protons were added while they should not have been added; -Solution: "neutralize" (-) charged proton acceptors by moving charges to other atoms -on the condition ADP cannot add in another way; -(b) n(orig) > n(revr) => 0 => too few protons were removed -Solution: (the easiest) attach H(+) to =O or -N< or -N= -Solution: move (+) from N or OH to an atom adjacent to (-) charge or to -an atom that is not N. - -n(orig) < n(revr) or nToBeRemovedByNormFromRevrs < 0 means: ------------------------------------------------------------ -- Too few protons were added by the Normalization to the Reconstructed Stucture -(a) n(orig) < 0 => protons were not added while they should have been added; -Solution: move (-) to O by replacing =O with -O(-) -(b) 0 <= n(orig) < n(revr) => too many protons were removed - -Note: it is critically important to takr into account cumbersome Normalization -Total Charge: if it is >= 0 then no H(+) may be removed from -OH or by ADP -However, if N(+) is present then ADP will always try to remove a proton -****************************************************************************/ -int AddRemoveProtonsRestr( inp_ATOM *at, - int num_atoms, - int *num_protons_to_add, - int nNumProtAddedByRestr, - INCHI_MODE bNormalizationFlags, - int num_tg, - int nChargeRevrs, - int nChargeInChI ) -{ - int i, j, ret = 0; - int nAtTypeTotals[ATTOT_ARRAY_LEN]; - int num_prot = *num_protons_to_add; - int type, mask, bSuccess, nTotCharge, nNumSuccess = 0; - int max_j_Aa = -1, max_j_Ar = -1; - - /* for the reference: - - #define FLAG_NORM_CONSIDER_TAUT ( FLAG_PROTON_NPO_SIMPLE_REMOVED | \ - FLAG_PROTON_NP_HARD_REMOVED | \ - FLAG_PROTON_AC_SIMPLE_ADDED | \ - FLAG_PROTON_AC_SIMPLE_REMOVED | \ - FLAG_PROTON_AC_HARD_REMOVED | \ - FLAG_PROTON_AC_HARD_ADDED | \ - FLAG_PROTON_SINGLE_REMOVED | \ - FLAG_PROTON_CHARGE_CANCEL ) - - #define FLAG_FORCE_SALT_TAUT ( FLAG_PROTON_NP_HARD_REMOVED | \ - FLAG_PROTON_AC_HARD_REMOVED | \ - FLAG_PROTON_AC_HARD_ADDED ) - - */ - - /* if ChargeRevrs > nChargeInChI then we should prevent proton addition or facilitate proton removal - a typical case is (=) on N or O instead of C(-) - - if ChargeRevrs < nChargeInChI then we should prevent proton removal or facilitate proton addition - */ - - mark_at_type( at, num_atoms, nAtTypeTotals ); - for (i = nTotCharge = 0; i < num_atoms; i++) - { - nTotCharge += at[i].charge; - } - /* Size for SimpleAddAcidicProtons() */ - for (max_j_Aa = 0; AaTypMask[2 * max_j_Aa]; max_j_Aa++) - { - ; - } - /* Size for SimpleRemoveAcidicProtons */ - for (max_j_Ar = 0; ArTypMask[2 * max_j_Ar]; max_j_Ar++) - { - ; - } - if (num_prot < 0 && nAtTypeTotals[ATTOT_TOT_CHARGE] - nNumProtAddedByRestr <= 0) - { - /* Remove proton(s) */ - /* use test from SimpleAddAcidicProtons() to test whether removal of H(+) from =C-OH, etc. is correct */ - for (i = 0; i < num_atoms && num_prot; i++) - { - /* Choose an atom */ - if (at[i].sb_parity[0] || at[i].p_parity || at[i].charge || - !at[i].num_H || at[i].radical || bHasChargedNeighbor( at, i )) - { - continue; - } - /* try to remove a proton and check whether InChI would add it back */ - at[i].charge--; - at[i].num_H--; - type = GetAtomChargeType( at, i, NULL, &mask, 0 ); - at[i].charge++; - at[i].num_H++; - - if (type) - { - for (bSuccess = 0, j = 0; j < max_j_Aa; j++) - { - if ((bSuccess = ( type & AaTypMask[2 * j] ) && ( mask && AaTypMask[2 * j + 1] ))) /* djb-rwth: addressing LLVM warning */ - { - break; /* the proton may be added to this atom */ - } - } - if (bSuccess) - { - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 1 ); /* subtract at[i] */ - at[i].charge--; - at[i].num_H--; - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); /* add changed at[i] */ - num_prot++; /* success */ - nNumSuccess++; - } - } - } - } - - if (num_prot < 0 && num_tg && nAtTypeTotals[ATTOT_TOT_CHARGE] - nNumProtAddedByRestr <= 0) - { - /* Alternative proton removal: O=C-NH => (-)O-C=N, O and N are taut. endpoints */ - int endp2, centp, k, i0, k0; - for (i = 0; i < num_atoms; i++) - { - /* Choose an atom */ - if (!at[i].endpoint || at[i].sb_parity[0] || at[i].p_parity || - at[i].radical || at[i].charge || bHasChargedNeighbor( at, i )) - { - continue; - } - /* Looking for tautomeric =O */ - if (1 != at[i].valence || BOND_TYPE_DOUBLE != at[i].bond_type[0] || at[i].num_H || - 2 != get_endpoint_valence( at[i].el_number )) - { - continue; - } - centp = at[i].neighbor[0]; - if (at[centp].sb_parity[0] || at[centp].p_parity || !is_centerpoint_elem( at[centp].el_number )) - { - continue; - } - /* Found a possible centerpoint, looking for -NH endpoint */ - for (k = 0; k < at[centp].valence; k++) - { - if (at[centp].bond_type[k] != BOND_TYPE_SINGLE) - { - continue; - } - endp2 = at[centp].neighbor[k]; - if (at[endp2].endpoint != at[i].endpoint || - !at[endp2].num_H || at[endp2].charge || - at[endp2].sb_parity[0] || at[endp2].p_parity || - at[endp2].valence != at[endp2].chem_bonds_valence || - 3 != at[endp2].chem_bonds_valence + at[endp2].num_H || - 3 != get_endpoint_valence( at[endp2].el_number )) - { - continue; - } - /* Find bonds in reciprocal ajacency lists */ - for (i0 = 0; i0 < at[centp].valence && i != at[centp].neighbor[i0]; i0++) - { - ; - } - for (k0 = 0; k0 < at[endp2].valence && centp != at[endp2].neighbor[k0]; k0++) - { - ; - } - if (i0 == at[centp].valence || k0 == at[endp2].valence) - { - return RI_ERR_PROGR; - } - /* -NH has been found */ - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 1 ); /* subtract at[i] */ - type = GetAtomChargeType( at, endp2, nAtTypeTotals, &mask, 1 ); /* subtract at[endp2] */ - - at[i].bond_type[0] --; - at[centp].bond_type[i0] --; - at[i].chem_bonds_valence--; - at[i].charge--; - - at[endp2].bond_type[k0] ++; - at[centp].bond_type[k] ++; - at[endp2].chem_bonds_valence++; - at[endp2].num_H--; - - num_prot++; - nNumSuccess++; - - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); /* add at[i] */ - type = GetAtomChargeType( at, endp2, nAtTypeTotals, &mask, 0 ); /* add at[endp2] */ - } - } - } - - if (num_prot > 0) - { - /* Add protons */ - /* 1. Use test from SimpleRemoveAcidicProtons() to test whether addition of H(+) to =C-O(-), etc. is correct */ - for (i = 0; i < num_atoms && num_prot && nAtTypeTotals[ATTOT_TOT_CHARGE] - nNumProtAddedByRestr >= 0; i++) - { - /* Choose an atom */ - if (at[i].sb_parity[0] || at[i].p_parity || at[i].num_H || - at[i].charge != -1 || at[i].radical || bHasChargedNeighbor( at, i )) - { - continue; - } - /* Try to add a proton and check whether InChI would remove it back */ - at[i].charge++; - at[i].num_H++; - type = GetAtomChargeType( at, i, NULL, &mask, 0 ); - at[i].charge--; - at[i].num_H--; - if (type) - { - for (bSuccess = 0, j = 0; j < max_j_Ar; j++) - { - if ((bSuccess = ( type & ArTypMask[2 * j] ) && ( mask && ArTypMask[2 * j + 1] ))) /* djb-rwth: addressing LLVM warning */ - { - break; - } - } - if (bSuccess) - { - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 1 ); /* subtract at[i] */ - at[i].charge++; - at[i].num_H++; - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); /* add changed at[i] */ - num_prot--; /* success */ - nNumSuccess++; - } - } - } - /* 2. Use test from SimpleRemoveHplusNPO() */ - for (i = 0; i < num_atoms && num_prot; i++) - { - /* Choose an atom */ - if (at[i].sb_parity[0] || at[i].p_parity || - at[i].charge || at[i].radical || bHasChargedNeighbor( at, i )) - { - continue; - } - /* Try to add a proton and check whether InChI would remove it back */ - at[i].num_H++; - at[i].charge++; - bSuccess = ( PR_SIMPLE_TYP & ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) ) ) && - ( PR_SIMPLE_MSK & mask ); /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - at[i].num_H--; /* failed */ - at[i].charge--; - if (bSuccess) - { - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 1 ); /* subtract at[i] */ - at[i].num_H++; - at[i].charge++; - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); /* add changed at[i] */ - num_prot--; /* succeeded */ - nNumSuccess++; - } - } - } - - if (num_prot < 0 && ( bNormalizationFlags & FLAG_PROTON_AC_HARD_ADDED ) && 1 == num_tg && - nAtTypeTotals[ATTOT_TOT_CHARGE] - nNumProtAddedByRestr <= 0) - { - /* Try to remove protons from tautomeric N (specific ADP must be present) */ - int nNumAcceptors_DB_O = 0, nNumDonors_SB_NH = 0, num_max, num_success; - for (i = 0; i < num_atoms; i++) - { - /* Choose an atom */ - if (!at[i].endpoint || at[i].radical || - at[i].sb_parity[0] || at[i].p_parity || bHasChargedNeighbor( at, i )) - { - continue; - } - type = GetAtomChargeType( at, i, NULL, &mask, 0 ); - if (( type & AA_HARD_TYP_CO ) && ( mask & AA_HARD_MSK_CO )) - { - nNumAcceptors_DB_O++; - } - else - { - if (( type == ATT_ATOM_N ) && ( mask == ATBIT_NP_H ) && !at[i].charge && - at[i].valence == at[i].chem_bonds_valence) - { - nNumDonors_SB_NH++; - } - } - } - num_max = inchi_min( nNumAcceptors_DB_O, nNumDonors_SB_NH ); - for (i = 0, num_success = 0; i < num_atoms && num_success < num_max && num_prot < 0; i++) - { - /* Choose an atom */ - if (!at[i].endpoint || at[i].radical || at[i].sb_parity[0] || - at[i].p_parity || bHasChargedNeighbor( at, i )) - { - continue; - } - type = GetAtomChargeType( at, i, NULL, &mask, 0 ); - if (( type == ATT_ATOM_N ) && ( mask == ATBIT_NP_H ) && !at[i].charge && - at[i].valence == at[i].chem_bonds_valence) - { - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 1 ); /* subtract at[i] */ - at[i].num_H--; - at[i].charge--; - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); /* add changed at[i] */ - num_prot++; - num_success++; - nNumSuccess++; - } - } - } - - /*exit_function:*/ - - *num_protons_to_add = num_prot; - - return ret < 0 ? ret : nNumSuccess; -} - - -/**************************************************************************** -Add or remove isotopic protons -****************************************************************************/ -int AddRemoveIsoProtonsRestr( inp_ATOM *at, - int num_atoms, - NUM_H num_protons_to_add[], - int num_tg ) -{ - int i, j, k, n, ret = 0; - int nNumSuccess = 0, min_at, max_at, num_H, num_iso_H, num_expl_H, num_expl_iso_H; /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ - int iCurIso; /* 0=> 1H, 1=> D, 2=> T */ - int iCurMode, iCurMode1, iCurMode2; /* 0=> Not Endpoints, 1=> Endpoints */ - - /* Distribute isotopes from heaviest to lightest; pick up atoms in order 1. Not endpoints; 2. Endpoints */ - iCurMode1 = 0; - iCurMode2 = num_tg ? 1 : 0; - for (iCurMode = iCurMode1; iCurMode <= iCurMode2; iCurMode++) - { - for (iCurIso = 2; 0 <= iCurIso; iCurIso--) - { - /* check for isotopic H to add */ - if (!num_protons_to_add[iCurIso]) - { - continue; - } - if (0 > num_protons_to_add[iCurIso]) - { - ret = RI_ERR_PROGR; - goto exit_function; - } - - /* Limits for atom scanning */ - min_at = 0; - max_at = num_atoms; - - /* Cycle withio the limits */ - for (i = min_at; i < max_at && 0 < num_protons_to_add[iCurIso]; i++) - { - /* Pick an atom */ - if (iCurMode) - { - if (at[i].endpoint) - { - j = i; /* atom number */ - } - else - { - continue; - } - } - else - { - if (!at[i].endpoint && 1 == bHeteroAtomMayHaveXchgIsoH( at, i )) - { /* atom number */ - j = i; - } - else - { - if (at[i].el_number == EL_NUMBER_H && at[i].charge == 1 && - !at[i].valence && !at[i].radical && !at[i].iso_atw_diff) - { - /* proton, not isotopic; make it isotopic */ - at[i].iso_atw_diff = 1 + iCurIso; - num_protons_to_add[iCurIso] --; - nNumSuccess++; - continue; - } - else - { - continue; - } - } - } - - /* j is the atom number */ - /* count implicit H */ - num_H = at[j].num_H; - num_iso_H = NUM_ISO_H(at, j); /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ - - while (num_H > 0 && num_protons_to_add[iCurIso] > 0) - { - /* Substitute one implicit H with an isotopic atom H */ - at[j].num_iso_H[iCurIso] ++; - at[j].num_H--; - num_protons_to_add[iCurIso] --; - num_H--; - num_iso_H++; - nNumSuccess++; - } - /* Count explicit H */ - num_expl_H = num_expl_iso_H = 0; - for (k = 0; k < at[j].valence && num_atoms <= ( n = at[j].neighbor[k] ); k++) - { - num_expl_H += ( 0 == at[n].iso_atw_diff ); - num_expl_iso_H += ( 0 != at[n].iso_atw_diff ); - } - while (num_expl_H > 0 && num_protons_to_add[iCurIso] > 0) - { - /* Substitute one explicit H with an isotopic atom H */ - n = at[j].neighbor[num_expl_H]; - if (at[n].iso_atw_diff) - { - ret = RI_ERR_PROGR; - goto exit_function; - } - at[n].iso_atw_diff = 1 + iCurIso; - num_expl_H--; - num_expl_iso_H++; - num_protons_to_add[iCurIso] --; - nNumSuccess++; - } - } - } - } - -exit_function: - - return ret < 0 ? ret : nNumSuccess; -} - -#endif From 6332c5eab98b65858fca52f435ed1aaeb167e95c Mon Sep 17 00:00:00 2001 From: Djordje Baljozovic Date: Sat, 31 Jan 2026 20:14:44 +0100 Subject: [PATCH 3/9] v.1.07.5_RC7 --- INCHI-1-SRC/INCHI_BASE/src/ichi_bns1.c | 12490 ----------------------- 1 file changed, 12490 deletions(-) delete mode 100644 INCHI-1-SRC/INCHI_BASE/src/ichi_bns1.c diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichi_bns1.c b/INCHI-1-SRC/INCHI_BASE/src/ichi_bns1.c deleted file mode 100644 index b7244c1f..00000000 --- a/INCHI-1-SRC/INCHI_BASE/src/ichi_bns1.c +++ /dev/null @@ -1,12490 +0,0 @@ -/* - * International Chemical Identifier (InChI) - * Version 1 - * Software version 1.07 - * April 30, 2024 - * - * MIT License - * - * Copyright (c) 2024 IUPAC and InChI Trust - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -* -* The InChI library and programs are free software developed under the - * auspices of the International Union of Pure and Applied Chemistry (IUPAC). - * Originally developed at NIST. - * Modifications and additions by IUPAC and the InChI Trust. - * Some portions of code were developed/changed by external contributors - * (either contractor or volunteer) which are listed in the file - * 'External-contributors' included in this distribution. - * - * info@inchi-trust.org - * -*/ - - -/* -Balanced Network Search - -Normalization related procedures -*/ - -#include -#include -#include - -#include "mode.h" -#include "ichitime.h" -#include "ichicant.h" -#include "ichierr.h" -#include "ichitaut.h" -#include "ichinorm.h" -#include "util.h" -#include "ichister.h" -#include "ichi_bns.h" - -#include "bcf_s.h" - -#include -#include "logging.h" /*(@nnuk : Nauman Ullah Khan) :: Needed for logging functionality*/ - -#define BNS_MARK_ONLY_BLOCKS 1 /* 1 => find only blocks, do not search for ring systems */ -#define ALLOW_ONLY_SIMPLE_ALT_PATH 0 /* 0 => allow alt. path to contain same bond 2 times (in opposite directions) */ -#define CHECK_TG_ALT_PATH 0 /* 1=> when chacking alt path of a tautomeric atom modify -t-group, not the atom */ -/* 0=> old mode */ - -#define FIX_CPOINT_BOND_CAP 1 /* 1=> fix bug in case of double bond from neutral cpoint */ -#define RESET_EDGE_FORBIDDEN_MASK 1 /* 1: previous; 0: do not apply "edge->forbidden &= pBNS->edge_forbidden_mask" */ -#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) -#define IS_FORBIDDEN(EDGE_FORBIDDEN, PBNS) (EDGE_FORBIDDEN) -#else -#define IS_FORBIDDEN(EDGE_FORBIDDEN, PBNS) (EDGE_FORBIDDEN & PBNS->edge_forbidden_mask) -#endif - - -typedef enum tagAtTypeTotals -{ - /* counts do not include: - charged atom adjacent to another charged atom - atom in an unusual valence state or adjacent to an atom in an unusual valence state - radicals different from singlet - */ - /*ATTOT_NUM_Plus. */ /* number of positive charges, +1, is (ATTOT_NUM_CHARGES + ATTOT_TOT_CHARGE)/2 */ - /*ATTOT_NUM_Minus.*/ /* number of negative charges, -1, is (ATTOT_NUM_CHARGES - ATTOT_TOT_CHARGE)/2 */ - ATTOT_NUM_NP_Plus, /* 0 no H: =N(+)=, #N(+)-, =N(+)<, does not include onium cations >P(+)<, >N(+)< */ - ATTOT_NUM_NP_Proton, /* 1 H(+): -NH3(+), =NH2(+), >NH2(+), =NH(+)-, >NH(+)-, #NH(+), N=N,P */ - ATTOT_NUM_NP_H, /* 2 H: -NH2, =NH, >NH -NH(-) */ - ATTOT_NUM_N_Minus, /* 3 (-): -NH(-), >N(-), =N(-) */ - ATTOT_NUM_NP, /* 4 no H: >N- =N-, #N */ - ATTOT_NUM_ON, /* 5 -N=O: do not allow -N=O => -NH-OH during H(+) add/removal */ - ATTOT_NUM_COH, /* 6 =C-OH, #C-OH; O=O,S,Se,Te */ - ATTOT_NUM_CSH, /* 7 -C-SH, -C-SeH -C-TeH */ - ATTOT_NUM_ZOH, /* 8 =Z-OH, #Z-OH; O=O,S,Se,Te; Z may have charge, Z != C */ - ATTOT_NUM_OOH, /* 9 -O-OH, O=O,S,Se,Te */ - ATTOT_NUM_ZOOH, /* 10 O=Z-OH, O=O,S,Se,Te */ - ATTOT_NUM_NOH, /* 11 =N-OH, -N(-)-OH */ - ATTOT_NUM_N_OH, /* 12 >N-OH, -NH-OH, >NH(+)-OH, -N(-)-OH */ - ATTOT_NUM_CO, /* 13 -C=O, =C=O; O=O,S,Se,Te */ - ATTOT_NUM_ZO, /* 14 -Z=O, =Z=O; O=O,S,Se,Te; Z may have charge */ - ATTOT_NUM_NO, /* 15 -N=O, =N(+)=O */ - ATTOT_NUM_N_O, /* 16 >N(+)=O, =N(+)=O */ - ATTOT_NUM_CO_Minus, /* 17 =C-O(-), #C-O(-); O=O,S,Se,Te */ - ATTOT_NUM_CS_Minus, /* 18 -C-S(-); S = S, Se, Te */ - ATTOT_NUM_ZO_Minus, /* 19 =Z-O(-), #Z-O(-); O = O, S, Se, Te */ - ATTOT_NUM_OO_Minus, /* 20 -O-O(-), O=O,S,Se,Te */ - ATTOT_NUM_ZOO_Minus, /* 21 O=Z-O(-), O=O,S,Se,Te */ - ATTOT_NUM_NO_Minus, /* 22 >N-O(-), -NH-O(-) */ - ATTOT_NUM_N_O_Minus, /* 23 -NH-O(-), >N-O(-); O = O, S, Se, Te */ - ATTOT_NUM_O_Minus, /* 24 -Z-O(-); O=O,S,Se,Te */ - ATTOT_NUM_OH_Plus, /* 25 any OH(+) */ - ATTOT_NUM_O_Plus, /* 26 any O(+) without H */ - ATTOT_NUM_Proton, /* 27 proton */ - ATTOT_NUM_HalAnion, /* 28 Halogen anion */ - ATTOT_NUM_HalAcid, /* 29 Halogen acid */ - ATTOT_NUM_Errors, /* 30 for debugging */ - ATTOT_TOT_CHARGE, /* 31 total of positive and negative single charges, +1 and -1 */ - ATTOT_NUM_CHARGES, /* 32 number of positive and negative single charges, +1 and -1 */ - ATTOT_ARRAY_LEN /* 33 array length */ -} AT_TYPE_TOTALS; - -#define ATBIT_NP_Plus (1 << ATTOT_NUM_NP_Plus) -#define ATBIT_NP_Proton (1 << ATTOT_NUM_NP_Proton) -#define ATBIT_NP_H (1 << ATTOT_NUM_NP_H) -#define ATBIT_N_Minus (1 << ATTOT_NUM_N_Minus) -#define ATBIT_NP (1 << ATTOT_NUM_NP) -#define ATBIT_ON (1 << ATTOT_NUM_ON) -#define ATBIT_COH (1 << ATTOT_NUM_COH) -#define ATBIT_CSH (1 << ATTOT_NUM_CSH) -#define ATBIT_ZOH (1 << ATTOT_NUM_ZOH) -#define ATBIT_OOH (1 << ATTOT_NUM_OOH) -#define ATBIT_ZOOH (1 << ATTOT_NUM_ZOOH) -#define ATBIT_NOH (1 << ATTOT_NUM_NOH) -#define ATBIT_N_OH (1 << ATTOT_NUM_N_OH) -#define ATBIT_CO (1 << ATTOT_NUM_CO) -#define ATBIT_ZO (1 << ATTOT_NUM_ZO) -#define ATBIT_NO (1 << ATTOT_NUM_NO) -#define ATBIT_N_O (1 << ATTOT_NUM_N_O) -#define ATBIT_CO_Minus (1 << ATTOT_NUM_CO_Minus) -#define ATBIT_CS_Minus (1 << ATTOT_NUM_CS_Minus) -#define ATBIT_ZO_Minus (1 << ATTOT_NUM_ZO_Minus) -#define ATBIT_OO_Minus (1 << ATTOT_NUM_OO_Minus) -#define ATBIT_ZOO_Minus (1 << ATTOT_NUM_ZOO_Minus) -#define ATBIT_NO_Minus (1 << ATTOT_NUM_NO_Minus) -#define ATBIT_N_O_Minus (1 << ATTOT_NUM_N_O_Minus) -#define ATBIT_O_Minus (1 << ATTOT_NUM_O_Minus) -#define ATBIT_OH_Plus (1 << ATTOT_NUM_OH_Plus) -#define ATBIT_O_Plus (1 << ATTOT_NUM_O_Plus) -#define ATBIT_Proton (1 << ATTOT_NUM_Proton) -#define ATBIT_HalAnion (1 << ATTOT_NUM_HalAnion) -#define ATBIT_HalAcid (1 << ATTOT_NUM_HalAcid) - - -#define ATBIT_Errors (1 << ATTOT_NUM_Errors) - -typedef struct tagProtonRemovalMaskAndType -{ - int typePos; /* atoms accessible to positive charges */ - int maskPos; - int typeNeg; /* atoms accessible to negative charges */ - int maskNeg; - int typeH; /* atoms accessible to hydrogen atoms */ - int maskH; -} PRMAT; - -#define PR_SIMPLE_MSK (ATBIT_NP_Proton | ATBIT_OH_Plus) -#define PR_SIMPLE_TYP (ATT_ATOM_N | ATT_ATOM_P | ATT_O_PLUS) - -#define ATBIT_MSK_NP (ATBIT_NP_Plus | ATBIT_NP_Proton | ATBIT_NP_H | ATBIT_N_Minus | ATBIT_NP) -#define KNOWN_ACIDIC_TYPE (ATT_ACIDIC_CO | ATT_ACIDIC_S | ATT_OO | ATT_ZOO | ATT_NO) -#define ATBIT_MSK_OS (ATBIT_COH | ATBIT_CSH | ATBIT_ZOH | ATBIT_OOH | ATBIT_ZOOH | ATBIT_NOH | ATBIT_N_OH |\ - ATBIT_CO | ATBIT_ZO | ATBIT_NO | ATBIT_N_O |\ - ATBIT_CO_Minus | ATBIT_CS_Minus | ATBIT_ZO_Minus | ATBIT_OO_Minus |\ - ATBIT_ZOO_Minus | ATBIT_NO_Minus | ATBIT_N_O_Minus /*| ATBIT_O_Minus*/ ) -#define ATBIT_MSK_H (ATBIT_NP_Proton | ATBIT_NP_H | ATBIT_COH | ATBIT_CSH | ATBIT_ZOH | ATBIT_OOH |\ - ATBIT_ZOOH | ATBIT_NOH | ATBIT_N_OH) - -#define ATTYP_OS (ATT_ACIDIC_CO | ATT_ACIDIC_S | ATT_OO | ATT_ZOO | ATT_NO /*| ATT_OTHER_NEG_O*/ | ATT_OTHER_ZO) -#define ATTYP_NP (ATT_ATOM_N | ATT_ATOM_P) -#define ATTYP_N (ATT_ATOM_N) -#define ATTYP_P (ATT_ATOM_P) - -/************* simple proton removal from acids **************************/ -#define AR_ANY_OH 0 /* 1 => create unknown to be acidic anions */ -#define AR_SIMPLE_STEPS 3 -/* acidic groups for proton removal, step 1 */ -#define AR_SIMPLE_MSK1 (ATBIT_COH | ATBIT_CSH | ATBIT_OOH | ATBIT_ZOOH | ATBIT_NOH | ATBIT_HalAcid) -#define AR_SIMPLE_TYP1 (ATT_ACIDIC_CO | ATT_ACIDIC_S | ATT_OO | ATT_ZOO | ATT_NO | ATT_HalAcid) -/* acidic groups for proton removal, step 2 */ -#define AR_SIMPLE_MSK2 (AR_ANY_OH? (ATBIT_N_OH) :0) -#define AR_SIMPLE_TYP2 (AR_ANY_OH? (ATT_N_O) :0) -/* acidic groups for proton removal, step 3 */ -#define AR_SIMPLE_MSK3 (AR_ANY_OH? (ATBIT_ZOH) :0) -#define AR_SIMPLE_TYP3 (AR_ANY_OH? (ATT_OTHER_ZO):0) - -/************* simple proton addition to acids **************************/ -#define AA_ANY_O_Minus 0 /* 1 => neutralize unknown to be acidic anions */ -#define AA_SIMPLE_STEPS 3 -/* acidic groups for proton addition, step 1 */ -#define AA_SIMPLE_MSK1 (ATBIT_CO_Minus | ATBIT_CS_Minus | ATBIT_OO_Minus | ATBIT_ZOO_Minus | ATBIT_NO_Minus | ATBIT_O_Minus | ATBIT_HalAnion) -#define AA_SIMPLE_TYP1 (ATT_ACIDIC_CO | ATT_ACIDIC_S | ATT_OO | ATT_ZOO | ATT_NO | ATT_OH_MINUS | ATT_HalAnion ) -/* acidic groups for proton addition, step 2 */ -#define AA_SIMPLE_MSK2 (AA_ANY_O_Minus? (ATBIT_N_O_Minus) :0) -#define AA_SIMPLE_TYP2 (AA_ANY_O_Minus? (ATT_N_O) :0) -/* acidic groups for proton addition, step 3 */ -#define AA_SIMPLE_MSK3 (AA_ANY_O_Minus? (ATBIT_ZO_Minus | ATBIT_O_Minus):0) -#define AA_SIMPLE_TYP3 (AA_ANY_O_Minus? (ATT_OTHER_ZO) :0) - -#if ( FIX_NP_MINUS_BUG == 1 ) -/* allow to add H(+) to =N(-) which previously was #N */ -#undef AA_SIMPLE_STEPS -#define AA_SIMPLE_STEPS 4 -#define AA_SIMPLE_MSK4 ATBIT_N_Minus -#define AA_SIMPLE_TYP4 ATT_NP_MINUS_V23 -#endif - -/************* hard proton removal from NP **************************/ -/* (+) charge group for proton removal: mask & type */ -#define PR_HARD_MSK_POS ATBIT_MSK_NP -#define PR_HARD_TYP_POS ATTYP_N -#define PR_HARD_TYP_POSP ATTYP_P -/* (-) charge group for proton removal */ -#define PR_HARD_MSK_NEG (ATBIT_MSK_NP | ATBIT_MSK_OS) -#define PR_HARD_TYP_NEG (ATTYP_N | ATTYP_OS) -/* H-group for proton removal */ -#define PR_HARD_MSK_H (ATBIT_MSK_NP | ATBIT_MSK_OS) -#define PR_HARD_TYP_H (ATTYP_N | ATTYP_OS) - -/************* hard proton removal from acids **************************/ -/* (+) charge group for proton removal: mask & type */ -#define AR_HARD_MSK_POS ATBIT_MSK_NP -#define AR_HARD_TYP_POS ATTYP_N -/* (-) charge group for proton removal */ -#define AR_HARD_MSK_NEG (ATBIT_MSK_NP | ATBIT_MSK_OS) -#define AR_HARD_TYP_NEG (ATTYP_N | ATTYP_OS) -/* H-group acid for proton removal */ -#define AR_HARD_MSK_HA (ATBIT_CO | ATBIT_NO ) -#define AR_HARD_TYP_HA (ATT_ACIDIC_CO | ATT_NO) -/* H-group non-acid for proton removal */ -#define AR_HARD_MSK_HN ((ATBIT_MSK_NP | ATBIT_MSK_OS) & ~AR_HARD_MSK_HA) -#define AR_HARD_TYP_HN ((ATTYP_N | ATTYP_OS) /*& ~AR_HARD_TYP_HA*/) - -/************* hard proton addition to acids **************************/ -/* (+) charge group for proton removal: mask & type */ -#define AA_HARD_MSK_POS ATBIT_MSK_NP -#define AA_HARD_TYP_POS ATTYP_N -/* (-) charge group for negative charge removal */ -#define AA_HARD_MSK_NEG ((ATBIT_MSK_NP | ATBIT_MSK_OS) & ~(ATBIT_CO | ATBIT_NO )) -#define AA_HARD_TYP_NEG (ATTYP_N | ATTYP_OS) -/* (-) charge group to accept negative charges */ -#define AA_HARD_MSK_CO (ATBIT_CO | ATBIT_NO ) -#define AA_HARD_TYP_CO (ATT_ACIDIC_CO | ATT_NO) -/* H-group non-acid for proton removal */ -#define AA_HARD_MSK_H (ATBIT_MSK_NP | ATBIT_MSK_OS) -#define AA_HARD_TYP_H (ATTYP_N | ATTYP_OS) - - -/*****************************************************************************/ -#define BNS_MAX_NUM_FLOW_CHANGES (1+2*MAX_BOND_EDGE_CAP) - -/* -- opiginal Pascal values -- -#define NO_VERTEX 0 -#define BLOSSOM_BASE -1 -#define FIRST_INDX 1 -*/ - -#define TREE_NOT_IN_M 0 /* not in T or T' */ -#define TREE_IN_2 1 /* in T' and not s-reachable */ -#define TREE_IN_2BLOSS 2 /* in T' and in a blossom, is s-reachable */ -#define TREE_IN_1 3 /* in T and is s-reachable */ - -#define TREE_IS_S_REACHABLE(X) (Tree[X] >= TREE_IN_2BLOSS) -#define TREE_IS_ON_SCANQ TREE_IS_S_REACHABLE -/* #define TREE_IS_ON_SCANQ(X) (Tree[X] != TREE_NOT_IN_M) */ -#define TREE_MARK(X, MARK) do{ if( Tree[X] < MARK ) Tree[X]=MARK; }while(0) - - -/***************************************************************************** -* store changes done to check whether an alternating path exists -* (see bSetBnsToCheckAltPath, bRestoreBnsAfterCheckAltPath) -******************************************************************************/ -typedef struct tagAltPathChanges -{ - /* caps changed in up to 2 vertices */ - VertexFlow nOldCapsVert[2][MAXVAL + 1]; - Vertex vOldVert[2]; - S_CHAR bSetOldCapsVert[2]; /* number of caps to restore, including st-cap */ - /* save ids of the newly created temporary vertices */ - Vertex vNewVertex[2]; - S_CHAR bSetNew[2]; /* indicators whether to remove vertices */ -} ALT_PATH_CHANGES; - - - -/*****************************************************************************/ - - -/* Local functions */ - -int RestoreRadicalsOnly( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at ); -int bRadChangesAtomType( BN_STRUCT *pBNS, BN_DATA *pBD, Vertex v, Vertex v_1, Vertex v_2 ); -int BnsAdjustFlowBondsRad( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at, int num_atoms ); -int SetAtomRadAndChemValFromVertexCapFlow( BN_STRUCT *pBNS, inp_ATOM *atom, int v1 ); -int bNeedToTestTheFlow( int bond_type, int nTestFlow, int bTestForNonStereoBond ); -int RestoreEdgeFlow( BNS_EDGE *edge, int delta, int bChangeFlow ); -int SetAtomBondType( BNS_EDGE *edge, U_CHAR *bond_type12, U_CHAR *bond_type21, int delta, int bChangeFlow ); -int RestoreBnStructFlow( BN_STRUCT *pBNS, int bChangeFlow ); -int CompTGroupNumber( const void *tg1, const void *tg2, void *p ); -int CompCGroupNumber( const void *cg1, const void *cg2, void *p ); - -/* Rings, Blocks, Non-stereo bonds */ -int ReInitBnStructForAltBns( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, int bUnknAltAsNoStereo ); -int MarkRingSystemsAltBns( BN_STRUCT* pBNS, int bUnknAltAsNoStereo ); -int MarkNonStereoAltBns( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, int bUnknAltAsNoStereo ); - -/* Called from BalancedNetworkSearch */ -int GetVertexDegree( BN_STRUCT* pBNS, Vertex v ); -/* Vertex Get2ndNeighbor1( BN_STRUCT* pBNS, Vertex u, EdgeIndex iedge ); not used */ -Vertex Get2ndEdgeVertex( BN_STRUCT* pBNS, Edge uv ); -Vertex GetVertexNeighbor( BN_STRUCT* pBNS, Vertex v, int neigh, EdgeIndex *iedge ); -int GetEdgePointer( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv, BNS_EDGE **uv, S_CHAR *s_or_t ); -int AugmentEdge( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv, int delta, S_CHAR bReverse, int bChangeFlow ); -int rescap_mark( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv ); -int rescap( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv ); -Vertex FindBase( Vertex u, Vertex *BasePtr ); -int FindPathToVertex_s( Vertex x, Edge *SwitchEdge, Vertex *BasePtr, Vertex *Path, int MaxPathLen ); -Vertex MakeBlossom( BN_STRUCT* pBNS, Vertex *ScanQ, int *pQSize, - Vertex *Pu, Vertex *Pv, int max_len_Pu_Pv, - Edge *SwitchEdge, Vertex *BasePtr, - Vertex u, Vertex v, EdgeIndex iuv, Vertex b_u, Vertex b_v, S_CHAR *Tree ); -int PullFlow( BN_STRUCT *pBNS, Edge *SwitchEdge, Vertex x, Vertex y, int delta, S_CHAR bReverse, int bChangeFlow ); -int FindPathCap( BN_STRUCT* pBNS, Edge *SwitchEdge, Vertex x, Vertex y, int delta ); - -/* -int SetBondType( BNS_EDGE *edge, U_CHAR *bond_type12, U_CHAR *bond_type21, int delta, int bChangeFlow ); -int SetBondsRestoreBnStructFlow( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, int bChangeFlow ); -*/ -int SetBondsFromBnStructFlow( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, int bChangeFlow0 ); -int MarkAtomsAtTautGroups( BN_STRUCT *pBNS, int num_atoms, BN_AATG *pAATG, int nEnd1, int nEnd2 ); - -int nMinFlow2Check( BN_STRUCT *pBNS, int iedge ); -int nMaxFlow2Check( BN_STRUCT *pBNS, int iedge ); -int nCurFlow2Check( BN_STRUCT *pBNS, int iedge ); - -/* Bonds testing */ -/* -int bRestoreFlowToCheckOneBond( BN_STRUCT *pBNS, BNS_FLOW_CHANGES *fcd, int nTestFlow, inp_ATOM *at, int num_atoms, int bChangeFlow ); -*/ -int bSetFlowToCheckOneBond( BN_STRUCT *pBNS, int iedge, int flow, BNS_FLOW_CHANGES *fcd ); -int bRestoreFlowAfterCheckOneBond( BN_STRUCT *pBNS, BNS_FLOW_CHANGES *fcd ); -int bSetBondsAfterCheckOneBond( BN_STRUCT *pBNS, BNS_FLOW_CHANGES *fcd, int nTestFlow, inp_ATOM *at, int num_atoms, int bChangeFlow ); -int BnsTestAndMarkAltBonds( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at, int num_atoms, BNS_FLOW_CHANGES *fcd, int bChangeFlow, int nBondTypeToTest ); -/* -int bIsAltBond(int bond_type); -- djb-rwth: function definition not found -*/ - -/* Fix bonds */ -int fix_special_bonds( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, int edge_forbidden_mask ); -int TempFix_NH_NH_Bonds( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms ); -int CorrectFixing_NH_NH_Bonds( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms ); -int fix_explicitly_indicated_bonds( int nebend, int *ebend, BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms ); - -/* Alt path testing */ -int bSetBnsToCheckAltPath( BN_STRUCT *pBNS, int nVertDoubleBond, int nVertSingleBond, AT_NUMB type, - int path_type, ALT_PATH_CHANGES *apc, BNS_FLOW_CHANGES *fcd, int *nDots ); -int bRestoreBnsAfterCheckAltPath( BN_STRUCT *pBNS, ALT_PATH_CHANGES *apc, int bChangeFlow ); -Vertex GetGroupVertex( BN_STRUCT *pBNS, Vertex v1, AT_NUMB type ); -BNS_IEDGE GetEdgeToGroupVertex( BN_STRUCT *pBNS, Vertex v1, AT_NUMB type ); -int bAddNewVertex( BN_STRUCT *pBNS, int nVertDoubleBond, int nCap, int nFlow, int nMaxAdjEdges, int *nDots ); -int AddNewEdge( BNS_VERTEX *p1, BNS_VERTEX *p2, BN_STRUCT *pBNS, int nEdgeCap, int nEdgeFlow ); -int bAddStCapToAVertex( BN_STRUCT *pBNS, Vertex v1, Vertex v2, VertexFlow *nOldCapVertSingleBond, int *nDots, int bAdjacentDonors ); - -static void remove_alt_bond_marks( inp_ATOM *at, int num_atoms ); -int bIsBnsEndpoint( BN_STRUCT *pBNS, int v ); - -/* Protons removal, charge neutralization */ -/* int is_acidic_CO(inp_ATOM* atom, int at_no); */ /* djb-rwth: function definition not found*/ -int mark_at_type( inp_ATOM *atom, int num_atoms, int nAtTypeTotals[] ); -int GetAtomChargeType( inp_ATOM *atom, int at_no, int nAtTypeTotals[], int *pMask, int bSubtract ); -int AddChangedAtHChargeBNS( inp_ATOM *at, int num_atoms, int nAtTypeTotals[], S_CHAR *mark ); -int EliminatePlusMinusChargeAmbiguity( BN_STRUCT *pBNS, int num_atoms ); -int AddOrRemoveExplOrImplH( int nDelta, inp_ATOM *at, int num_atoms, AT_NUMB at_no, T_GROUP_INFO *t_group_info ); -int SubtractOrChangeAtHChargeBNS( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, - int nAtTypeTotals[], S_CHAR *mark, T_GROUP_INFO *t_group_info, int bSubtract ); -int is_Z_atom( U_CHAR el_number ); -int IsZOX( inp_ATOM *atom, int at_x, int ord ); -int SimpleRemoveHplusNPO( inp_ATOM *at, int num_atoms, int nAtTypeTotals[], T_GROUP_INFO *t_group_info ); -int CreateCGroupInBnStruct( inp_ATOM *at, int num_atoms, - BN_STRUCT *pBNS, int nType, int nMask, int nCharge ); -int CreateTGroupInBnStruct( inp_ATOM *at, int num_atoms, - BN_STRUCT *pBNS, int nType, int nMask ); -int RemoveLastGroupFromBnStruct( inp_ATOM *at, int num_atoms, int tg, BN_STRUCT *pBNS ); -int SetInitCapFlowToCurrent( BN_STRUCT *pBNS ); -int SimpleRemoveAcidicProtons( inp_ATOM *at, int num_atoms, BN_AATG *pAATG, int num2remove ); -int SimpleAddAcidicProtons( inp_ATOM *at, int num_atoms, BN_AATG *pAATG, int num2add ); -int HardRemoveAcidicProtons( struct tagCANON_GLOBALS *pCG, inp_ATOM *at, int num_atoms, BN_AATG *pAATG, int num2remove, - int *nNumCanceledCharges, BN_STRUCT *pBNS, BN_DATA *pBD ); -int HardAddAcidicProtons( struct tagCANON_GLOBALS *pCG, inp_ATOM *at, int num_atoms, BN_AATG *pAATG, int num2add, - int *nNumCanceledCharges, BN_STRUCT *pBNS, BN_DATA *pBD ); -int HardRemoveHplusNP( struct tagCANON_GLOBALS *pCG, inp_ATOM *at, int num_atoms, int bCancelChargesAlways, int *nNumCanceledCharges, - BN_AATG *pAATG, BN_STRUCT *pBNS, BN_DATA *pBD ); -int RemoveNPProtonsAndAcidCharges( struct tagCANON_GLOBALS *pCG, inp_ATOM *at, int num_atoms, BN_AATG *pAATG, BN_STRUCT *pBNS, BN_DATA *pBD ); -Vertex GetPrevVertex( BN_STRUCT* pBNS, Vertex y, Edge *SwitchEdge, EdgeIndex *iuv ); -int bIgnoreVertexNonTACN_atom( BN_STRUCT* pBNS, Vertex u, Vertex v ); -int bIgnoreVertexNonTACN_group( BN_STRUCT* pBNS, Vertex v, Vertex w, Edge *SwitchEdge ); -int bIsRemovedHfromNHaion( BN_STRUCT* pBNS, Vertex u, Vertex v ); -int bIsAggressiveDeprotonation( BN_STRUCT* pBNS, Vertex v, Vertex w, Edge *SwitchEdge ); - -int bIsAtomTypeHard( inp_ATOM *at, int endpoint, int nType, int nMask, int nCharge ); -int bIsHDonorAccAtomType( inp_ATOM *at, int endpoint, int *cSubType ); -int bIsNegAtomType( inp_ATOM *at, int i, int *cSubType ); - -#if ( BNS_RAD_SEARCH == 1 ) -int RegisterRadEndpoint( BN_STRUCT *pBNS, BN_DATA *pBD, Vertex u ); -int cmp_rad_endpoints( const void *a1, const void *a2 ); -int cmp_endpoints_rad( const void *a1, const void *a2 ); -#endif - -int bHasChargedNeighbor( inp_ATOM *at, int iat ); -/*****************************************************************************/ -/**** prim(v) is v' *****/ -#define prim(v) (Vertex)((v)^1) - -/*****************************************************************************/ -#define SwitchEdge_Vert1(u) SwitchEdge[u][0] -#define SwitchEdge_Vert2(u) Get2ndEdgeVertex( pBNS, SwitchEdge[u] ) -#define SwitchEdge_IEdge(u) SwitchEdge[u][1] -/*****************************************************************************/ - - - - - -/**************************************************************************** -Returns value > 0 if a bond has been changed -****************************************************************************/ -int RestoreEdgeFlow( BNS_EDGE *edge, int delta, int bChangeFlow ) -{ - /*flow1 = edge->flow;*/ /* output from BNS */ - switch (bChangeFlow & BNS_EF_CHNG_RSTR) - { - case 0: - /* the flow has not been permitted to change inside the BNS */ - /* nothing to do */ - /*flow1 = edge->flow;*/ /* output from BNS, the original flow value */ - /*flow2 = flow1 + delta;*/ /* the flow would be changed to this value by the BNS if permitted */ - break; - case BNS_EF_CHNG_FLOW: - /* the flow has been changed by the BNS; update flow0 */ - /*flow2 = edge->flow;*/ /* output from BNS, the changed value */ - /*flow1 = flow2 - delta;*/ /* the original flow value before the BNS */ - edge->flow0 = edge->flow; /* SAVE NEW EDGE FLOW AS THE INITIAL FLOW FROM CHEM. BONDS */ - break; - case BNS_EF_CHNG_RSTR: - /* the flow has been changed by the BNS; requested to change it back */ - /*flow2 = edge->flow;*/ /* output from BNS, the changed value */ - /*flow1 = flow2 - delta;*/ /* the original flow value before the BNS */ - edge->flow = edge->flow - delta; /* CHANGE EDGE FLOW BACK (RESTORE) */ - break; - case BNS_EF_RSTR_FLOW: - /* the flow has not been permitted to change inside the BNS */ - /* nothing to do */ - /*flow1 = edge->flow;*/ /* output from BNS, the original flow value */ - /*flow2 = flow1 + delta;*/ /* the flow would be changed to this value by the BNS if permitted */ - break; - } - - return 0; -} - - -/**************************************************************************** -Returns value > 0 if a bond has been changed; do not change flow -****************************************************************************/ -int SetAtomBondType( BNS_EDGE *edge, - U_CHAR *bond_type12, - U_CHAR *bond_type21, - int delta, - int bChangeFlow ) -{ - int flow1, flow2, tmp, ret = 0; - int bond_mark = 0, bond_type, new_bond_type; /* djb-rwth: addressing LLVM warning */ - - if (!edge->pass || !bond_type21) - { - return 0; - } - - switch (bChangeFlow & BNS_EF_CHNG_RSTR) - { - case 0: /* the flow has not been permitted to change inside the BNS: simulated in case of check one bond */ - case BNS_EF_RSTR_FLOW: /* the flow has not been permitted to change inside the BNS: obsolete mode, unexpected bChangeFlow */ - flow1 = edge->flow0; /* output from BNS, the original (old) flow value */ - flow2 = flow1 + delta; /* the flow would be changed to this value by the BNS if permitted */ - break; - case BNS_EF_CHNG_FLOW: /* the flow has been changed by the BNS */ - case BNS_EF_CHNG_RSTR: /* the flow has been changed by the BNS; requested to change it back */ - flow2 = edge->flow; /* output from BNS, the changed (new) value */ - flow1 = edge->flow0; /* the original flow (old) value before the BNS */ - break; - default: - return 0; /* added 2006-03-21 */ - } - - if (( bChangeFlow & BNS_EF_CHNG_BONDS ) && ( bChangeFlow & BNS_EF_ALTR_NS ) != BNS_EF_ALTR_NS) - { - /* Set new bond types according to the new flow values */ - new_bond_type = flow2 + BOND_SINGLE; - if (*bond_type12 != new_bond_type) - { - *bond_type12 = *bond_type21 = new_bond_type; - ret++; - } - } - else - { - if (bChangeFlow & BNS_EF_ALTR_BONDS) - { - if (flow1 == flow2) - { - goto exit_function; - } - /* Update alternating bond information */ - if (flow1 > flow2) - { - /* Make sure flow2 > flow1 */ - tmp = flow1; - flow1 = flow2; - flow2 = tmp; - } - /* djb-rwth: removing redundant code */ - switch (bond_type = ( *bond_type12 & BOND_TYPE_MASK )) - { - case BOND_SINGLE: - case BOND_DOUBLE: - case BOND_TRIPLE: - /* assume that the input bond type fits either flow1 or flow2 */ - if (flow1 == 0 && flow2 == 1) - { - if (bChangeFlow & BNS_EF_SET_NOSTEREO) - { - bond_mark = BOND_MARK_ALT12NS; - bond_type = BOND_ALT12NS; - } - else - { - bond_mark = BOND_MARK_ALT12; - bond_type = BOND_ALTERN; - } - } - else - { - if (flow1 == 0 && flow2 == 2) - { - bond_mark = BOND_MARK_ALT13; - bond_type = BOND_ALT_13; - } - else - { - if (flow1 == 1 && flow2 == 2) - { - bond_mark = BOND_MARK_ALT23; - bond_type = BOND_ALT_23; - } - else - { - return BNS_BOND_ERR; /* error */ - } - } - } - break; - case BOND_TAUTOM: - if (flow1 == 0 && flow2 == 1) - { - bond_mark = BOND_MARK_ALT12NS; - } - else - if (flow1 == 1 && flow2 == 2) { - bond_mark = BOND_MARK_ALT23; - } - else { - return BNS_BOND_ERR; /* error */ - } - break; - default: - new_bond_type = bond_type; - bond_mark = ( *bond_type12 & BOND_MARK_MASK ); - switch (bond_mark) - { - case BOND_MARK_ALT12: - if (( bChangeFlow & BNS_EF_SET_NOSTEREO ) && flow1 == 0 && flow2 == 1) - { - bond_mark = BOND_MARK_ALT12NS; - new_bond_type = BOND_ALT12NS; - break; - } - case BOND_MARK_ALT12NS: - if (flow1 == 2 || flow2 == 2) - { - bond_mark = BOND_MARK_ALT123; - new_bond_type = BOND_ALT_123; - } - break; - case BOND_MARK_ALT13: - if (flow1 == 1 || flow2 == 1) - { - bond_mark = BOND_MARK_ALT123; - new_bond_type = BOND_ALT_123; - } - break; - case BOND_MARK_ALT23: - if (flow1 == 0 || flow2 == 0) - { - bond_mark = BOND_MARK_ALT123; - new_bond_type = BOND_ALT_123; - } - break; - case BOND_MARK_ALT123: - break; - - case 0: /* special case: second alt bond testing */ - if (flow1 == 0 && flow2 == 1) - { - bond_mark = BOND_MARK_ALT12; - } - else - { - if (flow1 == 0 && flow2 == 2) - { - bond_mark = BOND_MARK_ALT13; - } - else - { - if (flow1 == 1 && flow2 == 2) - { - bond_mark = BOND_MARK_ALT23; - } - else - { - return BNS_BOND_ERR; /* error */ - } - } - } - break; - - default: - return BNS_BOND_ERR; /* error */ - } - - switch (bond_type) - { - case BOND_TAUTOM: - break; - case BOND_ALTERN: - case BOND_ALT12NS: - case BOND_ALT_123: - case BOND_ALT_13: - case BOND_ALT_23: - bond_type = new_bond_type; - break; - default: - return BNS_BOND_ERR; /* error */ - } - } - - new_bond_type = bond_type | bond_mark; - if (new_bond_type != *bond_type12) - { - *bond_type12 = *bond_type21 = new_bond_type; - ret++; - } - } - } - -exit_function: - - return ret; -} - - -/**************************************************************************** -Run BalancedNetworkSearch( ... ) until no aug pass is found -****************************************************************************/ -int RunBalancedNetworkSearch( BN_STRUCT *pBNS, BN_DATA *pBD, int bChangeFlow ) -{ - int pass, delta = 0, nSumDelta; - - nSumDelta = 0; - for (pass = 0; pass < pBNS->max_altp; pass++) - { - pBNS->alt_path = pBNS->altp[pass]; - pBNS->bChangeFlow = 0; - delta = BalancedNetworkSearch( pBNS, pBD, bChangeFlow ); - ReInitBnData( pBD ); - if (0 < delta) - { - pBNS->num_altp++; - nSumDelta += abs( delta ); - } - else - { - break; - } - } - - if (IS_BNS_ERROR( delta )) - { - return delta; - } - - if (bInchiTimeIsOver( pBNS->ic, pBNS->ulTimeOutTime )) - { - return BNS_TIMEOUT; - } - - return nSumDelta; /* number of eliminated pairs of "dots" */ -} - - -/****************************************************************************/ -int SetAtomRadAndChemValFromVertexCapFlow( BN_STRUCT *pBNS, - inp_ATOM *atom, - int v1 ) -{ - BNS_VERTEX *vert = pBNS->vert + v1; - inp_ATOM *at = atom + v1; - S_CHAR cValue; - int nChanges = 0; - - /* Set only on the 1st pass */ - if (!vert->st_edge.pass) - { - return 0; - } - - /* Adjust chem_bonds_valence */ - cValue = at->chem_bonds_valence - at->valence; - if (cValue >= 0 && cValue != vert->st_edge.flow) - { - at->chem_bonds_valence = at->valence + vert->st_edge.flow; - nChanges++; - } - - /* Adjist radical */ - switch (vert->st_edge.cap - vert->st_edge.flow) - { - case 0: - cValue = 0; - break; - case 1: - cValue = RADICAL_DOUBLET; - break; - case 2: - cValue = RADICAL_TRIPLET; - break; - default: - return BNS_BOND_ERR; - } - if (cValue != at->radical) - { - at->radical = cValue; - nChanges++; - } - - return nChanges; -} - - -/****************************************************************************/ -int AddChangedAtHChargeBNS( inp_ATOM *at, - int num_atoms, - int nAtTypeTotals[], - S_CHAR *mark ) -{ - int i, mask, num; - for (i = 0, num = 0; i < num_atoms; i++) - { - if (mark[i]) - { - mark[i] = 0; -#if ( FIX_NORM_BUG_ADD_ION_PAIR == 1 ) - /* add ignoring adjacent charges */ - at[i].at_type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, -2 ); -#else - at[i].at_type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); -#endif - num++; - } - } - - return num; -} - - -/**************************************************************************** -Eliminate neutral representation ambiguity: - -replace (+)--N==(-) with (+)==N--(-) - -here (+) is positive charge group, -(-) is negative charge group, N is N or P -This reduces possibility of creating ion pair -OH => -O(+) + H(+) -instead of removing H(+) from N or P - -!Call this function after alt path was found and new flows have been set. -****************************************************************************/ -int EliminatePlusMinusChargeAmbiguity( BN_STRUCT *pBNS, int num_atoms ) -{ - int pass, i, v0, v1, v2, ineigh1, /*ineigh0,*/ /*ineigh2,*/ - vLast, n, delta, ret, err = 0; - int nFound, k; - BNS_EDGE *edge; - - for (pass = pBNS->num_altp - 1, ret = 0; 0 <= pass; pass--) - { - - pBNS->alt_path = pBNS->altp[pass]; - v1 = ALTP_START_ATOM( pBNS->alt_path ); - n = ALTP_PATH_LEN( pBNS->alt_path ); - delta = ALTP_DELTA( pBNS->alt_path ); - vLast = ALTP_END_ATOM( pBNS->alt_path ); - v0 = v2 = NO_VERTEX; /* negative number */ - - for (i = 0; i < n; i++, delta = -delta, v0 = v1, v1 = v2 /*, ineigh0 = ineigh1*/) - { - ineigh1 = ALTP_THIS_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v1->v2 neighbor */ - /*ineigh2 = ALTP_NEXT_ATOM_NEIGHBOR(pBNS->alt_path, i);*/ /* v2->v1 neighbor */ - edge = pBNS->edge + pBNS->vert[v1].iedge[ineigh1]; - /* follow the BN Structure, not the inp_ATOM, to take care of swithching to - t-groups, c-groups or other fictitious edges/vertices - */ - v2 = edge->neighbor12 ^ v1; - if (v1 < num_atoms && - ( (v0 >= num_atoms && ( pBNS->vert[v0].type & BNS_VERT_TYPE_C_GROUP )) || - (v2 >= num_atoms && ( pBNS->vert[v2].type & BNS_VERT_TYPE_C_GROUP ) ))) /* djb-rwth: addressing LLVM warning */ - { - int cgPos = 0, cgNeg = 0; - int neighPos = -1, neighNeg = -1; - BNS_EDGE *edgePos, *edgeNeg; - nFound = 0; - for (k = pBNS->vert[v1].num_adj_edges - 1; k >= 0 && ( neighPos < 0 || neighNeg < 0 ); k--) - { - BNS_EDGE *next_edge = pBNS->edge + pBNS->vert[v1].iedge[k]; - int v = next_edge->neighbor12 ^ v1; - if (pBNS->vert[v].type & BNS_VERT_TYPE_C_GROUP) - { - if (pBNS->vert[v].type & BNS_VERT_TYPE_C_NEGATIVE) - { - cgNeg = v; - neighNeg = k; - nFound++; - } - else - { - cgPos = v; - neighPos = k; - nFound++; - } - } - } - if (2 == nFound && neighPos >= 0 && neighNeg >= 0) - { - /* both c-groups have been found */ - edgePos = pBNS->edge + pBNS->vert[v1].iedge[neighPos]; - edgeNeg = pBNS->edge + pBNS->vert[v1].iedge[neighNeg]; - if (edgePos->flow < edgeNeg->flow) - { - /* ambiguity found; replace (+cg)--N==(-cg) with (+cg)==N--(-cg) */ - int dflow = edgeNeg->flow - edgePos->flow; - - edgePos->flow += dflow; - pBNS->vert[cgPos].st_edge.cap += dflow; - pBNS->vert[cgPos].st_edge.flow += dflow; - - edgeNeg->flow -= dflow; - pBNS->vert[cgNeg].st_edge.cap -= dflow; - pBNS->vert[cgNeg].st_edge.flow -= dflow; - ret++; - } - } - } - } - - if (v2 != vLast) - { - err = BNS_PROGRAM_ERR; - } - } - - return err ? err : ret; -} - - -/**************************************************************************** -Add or remove ixplicit or implicit hydrogens -****************************************************************************/ -int AddOrRemoveExplOrImplH( int nDelta, - inp_ATOM *at, - int num_atoms, - AT_NUMB at_no, - T_GROUP_INFO *t_group_info ) -{ - int i, iso, tot_num_iso_H, - num_H, /* number of H before the removal, including explicit H */ - nNum2Remove, /* number of H to remove */ - nNumRemovedExplicitH; /* djb-rwth: removing redundant variables */ - S_CHAR num_iso_H[NUM_H_ISOTOPES]; - inp_ATOM *at_H; - - if (!nDelta) - { - return 0; - } - /* add */ - if (nDelta > 0) - { - at[at_no].num_H += nDelta; - t_group_info->tni.nNumRemovedProtons--; - return nDelta; - } - /* remove */ - nNum2Remove = -nDelta; - nNumRemovedExplicitH = t_group_info->tni.nNumRemovedExplicitH; /* number of explicit H saved separately in - at[num_atoms+i], i=0..nNumRemovedExplicitH-1 */ - tot_num_iso_H = NUM_ISO_H( at, at_no ); - num_H = at[at_no].num_H; - /* - tot_num_iso_H = NUM_ISO_H(at,at_no); - num_H = at[at_no].num_H; - nNumAtomExplicitH = 0; - nNumRemovedExplicitH = t_group_info->tni.nNumRemovedExplicitH; - tot_num_explicit_iso_H = 0; - */ - - at_H = at + num_atoms; - memcpy(num_iso_H, at[at_no].num_iso_H, sizeof(num_iso_H)); - /* Remove all explicit H, otherwise a false stereo can occur. - Example: remove H(+) from the following substructure: - - H H - A / A / - >X==N(+) produces false stereogenic bond: >X==N - B \ B - H - - To avoid this effect all explicit H atoms must be removed - */ - - /* djb-rwth: removing redundant code */ - for (i = 0; i < nNumRemovedExplicitH; ) - { - if (at_H[i].neighbor[0] == at_no) - { - int m, k, orig_no = at_H[i].orig_at_number; - nNumRemovedExplicitH--; - /* djb-rwth: removing redundant code */ - if (nNumRemovedExplicitH > i) - { - inp_ATOM at_i = at_H[i]; - memmove(at_H + i, at_H + i + 1, sizeof(at_H[0]) * ((long long)nNumRemovedExplicitH - i)); /* djb-rwth: cast operator added */ - at_H[nNumRemovedExplicitH] = at_i; /* save removed H (for debugging purposes?) */ - } - /* Adjust 0D parities */ - if (at[at_no].sb_parity[0]) - { - for (m = 0; m < MAX_NUM_STEREO_BONDS && at[at_no].sb_parity[m]; m++) - { - if (at[at_no].sn_orig_at_num[m] == orig_no) - { - if (at[at_no].valence >= MIN_NUM_STEREO_BOND_NEIGH) - { - at[at_no].sn_ord[m] = k = ( at[at_no].sb_ord[m] == 0 ); - at[at_no].sn_orig_at_num[m] = at[(int) at[at_no].neighbor[k]].orig_at_number; - if (ATOM_PARITY_WELL_DEF( at[at_no].sb_parity[m] )) - { - at[at_no].sb_parity[m] = 3 - at[at_no].sb_parity[m]; - } - } - else - { - at[at_no].sn_ord[m] = -99; /* no sb neighbor exists anymore */ - at[at_no].sn_orig_at_num[m] = 0; - if (ATOM_PARITY_WELL_DEF( at[at_no].sb_parity[m] )) - { - int pnxt_atom, pinxt2cur, pinxt_sb_parity_ord; - if (0 < get_opposite_sb_atom( at, at_no, at[at_no].sb_ord[m], - &pnxt_atom, &pinxt2cur, &pinxt_sb_parity_ord )) - { - at[at_no].sb_parity[m] = - at[pnxt_atom].sb_parity[pinxt_sb_parity_ord] = AB_PARITY_UNDF; - } - } - } - } - } - } - /* do not increment i here: we have shifted next at_H[] element - to the ith position and decremented nNumRemovedExplicitH */ - } - else - { - i++; - } - } - - for (iso = -1; iso < NUM_H_ISOTOPES && 0 < nNum2Remove; iso++) - { - /* Each pass removes up to one H */ - if (iso < 0) - { - /* Try to remove non-isotopic */ - while (tot_num_iso_H < num_H && 0 < nNum2Remove) - { - /* Non-isotopic H exists */ - num_H--; - t_group_info->tni.nNumRemovedProtons++; - nNum2Remove--; - } - } - else - { - /* Remove isotopic */ - while (num_iso_H[iso] && num_H && 0 < nNum2Remove) - { - /* Isotopic H exists */ - num_H--; - num_iso_H[iso] --; - t_group_info->tni.nNumRemovedProtonsIsotopic[iso] ++; - t_group_info->tni.nNumRemovedProtons++; - nNum2Remove--; - } - } - } -#if ( bRELEASE_VERSION != 1 ) - if (nNum2Remove) - { - int stop = 1; /* Program error */ - } -#endif - if (nDelta + nNum2Remove < 0) - { - at[at_no].num_H = num_H; - memcpy(at[at_no].num_iso_H, num_iso_H, sizeof(at[0].num_iso_H)); - t_group_info->tni.nNumRemovedExplicitH = nNumRemovedExplicitH; - } - - return nDelta + nNum2Remove; -} - - -/****************************************************************************/ -int SubtractOrChangeAtHChargeBNS( BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - int nAtTypeTotals[], - S_CHAR *mark, - T_GROUP_INFO *t_group_info, - int bSubtract ) -{ - int pass, i, v0, v1, v2, ineigh1, /*ineigh2,*/ vLast, n, delta, ret, err = 0; - BNS_EDGE *edge; - int nDeltaH, nDeltaCharge; - int mask, type; /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - - for (pass = pBNS->num_altp - 1, ret = 0; 0 <= pass; pass--) - { - - pBNS->alt_path = pBNS->altp[pass]; - v1 = ALTP_START_ATOM( pBNS->alt_path ); - n = ALTP_PATH_LEN( pBNS->alt_path ); - delta = ALTP_DELTA( pBNS->alt_path ); - vLast = ALTP_END_ATOM( pBNS->alt_path ); - v0 = v2 = NO_VERTEX; - - for (i = 0; i < n; i++, delta = -delta, v0 = v1, v1 = v2) - { - ineigh1 = ALTP_THIS_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v1->v2 neighbor */ - /*ineigh2 = ALTP_NEXT_ATOM_NEIGHBOR(pBNS->alt_path, i);*/ /* v2->v1 neighbor */ - edge = pBNS->edge + pBNS->vert[v1].iedge[ineigh1]; - /* follow the BN Structure, not the inp_ATOM, to take care of swithching to - t-groups, c-groups or other fictitious edges/vertices - */ - v2 = edge->neighbor12 ^ v1; - if (v1 < num_atoms && ( v0 >= num_atoms || v2 >= num_atoms )) - { - nDeltaH = nDeltaCharge = 0; - if (v0 >= num_atoms) - { - /* delta(v0-v1) = -delta(v1-v2) along the alternating path */ - if (pBNS->vert[v0].type & BNS_VERT_TYPE_TGROUP) - { - nDeltaH -= delta; - } - else - { - if (pBNS->vert[v0].type & BNS_VERT_TYPE_C_GROUP) - { - nDeltaCharge += delta; - } - } - } - if (v2 >= num_atoms) - { - if (pBNS->vert[v2].type & BNS_VERT_TYPE_TGROUP) - { - nDeltaH += delta; - } - else - { - if (pBNS->vert[v2].type & BNS_VERT_TYPE_C_GROUP) - { - nDeltaCharge -= delta; - } - } - } - if (nDeltaH || nDeltaCharge) - { - if (bSubtract) - { - if (!mark[v1]) - { - /* first time the atom has been encountered: subtract */ - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ -#if ( FIX_NORM_BUG_ADD_ION_PAIR == 1 ) - type = GetAtomChargeType(at, v1, nAtTypeTotals, &mask, 2); -#else - type = GetAtomChargeType(at, v1, nAtTypeTotals, &mask, 1); -#endif - ret++; /* number of changed atoms */ - mark[v1] ++; - } - } - else - { - /* Change */ - at[v1].charge += nDeltaCharge; - if (nDeltaH) - { - AddOrRemoveExplOrImplH( nDeltaH, at, num_atoms, (AT_NUMB) v1, t_group_info ); - } - ret++; /* number of changed atoms */ - } - } - } - } - - if (v2 != vLast) - { - err = BNS_PROGRAM_ERR; - } - } - - return err ? err : ret; -} - - -/**************************************************************************** -Set Bonds From BnS Struct Flow -****************************************************************************/ -int SetBondsFromBnStructFlow( BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - int bChangeFlow0 ) -{ - int pass, i, v0, v1, v2, ineigh1, ineigh2, vLast, n, delta, ret, ret_val, err = 0; - BNS_EDGE *edge; - int bChangeFlowAdd; /* djb-rwth: removing redundant variables */ - int bChangeFlow = ( bChangeFlow0 & ~BNS_EF_SET_NOSTEREO ); - /* - bCheckMovingRad = (bChangeFlow & BNS_EF_ALTR_NS) == BNS_EF_ALTR_NS && - pBNS->tot_st_cap > pBNS->tot_st_flow; - */ - for (pass = pBNS->num_altp - 1, ret = 0; 0 <= pass; pass--) - { - pBNS->alt_path = pBNS->altp[pass]; - v1 = ALTP_START_ATOM( pBNS->alt_path ); - n = ALTP_PATH_LEN( pBNS->alt_path ); - delta = ALTP_DELTA( pBNS->alt_path ); - vLast = ALTP_END_ATOM( pBNS->alt_path ); - if (( bChangeFlow0 & BNS_EF_SET_NOSTEREO ) && - ( pBNS->vert[v1].st_edge.cap0 > pBNS->vert[v1].st_edge.flow0 || - pBNS->vert[vLast].st_edge.cap0 > pBNS->vert[vLast].st_edge.flow0 )) - { - /* djb-rwth: removing redundant code */ - bChangeFlowAdd = BNS_EF_SET_NOSTEREO; - ret |= 2; - } - else - { - bChangeFlowAdd = 0; - } - /* start vertex */ - if (( bChangeFlow & BNS_EF_CHNG_RSTR ) == BNS_EF_CHNG_RSTR) - { - /* Restore s-v1 edge flow to the BNS this pass input value */ - ; /*pBNS->vert[v1].st_edge.flow -= delta;*/ - } - else - { - if (( bChangeFlow & BNS_EF_SAVE_ALL ) == BNS_EF_SAVE_ALL) - { - if (v1 < num_atoms) - { - /* Will produce wrong result if called for v1 next time? */ - ret_val = SetAtomRadAndChemValFromVertexCapFlow( pBNS, at, v1 ); - if (ret_val < 0) - { - err = BNS_PROGRAM_ERR; - } - else - { - ret |= ( ret_val > 0 ); - } - } - /*pBNS->vert[v1].st_edge.flow0 = pBNS->vert[v1].st_edge.flow;*/ - } - } - - pBNS->vert[v1].st_edge.pass = 0; - - v0 = v2 = NO_VERTEX; - for (i = 0; i < n; i++, delta = -delta, v0 = v1, v1 = v2) - { - ineigh1 = ALTP_THIS_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v1->v2 neighbor */ - ineigh2 = ALTP_NEXT_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v2->v1 neighbor */ - edge = pBNS->edge + pBNS->vert[v1].iedge[ineigh1]; - /* follow the BN Structure, not the inp_ATOM, to take care of swithching to - t-groups, c-groups or other fictitious edges/vertices - */ - - v2 = edge->neighbor12 ^ v1; - - /* change at->chem_bonds_valence 2004-03-08 */ - if (( bChangeFlow & BNS_EF_CHNG_BONDS ) && v1 < num_atoms) - { - if (v0 >= num_atoms && v2 < num_atoms) - { - at[v1].chem_bonds_valence += delta; /* change in v1-v2 bond order */ - } - else - { - if (v0 < num_atoms && v2 >= num_atoms && v0 != NO_VERTEX) - { - at[v1].chem_bonds_valence -= delta; /* change in v0-v1 bond order */ - } - } - } - - if (!edge->pass) - { - continue; - } - - if (v1 < num_atoms && ineigh1 < at[v1].valence && - v2 < num_atoms && ineigh2 < at[v2].valence) - { - if (( bChangeFlow0 & BNS_EF_ALTR_NS ) == BNS_EF_ALTR_NS && - ( bChangeFlow0 & BNS_EF_SAVE_ALL ) == BNS_EF_SAVE_ALL) - { - /* 2004-07-02 special mode: save new ring bonds and mark as non-stereo non-ring bonds */ - if (at[v1].nRingSystem != at[v2].nRingSystem) - { - /* Non-ring bond (bridge) */ - bChangeFlowAdd = BNS_EF_ALTR_NS; - } - else - { - /* Ring bond */ - bChangeFlowAdd = 0; - } - } - /* Change bonds on the first pass only: in this case all flow correspond to the BNS output */ - ret_val = SetAtomBondType( edge, &at[v1].bond_type[ineigh1], &at[v2].bond_type[ineigh2], delta, bChangeFlow | bChangeFlowAdd ); - if (ret_val < 0) - { - err = BNS_PROGRAM_ERR; - } - else - { - ret |= ( ret_val > 0 ); - } - } - edge->pass = 0; - } - - if (v2 != vLast) - { - err = BNS_PROGRAM_ERR; - } - else - { - if (( bChangeFlow & BNS_EF_CHNG_RSTR ) == BNS_EF_CHNG_RSTR) - { - /* Restore v2-t edge flow to the BNS this pass input value */ - /* "+=" instead of "-=" explanation: delta must have same sign as at the last edge */ - ; /*pBNS->vert[v2].st_edge.flow += delta; */ - } - else - { - if (( bChangeFlow & BNS_EF_SAVE_ALL ) == BNS_EF_SAVE_ALL) - { - if (v2 < num_atoms) - { - ret_val = SetAtomRadAndChemValFromVertexCapFlow( pBNS, at, v2 ); - if (ret_val < 0) - { - err = BNS_PROGRAM_ERR; - } - else - { - ret |= ( ret_val > 0 ); - } - } - /*pBNS->vert[v2].st_edge.flow0 = pBNS->vert[v2].st_edge.flow;*/ - } - } - } - pBNS->vert[v2].st_edge.pass = 0; - } - - return err ? err : ret; -} - - -/****************************************************************************/ -int MarkAtomsAtTautGroups( BN_STRUCT *pBNS, - int num_atoms, - BN_AATG *pAATG, - int nEnd1, - int nEnd2 ) -{ - int pass, i, j, v1, v2, ineigh1, ineigh2, vLast, vFirst, n, delta, err = 0; /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ - BNS_EDGE *edge; - S_CHAR cDelta[MAX_ALT_AATG_ARRAY_LEN]; - AT_NUMB nVertex[MAX_ALT_AATG_ARRAY_LEN]; - int nLenDelta = 0, last_i, nNumFound; - - for (pass = pBNS->num_altp - 1; 0 <= pass; pass--) - { - pBNS->alt_path = pBNS->altp[pass]; - vFirst = - v1 = ALTP_START_ATOM( pBNS->alt_path ); - n = ALTP_PATH_LEN( pBNS->alt_path ); - delta = ALTP_DELTA( pBNS->alt_path ); - vLast = ALTP_END_ATOM( pBNS->alt_path ); - v2 = NO_VERTEX; - pAATG->nNumFound = 0; /* initialize */ - - if (nEnd1 != vFirst && nEnd1 != vLast) - { - nEnd1 = -1; /* really not the end */ - } - if (nEnd2 != vFirst && nEnd2 != vLast) - { - nEnd2 = -1; /* really not the end */ - } - - for (i = 0; i < n; i++, delta = -delta, v1 = v2) - { - ineigh1 = ALTP_THIS_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v1->v2 neighbor */ - ineigh2 = ALTP_NEXT_ATOM_NEIGHBOR(pBNS->alt_path, i); /* v2->v1 neighbor */ /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ - edge = pBNS->edge + pBNS->vert[v1].iedge[ineigh1]; - /* follow the BN Structure, not the inp_ATOM, to take care of swithching to - t-groups, c-groups or other fictitious edges/vertices - */ - v2 = edge->neighbor12 ^ v1; - /* - if ( v1 < num_atoms && v2 < num_atoms ) { - continue; - } - */ - /* BNS increased edge flow by delta */ - if (v1 >= num_atoms && - ( ( pBNS->vert[v1].type & BNS_VERT_TYPE_TGROUP ) || ( pBNS->vert[v1].type & BNS_VERT_TYPE_TEMP ) ) && - 0 <= v2 && v2 < num_atoms && ( pBNS->vert[v2].type & BNS_VERT_TYPE_ATOM )) - { - /* - if ( !(pAATG->nMarkedAtom[v2] & AATG_MARK_IN_PATH) ) { - pAATG->nMarkedAtom[v2] |= AATG_MARK_IN_PATH; - pAATG->nNumFound ++; - } - */ - - /* BNS increased bond order in v1(t-group)-v2(atom) by delta: added delta attachments */ - if (nLenDelta < MAX_ALT_AATG_ARRAY_LEN) - { - cDelta[nLenDelta] = delta; - nVertex[nLenDelta] = v2; - nLenDelta++; - } - } - else - { - if (v2 >= num_atoms && - ( ( pBNS->vert[v2].type & BNS_VERT_TYPE_TGROUP ) || ( pBNS->vert[v2].type & BNS_VERT_TYPE_TEMP ) ) && - 0 <= v1 && v1 < num_atoms && ( pBNS->vert[v1].type & BNS_VERT_TYPE_ATOM )) - { - /* - if ( !(pAATG->nMarkedAtom[v1] & AATG_MARK_IN_PATH) ) { - pAATG->nMarkedAtom[v1] |= AATG_MARK_IN_PATH; - pAATG->nNumFound ++; - } - */ - - /* BNS increased bond order in v1(atom)-v2(t-group) by delta: added delta attachments */ - if (nLenDelta < MAX_ALT_AATG_ARRAY_LEN) - { - cDelta[nLenDelta] = delta; - nVertex[nLenDelta] = v1; - nLenDelta++; - } - } - else - { - /* Special case when the testing 'dot' was placed on an atom (should be nEnd1 only) */ - if ((0 <= v1 && v1 == nEnd1) || (v1 == nEnd2 && 0 <= v2 && v2 < num_atoms)) /* djb-rwth: addressing LLVM warning */ - { - if (nLenDelta < MAX_ALT_AATG_ARRAY_LEN) - { - cDelta[nLenDelta] = -delta; - nVertex[nLenDelta] = v1; - nLenDelta++; - } - } - else - { - if ((0 <= v2 && v2 == nEnd1) || (v2 == nEnd2 && 0 <= v1 && v1 < num_atoms)) /* djb-rwth: addressing LLVM warning */ - { - if (nLenDelta < MAX_ALT_AATG_ARRAY_LEN) - { - cDelta[nLenDelta] = -delta; - nVertex[nLenDelta] = v2; - nLenDelta++; - } - } - } - } - } - } - - if (v2 != vLast) - { - err = BNS_PROGRAM_ERR; - } - else - { - last_i = -1; - nNumFound = 0; - /* first run */ - for (i = 1, j = 0; i < nLenDelta; j = i++) - { - /* Ignore sequences (-1,+1) and (+1,-1) in cDelta[] because they */ - /* describe ordinary aug. paths of moving a single attachment */ - /* we are looking for aug. paths describing movement of 2 or more */ - if ((cDelta[j] > 0 && cDelta[i] > 0) || - (cDelta[j] < 0 && cDelta[i] < 0)) /* djb-rwth: addressing LLVM warning */ - { - if (j == last_i) - { - /* Three attachments moved */ - return 0; - } - v1 = nVertex[j]; - if (!( pAATG->nMarkedAtom[v1] & AATG_MARK_IN_PATH )) - { - nNumFound++; - } - v2 = nVertex[i]; - if (!( pAATG->nMarkedAtom[v2] & AATG_MARK_IN_PATH )) - { - nNumFound++; - } - last_i = i; - } - } - if (!nNumFound) - { - return 0; - } - if (nNumFound > 4) - { - return 0; - } - if (nNumFound < 4) - { - return 0; - } - - /* Second run */ - for (i = 1, j = 0; i < nLenDelta; j = i++) - { - /* Ignore sequences (-1,+1) and (+1,-1) in cDelta[] because they */ - /* describe ordinary aug. paths of moving a single attachment */ - /* we are looking for aug. paths describing movement of 2 or more */ - if ((cDelta[j] > 0 && cDelta[i] > 0) || - (cDelta[j] < 0 && cDelta[i] < 0)) /* djb-rwth: addressing LLVM warning */ - { - v1 = nVertex[i - 1]; - if (!( pAATG->nMarkedAtom[v1] & AATG_MARK_IN_PATH )) - { - pAATG->nMarkedAtom[v1] |= AATG_MARK_IN_PATH; - pAATG->nNumFound++; - } - v2 = nVertex[i]; - if (!( pAATG->nMarkedAtom[v2] & AATG_MARK_IN_PATH )) - { - pAATG->nMarkedAtom[v2] |= AATG_MARK_IN_PATH; - pAATG->nNumFound++; - } - } - } - } - } - - return err ? err : pAATG->nNumFound; -} - - -/****************************************************************************/ -int RestoreBnStructFlow( BN_STRUCT *pBNS, int bChangeFlow ) -{ - int pass, i, v1, v2, ineigh1, ineigh2, vLast, n, delta, ret, err = 0; /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ - BNS_EDGE *edge; - - for (pass = pBNS->num_altp - 1, ret = 0; 0 <= pass; pass--) - { - pBNS->alt_path = pBNS->altp[pass]; - v1 = ALTP_START_ATOM( pBNS->alt_path ); - n = ALTP_PATH_LEN( pBNS->alt_path ); - delta = ALTP_DELTA( pBNS->alt_path ); - vLast = ALTP_END_ATOM( pBNS->alt_path ); - v2 = NO_VERTEX; - /* starting vertex */ - if (( bChangeFlow & BNS_EF_CHNG_RSTR ) == BNS_EF_CHNG_RSTR) - { - pBNS->vert[v1].st_edge.flow -= delta; /* restore s-v1 edge flow to the BNS input value */ - } - else - { - if (( bChangeFlow & BNS_EF_SAVE_ALL ) == BNS_EF_SAVE_ALL) - { - pBNS->vert[v1].st_edge.flow0 = pBNS->vert[v1].st_edge.flow; - } - } - - /* Augmenting path edges */ - for (i = 0; i < n; i++, delta = -delta, v1 = v2) - { - ineigh1 = ALTP_THIS_ATOM_NEIGHBOR( pBNS->alt_path, i ); /* v1->v2 neighbor */ - ineigh2 = ALTP_NEXT_ATOM_NEIGHBOR(pBNS->alt_path, i); /* v2->v1 neighbor */ /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ - edge = pBNS->edge + pBNS->vert[v1].iedge[ineigh1]; - v2 = edge->neighbor12 ^ v1; - RestoreEdgeFlow( edge, delta, bChangeFlow ); - edge->pass = 0; - } - - /* Ending vertex */ - if (v2 != vLast) - { - err = BNS_PROGRAM_ERR; - } - else - { - if (( bChangeFlow & BNS_EF_CHNG_RSTR ) == BNS_EF_CHNG_RSTR) - { - /* Restore v2-t edge flow to the original value */ - /* "+=" instead of "-=" explanation: delta must have same sign as at the last edge */ - pBNS->vert[v2].st_edge.flow += delta; - } - else - { - if (( bChangeFlow & BNS_EF_SAVE_ALL ) == BNS_EF_SAVE_ALL) - { - pBNS->vert[v2].st_edge.flow0 = pBNS->vert[v2].st_edge.flow; - } - } - } - } - - return err ? err : ret; -} - - -/****************************************************************************/ -int bNeedToTestTheFlow( int bond_type, - int nTestFlow, - int bTestForNonStereoBond ) -{ - int nBondType = ( BOND_TYPE_MASK & bond_type ); - int nBondAttrib = ( BOND_MARK_MASK & bond_type ); - - if (bTestForNonStereoBond) - { - if (nBondAttrib || nBondType == BOND_ALTERN || nBondType == BOND_ALT12NS) - { - switch (nTestFlow) - { - case 0: /* single: can be 1 (single)? */ - if (nBondAttrib == BOND_MARK_ALT12NS || - nBondAttrib == BOND_MARK_ALT123 || - nBondAttrib == BOND_MARK_ALT13) - { - return 0; /* yes, already checked */ - } - break; - - case 1: /* double: can be 2 (double)? */ - if (nBondAttrib == BOND_MARK_ALT12NS || - nBondAttrib == BOND_MARK_ALT123 || - nBondAttrib == BOND_MARK_ALT23) - { - return 0; /* yes, already checked */ - } - break; - case 2: /* triple: can be 3 (triple)? */ - if (nBondAttrib == BOND_MARK_ALT13 || - nBondAttrib == BOND_MARK_ALT123 || - nBondAttrib == BOND_MARK_ALT23) - { - return 0; /* yes, already checked */ - } - break; - } - } - } - else - { - if (nBondAttrib || nBondType == BOND_ALTERN || nBondType == BOND_ALT12NS) - { - switch (nTestFlow) - { - case 0: /* single: can be 1 (single)? */ - if (nBondAttrib == BOND_MARK_ALT12 || - nBondAttrib == BOND_MARK_ALT12NS || - nBondAttrib == BOND_MARK_ALT123 || - nBondAttrib == BOND_MARK_ALT13) - { - return 0; - } - break; - - case 1: /* double: can be 2 (double)? */ - if (nBondAttrib == BOND_MARK_ALT12 || - nBondAttrib == BOND_MARK_ALT12NS || - nBondAttrib == BOND_MARK_ALT123 || - nBondAttrib == BOND_MARK_ALT23) - { - return 0; /* yes */ - } - break; - case 2: /* triple: can be 3 (triple)? */ - if (nBondAttrib == BOND_MARK_ALT13 || - nBondAttrib == BOND_MARK_ALT123 || - nBondAttrib == BOND_MARK_ALT23) - { - return 0; - } - break; - } - } - } - - return 1; -} - - -/****************************************************************************/ -int nBondsValenceInpAt( const inp_ATOM *at, - int *nNumAltBonds, - int *nNumWrongBonds ) -{ - int j, bond_type, nBondsValence = 0, nAltBonds = 0, nNumWrong = 0; - for (j = 0; j < at->valence; j++) - { - bond_type = at->bond_type[j] & BOND_TYPE_MASK; - switch (bond_type) - { - case 0: /* for structure from InChI reconstruction */ - case BOND_SINGLE: - case BOND_DOUBLE: - case BOND_TRIPLE: - nBondsValence += bond_type; - break; - case BOND_ALTERN: - nAltBonds++; - break; - default: - nNumWrong++; - } - } - switch (nAltBonds) - { - case 0: - break; - case 1: - nBondsValence += 1; /* 1 or greater than 3 is wrong */ - nNumWrong++; - break; - default: - nBondsValence += nAltBonds + 1; - break; - } - if (nNumAltBonds) - { - *nNumAltBonds = nAltBonds; - } - if (nNumWrongBonds) - { - *nNumWrongBonds = nNumWrong; - } - - return nBondsValence; -} - - -/**************************************************************************** -If radical or has aromatic bonds, -then augment to the lowest "multiplicity" -****************************************************************************/ -int BnsAdjustFlowBondsRad( BN_STRUCT *pBNS, - BN_DATA *pBD, - inp_ATOM *at, - int num_atoms ) -{ - int bError = 0, nOrigDelta = 0, ret, num_removed; - -#if( CHECK_AROMBOND2ALT == 1 ) - int *pcValMinusBondsVal = NULL; - int i, nValMinusBondsVal, nAltBonds, bIgnore, valen, is_rad, excess; - - /* Find valence excess (it may only be due to aromatic bonds) */ - for (i = 0; i < num_atoms; i++) - { - valen = nBondsValenceInpAt( at + i, &nAltBonds, &bIgnore ); - nValMinusBondsVal = (int) at[i].chem_bonds_valence - valen; - bIgnore += ( nAltBonds > 3 ); - if (!bIgnore && nValMinusBondsVal > 0) - { - if (!pcValMinusBondsVal && - !( pcValMinusBondsVal = (int *) inchi_calloc( num_atoms, sizeof( pcValMinusBondsVal[0] ) ) )) - { - bError = BNS_OUT_OF_RAM; - goto exit_function; - } - /* Mark atoms that have extra unsatisfied valence due to aromatic bonds */ - is_rad = ( at[i].radical == RADICAL_DOUBLET ); - excess = nValMinusBondsVal + is_rad; - pcValMinusBondsVal[i] = excess; - } - } -#endif /* CHECK_AROMBOND2ALT */ - - /* Match bonds to valences */ - do - { - num_removed = 0; - ret = RunBalancedNetworkSearch( pBNS, pBD, BNS_EF_CHNG_FLOW ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - else - { - nOrigDelta += ret; - num_removed = pBNS->num_altp; /* number of augmenting paths */ - if (ret > 0) - { - /* save new bonds in at[] and flows in pBNS and at[] */ - ret = SetBondsFromBnStructFlow( pBNS, at, num_atoms, BNS_EF_SAVE_ALL ); /* must include 1: 5=(4|1) */ - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - ret = RestoreBnStructFlow( pBNS, BNS_EF_SAVE_ALL ); /* must include 1: 5=(4|1) */ - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - } - ReInitBnStructAltPaths( pBNS ); - } - } while (num_removed && num_removed == pBNS->max_altp && !bError); - -#if( CHECK_AROMBOND2ALT == 1 ) - /* Check whether aromatic bonds have been replaced with alternating bonds */ - if (!bError && pcValMinusBondsVal) - { - for (i = 0; i < num_atoms; i++) - { - if (!pcValMinusBondsVal[i]) - { - continue; - } - valen = nBondsValenceInpAt( at + i, &nAltBonds, &bIgnore ); - nValMinusBondsVal = (int) at[i].chem_bonds_valence - valen; - is_rad = ( at[i].radical == RADICAL_DOUBLET ); - excess = nValMinusBondsVal + is_rad; - if (bIgnore || - ( pcValMinusBondsVal[i] - excess ) != 1) - { - /* radical excess has not been reduced */ - bError = BNS_ALTBOND_ERR; - break; - } - } - } - -exit_function: - if (pcValMinusBondsVal) - { - inchi_free( pcValMinusBondsVal ); - } -#endif /* CHECK_AROMBOND2ALT */ - - return bError ? bError : nOrigDelta; -} - - -/****************************************************************************/ -int BnsTestAndMarkAltBonds( BN_STRUCT *pBNS, - BN_DATA *pBD, - inp_ATOM *at, - int num_atoms, - BNS_FLOW_CHANGES *fcd, - int bChangeFlow, - int nBondTypeToTest ) -{ - int ret, iat, ineigh, neigh; - int nMinFlow, nMaxFlow, nTestFlow, nCurFlow; - int iedge, bError, nDots, nChanges, bTestForNonStereoBond; /* djb-rwth: removing redundant variables */ - - /* Normalize bonds and find tautomeric groups */ - bError = 0; - nChanges = 0; - bTestForNonStereoBond = pBNS->tot_st_cap > pBNS->tot_st_flow; - - for (iat = 0; iat < num_atoms && !bError; iat++) - { - for (ineigh = 0; ineigh < at[iat].valence && !bError; ineigh++) - { - neigh = at[iat].neighbor[ineigh]; - if (neigh < iat) - { - continue; /* we have already tested the bond */ - } - iedge = pBNS->vert[iat].iedge[ineigh]; - if (IS_FORBIDDEN( pBNS->edge[iedge].forbidden, pBNS )) - { - continue; - } - if (nBondTypeToTest && ( at[iat].bond_type[ineigh] & BOND_TYPE_MASK ) != nBondTypeToTest) - { - continue; - } - nMinFlow = nMinFlow2Check( pBNS, iedge ); - nMaxFlow = nMaxFlow2Check( pBNS, iedge ); - nCurFlow = nCurFlow2Check( pBNS, iedge ); - if (nMinFlow == nMaxFlow) - { - if (nMaxFlow && bTestForNonStereoBond) - { - nTestFlow = nMaxFlow - (int) ( pBNS->tot_st_cap - pBNS->tot_st_flow ); /* temporary use of nTestFlow */ - nMinFlow = inchi_max( 0, nTestFlow ); - } - else - { - continue; - } - } - for (nTestFlow = nMinFlow; nTestFlow <= nMaxFlow && !bError; nTestFlow++) - { - if (nTestFlow == nCurFlow) - { - continue; - } - if (!bNeedToTestTheFlow( at[iat].bond_type[ineigh], nTestFlow, bTestForNonStereoBond )) - { - continue; - } - /* djb-rwth: removing redundant code */ - nDots = bSetFlowToCheckOneBond( pBNS, iedge, nTestFlow, fcd ); - - if (IS_BNS_ERROR( nDots )) - { - if (nDots == BNS_CANT_SET_BOND) - { - ret = bRestoreFlowAfterCheckOneBond( pBNS, fcd ); - if (!IS_BNS_ERROR( ret )) - { - continue; - } - } - bError = nDots; - } - else - { - if (nDots > 0) - { - ret = RunBalancedNetworkSearch( pBNS, pBD, bChangeFlow ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - else - { - if (ret > 0) - { - if (2 * ret == nDots) - { - ret = bSetBondsAfterCheckOneBond( pBNS, fcd, nTestFlow, at, num_atoms, bChangeFlow ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - else - { - nChanges += ( ret & 1 ); - ret = SetBondsFromBnStructFlow( pBNS, at, num_atoms, bChangeFlow ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - else - { - if (ret >= 0) - { - nChanges += ( ret & 1 ); - /* djb-rwth: removing redundant code */ - } - else - { - bError = ret; - } - } - } - } - /* typically 2*ret < nDots; 2*ret > nDots should not happen. Check later */ - ret = RestoreBnStructFlow( pBNS, bChangeFlow & BNS_EF_CHNG_RSTR ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - } - } - /* --- Reinitialize to repeat the calculations --- */ - ReInitBnStructAltPaths( pBNS ); - } - - else - { - if (nDots == 0) - { - ret = bSetBondsAfterCheckOneBond( pBNS, fcd, nTestFlow, at, num_atoms, bChangeFlow ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - else - { - nChanges += ( ret & 1 ); - } - } - } - } - - ret = bRestoreFlowAfterCheckOneBond( pBNS, fcd ); - - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - - } /* for (nTestFlow = */ - } /* for (ineigh = */ - } /* for (iat = */ - - return bError ? bError : nChanges; -} - - -/****************************************************************************/ -static void remove_alt_bond_marks( inp_ATOM *at, int num_atoms ) -{ - int i, j, val; - for (i = 0; i < num_atoms; i++) - { - for (val = at[i].valence, j = 0; j < val; j++) - { - at[i].bond_type[j] &= BOND_TYPE_MASK; - } - } - -} - - -/****************************************************************************/ -int SetForbiddenEdges( BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - int forbidden_mask, - int nebend, - int *ebend ) -{ - - - int i, j, neigh, num_found; - BNS_IEDGE iedge; - /*S_CHAR edge_forbidden_mask = BNS_EDGE_FORBIDDEN_MASK;*/ - S_CHAR edge_forbidden_mask = forbidden_mask; - - pBNS->edge_forbidden_mask |= forbidden_mask; - - num_found = 0; - - for (i = 0; i < num_atoms; i++) - { - /* acetyl */ - if (at[i].el_number == EL_NUMBER_C && 3 == at[i].valence && - 4 == at[i].chem_bonds_valence) - { - int num_O = 0; - int bond_to_O_val = 0; - int forbidden_bond_pos = -1; - int forbidden_bond_val = -1; - for (j = 0; j < at[i].valence; j++) - { - neigh = at[i].neighbor[j]; - if (at[neigh].el_number == EL_NUMBER_O && - at[neigh].valence == 1) - { - num_O++; - bond_to_O_val += ( at[i].bond_type[j] & BOND_TYPE_MASK ); - } - else - { - forbidden_bond_pos = j; - forbidden_bond_val = ( at[i].bond_type[j] & BOND_TYPE_MASK ); - } - } - if (2 == num_O && 3 == bond_to_O_val && 1 == forbidden_bond_val) - { - iedge = pBNS->vert[i].iedge[forbidden_bond_pos]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_found++; - } - } - else - { - /* nitro */ - if (at[i].el_number == EL_NUMBER_N && 3 == at[i].valence && - ( 4 == at[i].chem_bonds_valence || 5 == at[i].chem_bonds_valence )) - { - int num_O = 0; - int bond_to_O_val = 0; - int forbidden_bond_pos = -1; - int forbidden_bond_val = -1; - for (j = 0; j < at[i].valence; j++) - { - neigh = at[i].neighbor[j]; - if (at[neigh].el_number == EL_NUMBER_O && - at[neigh].valence == 1) - { - num_O++; - bond_to_O_val += ( at[i].bond_type[j] & BOND_TYPE_MASK ); - } - else - { - forbidden_bond_pos = j; - forbidden_bond_val = ( at[i].bond_type[j] & BOND_TYPE_MASK ); - } - } - if (2 == num_O && ( 3 == bond_to_O_val || 4 == bond_to_O_val ) && 1 == forbidden_bond_val) - { - iedge = pBNS->vert[i].iedge[forbidden_bond_pos]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_found++; - } - } - } - } - -#ifdef FIX_SRU_CYCLIZING_PS_BONDS_IN_BNS - if (nebend > 1) - num_found += fix_explicitly_indicated_bonds( nebend, ebend, pBNS, at, num_atoms ); -#endif - -#if ( REMOVE_ION_PAIRS_FIX_BONDS == 1 ) - num_found += fix_special_bonds( pBNS, at, num_atoms, edge_forbidden_mask ); -#endif -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - num_found += TempFix_NH_NH_Bonds( pBNS, at, num_atoms ); -#endif - - return num_found; -} - - - -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - - -/****************************************************************************/ -int TempFix_NH_NH_Bonds( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms ) -{ - int i, j, neigh, num_found; - BNS_IEDGE iedge; - S_CHAR edge_forbidden_mask = BNS_EDGE_FORBIDDEN_TEMP; - for (i = 0, num_found = 0; i < num_atoms; i++) - { - /* -NH-NH- or -NH-NH3 */ - if (at[i].el_number == EL_NUMBER_N && at[i].valence < 3 && at[i].num_H && - 3 == at[i].chem_bonds_valence + at[i].num_H && - at[i].chem_bonds_valence == at[i].valence && - !at[i].charge && !at[i].radical) - { - for (j = 0; j < at[i].valence; j++) - { - neigh = at[i].neighbor[j]; - if (neigh < i && - at[neigh].el_number == EL_NUMBER_N && at[neigh].valence < 3 && at[neigh].num_H && - 3 == at[neigh].chem_bonds_valence + at[neigh].num_H && - at[neigh].chem_bonds_valence == at[neigh].valence && - !at[neigh].charge && !at[neigh].radical) - { - iedge = pBNS->vert[i].iedge[j]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_found++; - } - } - } - } - - return num_found; -} - - -/****************************************************************************/ -int CorrectFixing_NH_NH_Bonds( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms ) -{ - int i, j, neigh, num_found; - BNS_IEDGE iedge; - S_CHAR edge_forbidden_mask = BNS_EDGE_FORBIDDEN_TEMP; - - for (i = 0, num_found = 0; i < num_atoms; i++) - { - /* -NH-NH- or -NH-NH3 */ - if (at[i].el_number == EL_NUMBER_N && at[i].valence < 3) - { - for (j = 0; j < at[i].valence; j++) - { - neigh = at[i].neighbor[j]; - if (neigh < i && - at[neigh].el_number == EL_NUMBER_N && at[neigh].valence < 3) - { - if (BOND_TYPE_SINGLE != ( at[i].bond_type[j] & BOND_TYPE_MASK )) - { - iedge = pBNS->vert[i].iedge[j]; - if (pBNS->edge[iedge].forbidden & edge_forbidden_mask) - { - pBNS->edge[iedge].forbidden &= ~edge_forbidden_mask; - num_found++; - } - } - } - } - } - } - - return num_found; -} -#endif - -/**************************************************************************** -Fixes bonds which were set by remove_ion_pairs( ... ) -****************************************************************************/ -int fix_special_bonds( BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - int forbidden_mask ) -{ - int num_changes = 0; - -#define MAX_NEIGH 6 - - int i, k, n1, n2, n3, i1, i2, i3, i4, bond_type; /* djb-rwth: removing redundant variables */ - inp_ATOM *a; - int j[3], m[3], num_O, k_O, num_N, num_OH, num_OM, num_X, num_other, k_N; - - BNS_IEDGE iedge; - /*S_CHAR edge_forbidden_mask = BNS_EDGE_FORBIDDEN_MASK;*/ - S_CHAR edge_forbidden_mask = forbidden_mask; - - pBNS->edge_forbidden_mask |= edge_forbidden_mask; - - for (i = 0, a = at; i < num_atoms; i++, a++) - { - - if (!a->charge && !a->radical && - 2 <= a->chem_bonds_valence + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && - 0 == num_of_H( at, i ) && - 2 == nNoMetalBondsValence( at, i ) + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && - ion_el_group( at[i].el_number ) == EL_NUMBER_N ) - { - /* Found N(V), no H */ - if (2 == nNoMetalNumBonds( at, i )) - { - /* #N= */ - /* fix bonds: double and triple: =N# so that bonds cannot be changed by the normalization */ -#if ( FIX_N_V_METAL_BONDS_GPF == 1 ) - if (0 > ( i1 = nNoMetalNeighIndex( at, i ) ) || - 0 > ( i2 = nNoMetalOtherNeighIndex( at, i, n1 = a->neighbor[i1]/* non-metal neighbor #1 */ ) )) - { - /*num_err ++; */ /* do not count would-be original InChI v.1 buffer overflow GPF */ - continue; /* v1 bug: 2 bonds to metal yield i1 < 0 and/or i2 < 0 => bounds violation */ - } -#else - i1 = nNoMetalNeighIndex( at, i ); - n1 = a->neighbor[i1]; /* non-metal neighbor #1 */ - i2 = nNoMetalOtherNeighIndex( at, i, n1 ); -#endif - n2 = a->neighbor[i2]; /* non-metal neighbor #2 */ - /* forbid all edges to non-metals */ - iedge = pBNS->vert[i].iedge[i1]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; /* fix bond to neighbor #1 */ - iedge = pBNS->vert[i].iedge[i2]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; /* fix bond to neighbor #1 */ - num_changes++; /* added 11-15-2005 */ - /* i n3 */ - /* forbid single bond edge beyond the neighboring =N- as in #N=N- */ - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - if (( at[i].bond_type[i1] & BOND_TYPE_MASK ) == BOND_TYPE_DOUBLE) - { - i3 = i1; /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - n3 = n1; - } - else - { - i3 = i2; /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - n3 = n2; - } - if (0 == NUMH( at, n3 ) && 2 == nNoMetalNumBonds( at, n3 ) && - 3 == nNoMetalBondsValence( at, n3 ) && - ion_el_group( at[n3].el_number ) == EL_NUMBER_N && - 0 <= ( k = nNoMetalOtherNeighIndex( at, n3, i ) )) - { - /* found =N- ; forbid the edge*/ - iedge = pBNS->vert[n3].iedge[k]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - } - } - else if (3 == nNoMetalNumBonds( at, i ) && - /* | */ - /* found =N= */ - /* locate all non-metal neighbors */ - 0 <= ( j[0] = nNoMetalNeighIndex( at, i ) ) && - 0 <= ( j[1] = nNoMetalOtherNeighIndex( at, i, m[0] = a->neighbor[j[0]] ) ) && - 0 <= ( j[2] = nNoMetalOtherNeighIndex2( at, i, m[0], m[1] = a->neighbor[j[1]] ) )) - { - /* Count specific neighbors: N(V)=N, N(V)-N N(V)=O, and N(V)-N */ - - /* if there is a single neighbor connected by a double bond, namely - N(V)=N and/or N(V)=O, then fix the bond(s). - If N(V)=O was fixed then do not fix another bond */ - m[2] = a->neighbor[j[2]]; - num_O = num_N = 0; - for (k = 0; k < 3; k++) - { - n1 = m[k]; - i1 = j[k]; /* djb-rwth: ignoring LLVM warning: variable used */ - if (ion_el_group( at[n1].el_number ) == EL_NUMBER_N) - { - k_N = k; - num_N++; - } - else if (ion_el_group( at[n1].el_number ) == EL_NUMBER_O && - 1 == nNoMetalNumBonds( at, n1 )) - { - k_O = k; - num_O++; - } - } - num_other = 0; - if (1 == num_O && - 0 == at[n1 = m[k_O]].charge && - 0 == at[n1].radical && - BOND_TYPE_DOUBLE == ( at[i].bond_type[i1 = j[k_O]] & BOND_TYPE_MASK ) - ) - { - /* Fix bond to neighbor =O */ - iedge = pBNS->vert[i].iedge[i1]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - num_other++; /* indicator: double to a terminal O has been fixed */ - } - if (!num_other && - num_O <= 1 && - 1 == num_N && - 0 == at[n1 = m[k_N]].charge && - 0 == at[n1].radical && - BOND_TYPE_DOUBLE == ( at[i].bond_type[i1 = j[k_N]] & BOND_TYPE_MASK )) - { - /* Fix bond to neighbor =N */ - iedge = pBNS->vert[i].iedge[i1]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - } - } - else if (4 == nNoMetalNumBonds( at, i )) - { - /* | */ - /* found -N=N- */ - /* | */ - /* locate non-metal neighbor connected by a double bond; - * if it is =N- then fix the double bond and the single bond beyond the neighbor - */ - num_N = 0; - num_other = 0; /* djb-rwth: ignoring LLVM warning: variable used */ - for (i1 = 0; i1 < at[i].valence; i1++) - { - if (BOND_TYPE_DOUBLE == ( at[i].bond_type[i1] & BOND_TYPE_MASK ) && - !is_el_a_metal( at[n1 = (int) at[i].neighbor[i1]].el_number ) && - ion_el_group( at[n1].el_number ) == EL_NUMBER_N) - { - num_N++; - n2 = n1; - i2 = i1; - } - } - if (1 == num_N && 0 == NUMH( at, n2 ) && - 2 == nNoMetalNumBonds( at, n2 ) && - 3 == nNoMetalBondsValence( at, n2 ) && - 0 <= ( i3 = nNoMetalOtherNeighIndex( at, n2, i ) ) && - BOND_TYPE_SINGLE == ( at[n2].bond_type[i3] & BOND_TYPE_MASK )) - { - /* fix the single bond beyond the N(V) neighbor N(V)=N- */ - iedge = pBNS->vert[n2].iedge[i3]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - /* fix the double bond */ - iedge = pBNS->vert[i].iedge[i2]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - } - } - } - - else if (!a->charge && !a->radical && - 2 <= a->chem_bonds_valence + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && - 0 == num_of_H( at, i ) && - 2 == nNoMetalBondsValence( at, i ) + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && - a->el_number != EL_NUMBER_O && ion_el_group( a->el_number ) == EL_NUMBER_O && - 3 == nNoMetalNumBonds( at, i )) - { - /* Found S(IV), no H, one double bond, total 3 bonds */ - /* OH - / - in O=S (X != O) fix single bond O-X (type 1) - \ - X - - X - / - in Z=S (X, Y != OH) fix double bond Z=S (type 2) - \ - Y - */ - num_N = 0; /* number of non-metal neighbors connected by a double bond */ - num_OH = 0; /* number of neighbors OH connected by a single bond */ - num_OM = 0; /* number of charged neighbors O connected by a single bond */ - num_O = 0; /* number of neighbors =O connected by a double bond */ - num_other = 0; - - for (i1 = 0; i1 < a->valence; i1++) - { - n1 = (int) a->neighbor[i1]; - if (is_el_a_metal( at[n1].el_number )) - { - continue; - } - - bond_type = ( a->bond_type[i1] & BOND_TYPE_MASK ); - - if (BOND_TYPE_DOUBLE == bond_type) - { - num_N++; - n2 = n1; - i2 = i1; - if (ion_el_group( at[n1].el_number ) == EL_NUMBER_O) - { - num_O++; - } - } - else if (BOND_TYPE_SINGLE == bond_type && - 1 == nNoMetalNumBonds( at, n1 ) && - 1 == nNoMetalBondsValence( at, n1 ) && - ion_el_group( at[n1].el_number ) == EL_NUMBER_O) - { - if (0 == at[n1].charge) - { - num_OH++; - n3 = n1; - i3 = i1; /* djb-rwth: ignoring LLVM warning: variable used */ - } - else - { - num_OM++; - } - } - else - { - num_other++; - /* djb-rwth: removing redundant code */ - i4 = i1; - } - } /* for (i1 = */ - - if (1 == num_N && 1 == num_O && 1 == num_OH + num_OM) - { - if (1 == num_other) - { - /* type 1: fix the single bond S-X */ - iedge = pBNS->vert[i].iedge[i4]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - } - } - else if (1 == num_N && !num_OH && !num_OM) - { - int bFound = 0; /* flag */ - int bDoNotFixAnyBond = 0; /* flag */ - /* Avoid case N=S-NH or N=S-N(-); N = N, P, As, Sb */ - if (ion_el_group( at[n2].el_number ) == EL_NUMBER_N) - { - U_CHAR el_number = at[n2].el_number; - for (i1 = 0; i1 < a->valence; i1++) - { - n1 = (int) a->neighbor[i1]; - bond_type = ( a->bond_type[i1] & BOND_TYPE_MASK ); - if (BOND_TYPE_SINGLE == bond_type && - ( NUMH( at, n1 ) || -1 == at[n1].charge ) && - el_number == at[n1].el_number) - { - i3 = i1; /* djb-rwth: ignoring LLVM warning: variable used */ - n3 = n1; - bFound++; - } - } - } - /* Exception: check if Z==X and they belong to the same ring system */ - for (i1 = 0; i1 < a->valence; i1++) - { - if (i1 != i2) - { - n1 = (int) a->neighbor[i1]; - if (at[n2].el_number == at[n1].el_number && - at[n2].nRingSystem == at[n1].nRingSystem) - { - bDoNotFixAnyBond++; - } - } - } - if (bDoNotFixAnyBond) - { - ; /* do nothing */ - } - else if (bFound) - { - if (1 == bFound && - 0 <= ( i4 = nNoMetalOtherNeighIndex2( at, i, n2, n3 ) )) - { - /* fix bond i4 */ - iedge = pBNS->vert[i].iedge[i4]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - } - } - else - { - /* fix the double bond >S=X */ - iedge = pBNS->vert[i].iedge[i2]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - /* -- test later -- - if ( 2 == nNoMetalNumBonds( at, n2 ) && - 0 <= ( i3 = nNoMetalOtherNeighIndex( at, n2, i ) ) ) { - iedge = pBNS->vert[n2].iedge[i3]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes ++; - } - -------------------*/ - } - } - } - - else if (!a->charge && !a->radical && - 4 <= a->chem_bonds_valence + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && - 0 == num_of_H( at, i ) && - 4 == nNoMetalBondsValence( at, i ) + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && - a->el_number != EL_NUMBER_O && ion_el_group( a->el_number ) == EL_NUMBER_O && - 4 == nNoMetalNumBonds( at, i )) - { - /* Found S(VI), no H, two double bonds or one triple bond */ - /* O - || - in O=S--Y- (X, Y -- non-terminal) fix single bonds S-X, S-Y (type 1) - \ - X-- - - O - || - in O=S--O(-) (X -- non-terminal) fix single bond S-X (type 2) - \ - X-- - - O - || - in O=S--OH (X -- non-terminal) fix single bond S-X (type 3) - \ - X-- - - */ - int iN[4]; /* indexes of non-terminal neighbors connected by a single bond */ - num_N = 0; /* number of non-metal neighbors connected by a double bond */ - num_OH = 0; /* number of neighbors OH connected by a single bond */ - num_OM = 0; /* number of non-terminal neighbors connected by a single bond */ - num_O = 0; /* number of neighbors =O connected by a double bond */ - num_X = 0; /* number of terminal atom X != O connected by a single bond */ - num_other = 0; - for (i1 = 0; i1 < a->valence; i1++) - { - n1 = (int) a->neighbor[i1]; - if (is_el_a_metal( at[n1].el_number )) - { - continue; - } - bond_type = ( a->bond_type[i1] & BOND_TYPE_MASK ); - if (BOND_TYPE_DOUBLE == bond_type) - { - num_N++; - if (( 0 == at[n1].charge -#if ( S_VI_O_PLUS_METAL_FIX_BOND == 1 ) - || (1 == at[n1].charge && 2 == at[n1].valence) /* djb-rwth: addressing LLVM warning */ -#endif - ) && - 0 == at[n1].radical && - 0 == num_of_H( at, n1 ) && - ion_el_group( at[n1].el_number ) == EL_NUMBER_O && - 1 == nNoMetalNumBonds( at, n1 )) - { - num_O++; - } - } - else if (BOND_TYPE_SINGLE == bond_type && - 1 == nNoMetalNumBonds( at, n1 ) && - ion_el_group( at[n1].el_number ) == EL_NUMBER_O && - 1 >= num_of_H( at, n1 ) && - 1 == ( ( 0 == at[n1].charge ) && 1 == num_of_H( at, n1 ) ) - + ( ( -1 == at[n1].charge ) && 0 == num_of_H( at, n1 ) )) - { - num_OH++; /* -OH or -O(-) */ - } - else if (BOND_TYPE_SINGLE == bond_type && - 1 < nNoMetalNumBonds( at, n1 )) - { - iN[num_OM++] = i1; /* non-terminal neighbor connected by a single bond */ - } - else if (BOND_TYPE_SINGLE == bond_type && - 1 == nNoMetalNumBonds( at, n1 )) - { - num_X++; /* other terminal neighbor connected by a single bond */ - } - else - { - num_other++; - } - } - if (num_N == num_O && 2 == num_O && 2 == num_OH + num_OM + num_X && 0 == num_other) - { - for (i2 = 0; i2 < num_OM; i2++) - { - i1 = iN[i2]; - /* fix bond i1 */ - iedge = pBNS->vert[i].iedge[i1]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - } - } - } - - else if (!a->charge && !a->radical && - 6 <= a->chem_bonds_valence + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && - 0 == num_of_H( at, i ) && - 6 == nNoMetalBondsValence( at, i ) + NUMH( a, 0 ) - get_el_valence( a->el_number, 0, 0 ) && - a->el_number != EL_NUMBER_O && ion_el_group( a->el_number ) == EL_NUMBER_O && - 5 == nNoMetalNumBonds( at, i )) - { - /* Found S(VIII), no H, three double bonds or two triple bond */ - /* - - O - || - in O=S--Y-- (X, Y -- non-terminal) fix single bond S-X, S-Y (type 4) - //\ - O X-- - - note: this structure is a mistakenly drawn structure - - O O - || || - O=S--O--Y-- or O=S--Y-- - \ \ - X-- O--X-- - - - */ - int iN[5]; /* indexes of non-terminal neighbors connected by a single bond */ - num_N = 0; /* number of non-metal neighbors connected by a double bond */ - num_OH = 0; /* number of neighbors OH connected by a single bond */ - num_OM = 0; /* number of non-terminal neighbors connected by a single bond */ - num_O = 0; /* number of neighbors =O connected by a double bond */ - num_X = 0; /* number of terminal atom X != O connected by a single bond */ - num_other = 0; - for (i1 = 0; i1 < a->valence; i1++) - { - n1 = (int) a->neighbor[i1]; - if (is_el_a_metal( at[n1].el_number )) - { - continue; - } - bond_type = ( a->bond_type[i1] & BOND_TYPE_MASK ); - if (BOND_TYPE_DOUBLE == bond_type) - { - num_N++; - if (( 0 == at[n1].charge -#if ( S_VI_O_PLUS_METAL_FIX_BOND == 1 ) - || (1 == at[n1].charge && 2 == at[n1].valence) /* djb-rwth: addressing LLVM warning */ -#endif - ) - && 0 == at[n1].radical && - 0 == num_of_H( at, n1 ) && - ion_el_group( at[n1].el_number ) == EL_NUMBER_O && - 1 == nNoMetalNumBonds( at, n1 )) - { - num_O++; - } - } - else if (BOND_TYPE_SINGLE == bond_type && - 1 == nNoMetalNumBonds( at, n1 ) && - ion_el_group( at[n1].el_number ) == EL_NUMBER_O && - 1 >= num_of_H( at, n1 ) && - 1 == ( ( 0 == at[n1].charge ) && 1 == num_of_H( at, n1 ) ) - + ( ( -1 == at[n1].charge ) && 0 == num_of_H( at, n1 ) )) - { - num_OH++; /* -OH or -O(-) */ - } - else - { - if (BOND_TYPE_SINGLE == bond_type && - 1 < nNoMetalNumBonds( at, n1 )) - { - - iN[num_OM++] = i1; /* non-terminal neighbor connected by a single bond */ - } - else - { - if (BOND_TYPE_SINGLE == bond_type && 1 == nNoMetalNumBonds( at, n1 )) - { - - num_X++; /* other terminal neighbor connected by a single bond */ - } - else - { - num_other++; - } - } - } - } - if (num_N == num_O && 3 == num_O && 2 == num_OH + num_OM + num_X && 0 == num_other) - { - for (i2 = 0; i2 < num_OM; i2++) - { - i1 = iN[i2]; - /* fix bond i1 */ - iedge = pBNS->vert[i].iedge[i1]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - } - } - } - - } /* for (i = */ - - return num_changes; -} - - -/****************************************************************************/ -int fix_explicitly_indicated_bonds( int nebend, - int *ebend, - BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms ) -{ - int i, num_changes = 0; - inp_ATOM *a; - int j, ia1, ia2, i1 = -1, i2 = -1, index = -1, neigh; - BNS_IEDGE iedge; - S_CHAR edge_forbidden_mask = BNS_EDGE_FORBIDDEN_MASK; - pBNS->edge_forbidden_mask |= edge_forbidden_mask; - - if (nebend < 1 || !ebend) - { - return 0; - } - - for (j = 0; j < nebend; j += 2) - { - - ia1 = ebend[2 * j]; - ia2 = ebend[2 * j + 1]; - - for (i = 0; i < num_atoms; i++) - { - if (at[i].orig_at_number == ia1) - { - i1 = i; - } - else if (at[i].orig_at_number == ia2) - { - i2 = i; - } - if (i1 > 0 && i2 > 0) - { - break; - } - } - - if (i1 < 0 || i2 < 0) - { - return 0; - } - - if (i2 < i1) - { - int tmp = i1; i1 = i2; i2 = tmp; - } - - a = at + i1; - for (i = 0; i < a->valence; i++) - { - neigh = (int) a->neighbor[i]; - if (neigh == i2) - { - index = i; break; - } - } - if (index > -1) - { - iedge = pBNS->vert[i].iedge[index]; - pBNS->edge[iedge].forbidden |= edge_forbidden_mask; - num_changes++; - } - } - - return num_changes; -} - - - - -#define ALL_NONMETAL_Z 0 - - -/****************************************************************************/ -int is_Z_atom( U_CHAR el_number ) -{ - switch ( el_number ) - { - case EL_NUMBER_C: /* fallthrough */ - case EL_NUMBER_N: - case EL_NUMBER_P: - case EL_NUMBER_AS: - case EL_NUMBER_SB: - case EL_NUMBER_S: - case EL_NUMBER_SE: - case EL_NUMBER_TE: - case EL_NUMBER_CL: - case EL_NUMBER_BR: - case EL_NUMBER_I: -#if ( ALL_NONMETAL_Z == 1 ) - case EL_NUMBER_B: - case EL_NUMBER_O: - case EL_NUMBER_SI: - case EL_NUMBER_GE: - case EL_NUMBER_F: - case EL_NUMBER_AT: -#endif - return 1; - default: - return 0; - } -} - - -/**************************************************************************** -Detect O==Z--X, O=O,S,Se,Te -****************************************************************************/ -int IsZOX( inp_ATOM *atom, int at_x, int ord ) -{ - inp_ATOM *at_Z = atom + atom[at_x].neighbor[ord]; - - int i, neigh, num_O; - - for (i = 0, num_O = 0; i < at_Z->valence; i++) - { - neigh = at_Z->neighbor[i]; - if (neigh == at_x) - { - continue; - } - if (atom[neigh].valence == 1 && - atom[neigh].chem_bonds_valence == 2 && - atom[neigh].charge == 0 && - atom[neigh].radical == 0 && - ( atom[neigh].el_number == EL_NUMBER_O || - atom[neigh].el_number == EL_NUMBER_S || - atom[neigh].el_number == EL_NUMBER_SE || - atom[neigh].el_number == EL_NUMBER_TE )) - { - num_O++; - } - } - - return num_O; -} - -#if ( FIX_RENUM_BUG_FOR_CASE_OF_ACIDIC_OH_AT_P_PLUS == 1 ) -void update_some_attype_totals(int nAtTypeTotals[], int mask, int delta, S_CHAR at_charge); -/****************************************************************************/ -void update_some_attype_totals(int nAtTypeTotals[], int mask, int delta, S_CHAR at_charge) -{ - int i; - int32_t bit; /* djb-rwth: fixing coverity CID #499534 */ - if (nAtTypeTotals) - { - if (mask && !(mask & (ATBIT_Errors))) - { - for (i = 0, bit = 1; i < ATTOT_ARRAY_LEN; i++, bit <<= 1) - { - if (bit & mask) - { - nAtTypeTotals[i] += delta; - } - } - } - /* Count charges */ - if (at_charge) - { - nAtTypeTotals[ATTOT_TOT_CHARGE] += delta * at_charge; - nAtTypeTotals[ATTOT_NUM_CHARGES] += delta; - } - } - return; -} -#endif -/****************************************************************************/ -int GetAtomChargeType( inp_ATOM *atom, - int at_no, - int nAtTypeTotals[], - int *pMask, - int bSubtract ) -{ - - inp_ATOM *at = atom + at_no; -#if ( FIX_NORM_BUG_ADD_ION_PAIR == 1 ) - int i, neigh, mask, type, num_z, num_m, num_o, delta = bSubtract > 0 ? -1 : 1; /* 0 or -2 => add, 1 or 2 => subtract */ - int32_t bit; /* djb-rwth: fixing coverity CID #499579 */ - int bNoAdjIon = ( bSubtract == 0 || bSubtract == 1 ); -#else - int i, neigh, mask, bit, type, num_z, num_m, num_o, delta = bSubtract ? -1 : 1; -#endif - int bUnsatNHasTerminalO = 0; - - type = ATT_NONE; - mask = 0; - - if (at->radical && at->radical != RADICAL_SINGLET) - { - goto exit_function; - } - - if (is_el_a_metal( at->el_number )) - { - goto exit_function; - } - if (at->charge < -1 || at->charge > 1) - { - goto exit_function; - } - - if (!at->valence && at->charge == 1 && !at->num_H && !at->radical && at->el_number == EL_NUMBER_H) - { - /* a proton H+ (#1) */ - type = ATT_PROTON; - mask = ATBIT_Proton; - goto count_mask_bits; - } - - if ( !at->valence && at->charge == -1 && - !at->num_H && !at->radical && - ( at->el_number == EL_NUMBER_F || at->el_number == EL_NUMBER_CL || - at->el_number == EL_NUMBER_BR || at->el_number == EL_NUMBER_I ) - ) - { - /* a halogen anion Hal- (#2) */ - type = ATT_HalAnion; - mask = ATBIT_HalAnion; - goto count_mask_bits; - } -#if ( HAL_ACID_H_XCHG == 1 ) - /* halogen/chalcogen acid */ - if ((!at->valence && at->charge == 0 && 1 == at->num_H && !at->radical && - ( at->el_number == EL_NUMBER_F || - at->el_number == EL_NUMBER_CL || - at->el_number == EL_NUMBER_BR || - at->el_number == EL_NUMBER_I )) || - (!at->valence && at->charge == 0 && 2 == at->num_H && !at->radical && - ( at->el_number == EL_NUMBER_O || - at->el_number == EL_NUMBER_S || - at->el_number == EL_NUMBER_SE || - at->el_number == EL_NUMBER_TE )) /* djb-rwth: addressing LLVM warning */ - ) - { - /* a halogen/chalcogen acid (#3) */ - type = ATT_HalAcid; - mask = ATBIT_HalAcid; - goto count_mask_bits; - } -#endif - - if (detect_unusual_el_valence( at->el_number, at->charge, at->radical, - at->chem_bonds_valence, at->num_H, at->valence )) - { - goto exit_function; /* unusual valence state */ - } - - /* Check neighbors */ - for (i = 0, num_z = 0, num_m = 0, num_o = 0; i < at->valence; i++) - { - neigh = at->neighbor[i]; -#if ( FIX_NORM_BUG_ADD_ION_PAIR == 1 ) - if (atom[neigh].charge < -1 || atom[neigh].charge > 1) - { - goto exit_function; /* neighboring charge */ - } - if (atom[neigh].charge && at->charge) - { - if (bNoAdjIon) - { -#if ( FIX_RENUM_BUG_FOR_CASE_OF_ACIDIC_OH_AT_P_PLUS == 1 ) - goto count_mask_bits; - /*update_some_attype_totals(nAtTypeTotals, mask, delta, at->charge);*/ -#endif - goto exit_function; /* neighboring charge */ - } - type = ATT_NONE; - mask = 0; - goto count_mask_bits; - } -#else - if (atom[neigh].charge < -1 || atom[neigh].charge > 1 || atom[neigh].charge && at->charge) - { - goto exit_function; /* neighboring charge */ - } -#endif - if (detect_unusual_el_valence( atom[neigh].el_number, atom[neigh].charge, atom[neigh].radical, - atom[neigh].chem_bonds_valence, atom[neigh].num_H, - atom[neigh].valence )) - { - /* neighbor in unusual valence state */ - goto exit_function; - } - if (is_Z_atom( atom[neigh].el_number )) - { - num_z++; - } - if (is_el_a_metal( atom[neigh].el_number )) - { - num_m++; - } - num_o += ( atom[neigh].el_number == EL_NUMBER_O ); - if (at->el_number == EL_NUMBER_N && at->valence == 2 && !at->charge && - /*at->valence < at->chem_bonds_valence &&*/ - atom[neigh].valence == 1 && atom[neigh].chem_bonds_valence == 2 && - ( atom[neigh].el_number == EL_NUMBER_O || - atom[neigh].el_number == EL_NUMBER_S || - atom[neigh].el_number == EL_NUMBER_SE || - atom[neigh].el_number == EL_NUMBER_TE )) - { - bUnsatNHasTerminalO++; - } - } /* eof check neighbors */ - - /* O, S, Se, Te */ - if ( at->el_number == EL_NUMBER_O || - at->el_number == EL_NUMBER_S || - at->el_number == EL_NUMBER_SE || - at->el_number == EL_NUMBER_TE ) - { - if (at->charge == 1) - { - if (at->num_H) - { - /* #4 */ - type = ATT_O_PLUS; - mask |= ATBIT_OH_Plus; - } - else - { - /* #5 */ - type = ATT_O_PLUS; - mask |= ATBIT_O_Plus; - } - } - else - { - /* at->charge != 1 */ - if (at->valence > 1) - { - goto exit_function; /* not a terminal atom #C1 */ - } - else - { - if (at->valence && !( num_z || num_o )) - { - if (num_m == at->valence) - { - goto exit_function; /* #C2 */ - } - goto count_mask_bits; /* #C3 count charges, no donor or acceptor found */ - } - else - { - /* Here at->neigh[0] is one of: O, or Z={C, N, P, As, Sb, S, Se, Te, Cl, Br, I} */ - if (at->valence) - { - neigh = at->neighbor[0]; /* Z or O only */ - if (!atom[neigh].charge && atom[neigh].el_number == EL_NUMBER_C && - atom[neigh].chem_bonds_valence > atom[neigh].valence) - { - /* =C-OH, #C-OH, =C-O(-), #C-O(-), -C=O, =C=O; O = O, S, Se, Te */ - type = ATT_ACIDIC_CO; - if (at->num_H == 1) - { - mask |= ( ATBIT_COH ); /* #6: =C-OH, #C-OH; O=O,S,Se,Te */ - /*nAtTypeTotals[ATTOT_NUM_COH] ++;*/ - } - else - { - if (at->charge == -1) - { - mask |= ( ATBIT_CO_Minus ); /* #7: =C-O(-), #C-O(-); O=O,S,Se,Te */ - /*nAtTypeTotals[ATTOT_NUM_CO_Minus] ++;*/ - } - else - { - if (!at->num_H && !at->charge) - { - mask |= ( ATBIT_CO ); /* #8 -C=O, =C=O; O=O,S,Se,Te */ - /*nAtTypeTotals[ATTOT_NUM_CO] ++;*/ - } - else - { - mask |= ( ATBIT_Errors ); - /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ - } - } - } - } - else - { - if (!atom[neigh].charge && - ( atom[neigh].el_number == EL_NUMBER_O || - atom[neigh].el_number == EL_NUMBER_S || - atom[neigh].el_number == EL_NUMBER_SE || - atom[neigh].el_number == EL_NUMBER_TE ) && - atom[neigh].chem_bonds_valence == atom[neigh].valence) - { - /* -O-OH, -O-O(-); O = O, S, Se, Te */ - type = ATT_OO; - if (at->num_H == 1) - { - mask |= ( ATBIT_OOH ); /* #9 -O-OH */ - /*nAtTypeTotals[ATTOT_NUM_OOH] ++;*/ - } - else - { - if (at->charge == -1) - { - mask |= ( ATBIT_OO_Minus ); /* #10 -O-O(-) */ - /*nAtTypeTotals[ATTOT_NUM_OO_Minus] ++;*/ - } - else - { - mask |= ( ATBIT_Errors ); - /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ - } - } - } - else - { - if (!atom[neigh].charge && - atom[neigh].chem_bonds_valence == atom[neigh].valence && - atom[neigh].el_number == EL_NUMBER_C && - at->el_number != EL_NUMBER_O) - { - /* >C-S(-), >C-SH; S = S, Se, Te */ - type = ATT_ACIDIC_S; - if (at->num_H == 1) - { - mask |= ( ATBIT_CSH ); /* #11: >C-SH, >CH-SH, -CH2-SH; S = S, Se, Te */ - /*nAtTypeTotals[ATTOT_NUM_CSH] ++;*/ - } - else - { - if (at->charge == -1) - { - mask |= ( ATBIT_CS_Minus ); /* #12: >C-S(-), >CH-S(-), -CH2-S(-); S = S, Se, Te */ - /*nAtTypeTotals[ATTOT_NUM_CS_Minus] ++;*/ - } - else - { - mask |= ( ATBIT_Errors ); - /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ - } - } - } - else - { - if (atom[neigh].el_number == EL_NUMBER_N && - atom[neigh].valence == 2 && - ( !atom[neigh].num_H || (atom[neigh].num_H == 1 && atom[neigh].charge == 1) )) /* djb-rwth: addressing LLVM warning */ - { - /* N or N(-) or NH(+) neighbor */ - type = ATT_NO; /* single bond only */ - if (at->num_H == 1) - { - mask |= ( ATBIT_NOH ); /* #13: =N-OH, =NH(+)-OH, #N(+)-OH, -N(-)-OH; O = O, S, Se, Te */ - /*nAtTypeTotals[ATTOT_NUM_NOH] ++;*/ - } - else - { - if (at->charge == -1) - { - mask |= ( ATBIT_NO_Minus ); /* #14: =N-O(-); O = O, S, Se, Te */ - /*nAtTypeTotals[ATTOT_NUM_NO_Minus] ++;*/ - } - else - { - if (atom[neigh].charge == 1 || atom[neigh].charge == 0) - { - mask |= ( ATBIT_NO ); /* #15: =N(+)=O, -NH(+)=O -N=O */ - /*nAtTypeTotals[ATTOT_NUM_NO] ++;*/ - } - else - { - mask |= ( ATBIT_Errors ); - /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ - } - } - } - } - else - { - if (atom[neigh].el_number == EL_NUMBER_N) - { - type = ATT_N_O; /* #16: single bond only */ - if (at->num_H == 1) - { - mask |= ( ATBIT_N_OH ); /* #16: -NH-OH, >N-OH or >N(+)charge == -1) - { - mask |= ( ATBIT_N_O_Minus ); /* #17: -NH-O(-), >N-O(-); O = O, S, Se, Te */ - /*nAtTypeTotals[ATTOT_NUM_NO_Minus] ++;*/ - } - else - { - if (atom[neigh].charge == 1) - { - mask |= ( ATBIT_N_O ); /* #18: >N(+)=O */ - /*nAtTypeTotals[ATTOT_NUM_NO] ++;*/ - } - else - { - mask |= ( ATBIT_Errors ); - /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ - } - } - } - } - else - { - if ( atom[neigh].el_number != EL_NUMBER_C && - atom[neigh].el_number != EL_NUMBER_O && - !is_el_a_metal( atom[neigh].el_number ) && - atom[neigh].chem_bonds_valence > atom[neigh].valence) - { - /* =Z-OH, #Z-OH, =Z-O(-), #Z-O(-), -Z=O, =Z=O; - =Z(+)-OH, #Z(+)-OH, =Z-O(-), #Z-O(-), -Z(+)=O, =Z(+)=O; O = O, S, Se, Te */ - /* neigh = Z\{N,C} = P, As, Sb, S, Se, Te, Cl, Br, I */ - if (at->chem_bonds_valence == 1 && IsZOX( atom, at_no, 0 )) - { - type = ATT_ZOO; - if (at->num_H == 1) - { - mask |= ( ATBIT_ZOOH ); /* 18: O=Z-OH; O=O,S,Se,Te; Z may have charge */ - /*nAtTypeTotals[ATTOT_NUM_ZOOH] ++;*/ - } - else - { - if (at->charge == -1) - { - mask |= ( ATBIT_ZOO_Minus ); /* 19: O=Z-O(-); O = O, S, Se, Te */ - /*nAtTypeTotals[ATTOT_NUM_ZOO_Minus] ++;*/ - } - else - { - mask |= ( ATBIT_Errors ); - /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ - } - } - } - else - { - type = ATT_OTHER_ZO; - if (at->num_H == 1) - { - mask |= ( ATBIT_ZOH ); /* 20: =Z-OH, #Z-OH; O=O,S,Se,Te; Z may have charge */ - /*nAtTypeTotals[ATTOT_NUM_ZOH] ++;*/ - } - else - { - if (at->charge == -1) - { - mask |= ( ATBIT_ZO_Minus ); /* 21: =Z-O(-), #Z-O(-); O = O, S, Se, Te */ - /*nAtTypeTotals[ATTOT_NUM_ZO_Minus] ++;*/ - } - else - { - if (at->num_H == 0) - { - mask |= ( ATBIT_ZO ); /* 22: -Z=O, =Z=O; O=O,S,Se,Te; Z may have charge */ - /*nAtTypeTotals[ATTOT_NUM_ZO] ++;*/ - } - else - { - mask |= ( ATBIT_Errors ); - /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ - } - } - } - } - } - else - { - if (at->charge == -1 && !is_el_a_metal( atom[neigh].el_number )) - { - /* >Z-O(-); O=O,S,Se,Te */ - type = ATT_OTHER_NEG_O; - mask |= ( ATBIT_O_Minus ); /* 23: -Z-O(-); O=O,S,Se,Te */ - /*nAtTypeTotals[ATTOT_NUM_ZO_Minus] ++;*/ - } - } - } - } - } - } - } - } - - else - { - if (at->charge == -1 && at->num_H == 1) - { - type = ATT_OH_MINUS; - mask |= ( ATBIT_O_Minus ); /* 25: HO(-); O=O,S,Se,Te */ - } - } - } - } - } - } - - else - { - /* P, N, neutral valence = 3 (not 5) */ - if (( at->el_number == EL_NUMBER_N || - at->el_number == EL_NUMBER_P ) && - 0 <= at->valence && at->valence <= 3 && - at->chem_bonds_valence + at->num_H == 3 + at->charge) - { - if (at->valence && !( num_z /*|| num_o == at->valence*/ )) - { - if (num_m == at->valence) - { - goto exit_function; - } - goto count_mask_bits; /* N(III), N(-)(II), N(+)(IV) and same P that have only oxygen neighbors are ignored here */ - } - type = ( at->el_number == EL_NUMBER_N ) ? ATT_ATOM_N : ATT_ATOM_P; - switch (at->charge) - { - case -1: - if (at->el_number == EL_NUMBER_N) - { - mask |= ( ATBIT_N_Minus ); /* 26: -NH(-), =N(-), >N(-) */ - if (at->num_H) - { - mask |= ( ATBIT_NP_H ); /* 27: -NH(-) */ - } -#if ( FIX_NP_MINUS_BUG == 1 ) - else - { - if (at->valence == 1 && at->chem_bonds_valence >= 2 && ( at->bond_type[0] & BOND_MARK_ALL )) - { - type |= ATT_NP_MINUS_V23; /* =N(-) created by normalization 2010-03-11 DT */ - } - } -#endif - } - /*nAtTypeTotals[ATTOT_NUM_N_Minus] += (at->el_number == EL_NUMBER_N);*/ - break; - case 0: - if (at->num_H) - { - mask |= ( ATBIT_NP_H ); /* 28: -NH2, =NH, >NH */ - /*nAtTypeTotals[ATTOT_NUM_NP_H] ++;*/ - } - else - { - if (bUnsatNHasTerminalO == 1) - { - mask |= ( ATBIT_ON ); /* 29: -N=O,-N=OH(+) only, not =N-OH */ - } - else - { - mask |= ( ATBIT_NP ); /* 30: -P=O,-P=OH(+), >N- =N- (incl. =N-OH) , #N */ - /*nAtTypeTotals[ATTOT_NUM_NP] ++;*/ - } - } - break; /* ignore neutral N or P */ - case 1: - if (at->num_H) - { - mask |= ( ATBIT_NP_Proton ); /* 31: NH4(+), -NH3(+), =NH2(+), >NH2(+), =NH(+)-, >NH(+)-, #NH(+) */ - /*nAtTypeTotals[ATTOT_NUM_NP_Proton] ++;*/ - } - else - { - if (at->chem_bonds_valence > at->valence) - { - mask |= ( ATBIT_NP_Plus ); /* =N(+)=, #N(+)-, =N(+)< */ - /*nAtTypeTotals[ATTOT_NUM_NP_Plus] ++;*/ - } - else - { - type = 0; /* 32: ignore onium cations >N(+)< */ - } - } - break; - default: - mask |= ( 1 << ATTOT_NUM_Errors ); - /*nAtTypeTotals[ATTOT_NUM_Errors] ++;*/ - break; - } - } - } - -count_mask_bits: - if (nAtTypeTotals) - { - if (mask && !( mask & ( ATBIT_Errors ) )) - { - for (i = 0, bit = 1; i < ATTOT_ARRAY_LEN; i++, bit <<= 1) - { - if (bit & mask) - { - nAtTypeTotals[i] += delta; - } - } - } - - /* Count charges */ - if (at->charge) - { - nAtTypeTotals[ATTOT_TOT_CHARGE] += delta * at->charge; - nAtTypeTotals[ATTOT_NUM_CHARGES] += delta; - } - } - - if (pMask) - { - *pMask = mask; - } - -exit_function: - if (mask & ( ATBIT_Errors )) - { - type = 0; - if (nAtTypeTotals) - { - nAtTypeTotals[ATTOT_NUM_Errors] += 1; - } - } - - - return type; -} - - -/****************************************************************************/ -int SimpleRemoveHplusNPO( inp_ATOM *at, - int num_atoms, - int nAtTypeTotals[], - T_GROUP_INFO *t_group_info ) -{ - int i, mask, type, num_removed; - for (i = 0, num_removed = 0; i < num_atoms; i++) - { - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - if (( PR_SIMPLE_TYP & ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) ) ) && - ( PR_SIMPLE_MSK & mask )) - { -#if ( bRELEASE_VERSION == 0 ) - if (at[i].charge != 1 || at[i].num_H == 0) - { - return -1; /* program error */ - } -#endif - type = GetAtomChargeType(at, i, nAtTypeTotals, &mask, 1); /* subtract at[i] */ /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - at[i].charge = 0; - AddOrRemoveExplOrImplH( -1, at, num_atoms, (AT_NUMB) i, t_group_info ); - /*at[i].num_H --;*/ - num_removed++; -#if ( FIX_NORM_BUG_ADD_ION_PAIR == 1 ) - type = GetAtomChargeType(at, i, nAtTypeTotals, &mask, 0); /* add changed at[i] */ /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ -#else - type = GetAtomChargeType(at, i, nAtTypeTotals, &mask, 1); /* bug: subtract instead of add */ /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ -#endif - /* - if ( nAtTypeTotals ) { - nAtTypeTotals[ATTOT_NUM_NP_Proton] --; - if ( at[i].num_H ) { - nAtTypeTotals[ATTOT_NUM_NP_H] ++; - } else { - nAtTypeTotals[ATTOT_NUM_NP] ++; - } - nAtTypeTotals[ATTOT_TOT_CHARGE] --; - nAtTypeTotals[ATTOT_NUM_CHARGES] --; - } - */ - } - } - - return num_removed; -} - - -/****************************************************************************/ -int bIsAtomTypeHard( inp_ATOM *at, - int endpoint, - int nType, - int nMask, - int nCharge ) -{ - int mask; - if (( nType & GetAtomChargeType( at, endpoint, NULL, &mask, 0 ) ) && ( mask & nMask ) -#if ( OPPOSITE_CHARGE_IN_CGROUP == 0 ) - && ( at[endpoint].charge == nCharge || !at[endpoint].charge ) -#endif - ) - { - return 1; - } - - return 0; -} - - -/****************************************************************************/ -int bIsHDonorAccAtomType( inp_ATOM *at, int endpoint, int *cSubType ) -{ - if (bIsAtomTypeHard( at, endpoint, PR_HARD_TYP_H, PR_HARD_MSK_H, 0 )) - { - /* Obtain donor/acceptor info */ - int neutral_valence = at[endpoint].chem_bonds_valence + at[endpoint].num_H - at[endpoint].charge; - if (neutral_valence != 2 /* O, S, Se, Te */ && - neutral_valence != 3 /* N, P */) - { - return -1; /* wrong endpoint neutral valence */ - } - else - { - int edge_flow = at[endpoint].num_H; - int num_bonds = at[endpoint].valence; - int edge_cap = neutral_valence - num_bonds; /* does not allow to reduce -NH3(+) to #N or -OH(+)- to -O- */ - edge_flow = inchi_min( edge_flow, edge_cap ); - /* what this means: */ - if (edge_cap) - { - if (edge_cap > edge_flow) - { - *cSubType |= SALT_ACCEPTOR; - } - if (edge_flow) - { - *cSubType |= SALT_DONOR_H; - } - return 4; - } - } - } - - return -1; -} - - -/****************************************************************************/ -int bIsNegAtomType( inp_ATOM *at, int endpoint, int *cSubType ) -{ - int sub_type = 0; - if (bIsAtomTypeHard( at, endpoint, PR_HARD_TYP_NEG, PR_HARD_MSK_NEG, -1 )) - { - /* Obtain donor/acceptor info */ - int neutral_valence = at[endpoint].chem_bonds_valence + at[endpoint].num_H - at[endpoint].charge; - if (neutral_valence != 2 /* O, S, Se, Te */ && - neutral_valence != 3 /* N, P */) - { - return -1; /* wrong endpoint neutral valence */ - } - else - { - int edge_flow = ( at[endpoint].charge == -1 ); - int num_bonds = at[endpoint].valence; - int edge_cap = neutral_valence - num_bonds - at[endpoint].num_H; /* does not allow to reduce -NH3(+) to #N or -OH(+)- to -O- */ - edge_flow = inchi_min( edge_flow, edge_cap ); - /* what this means: */ - if (edge_cap) - { - if (edge_cap > edge_flow) - { - sub_type |= SALT_ACCEPTOR; - } - if (edge_flow) - { - sub_type |= SALT_DONOR_Neg; - } - if (sub_type) - { - *cSubType |= sub_type; - return 4; - } - } - } - } - - return -1; -} - - -/****************************************************************************/ -int bIsHardRemHCandidate( inp_ATOM *at, int i, int *cSubType ) -{ - int ret1, ret2, ret; - int sub_type = 0; - ret1 = bIsHDonorAccAtomType( at, i, &sub_type ); - ret2 = bIsNegAtomType( at, i, &sub_type ); - ret = inchi_max( ret1, ret2 ); - if (ret > 0 && sub_type) - { - *cSubType |= sub_type; - return ret; - } - return -1; -} - - -/****************************************************************************/ -int CreateCGroupInBnStruct( inp_ATOM *at, - int num_atoms, - BN_STRUCT *pBNS, - int nType, - int nMask, - int nCharge ) -{ - int k, c_point, cg, centerpoint, fictpoint, type, ret = 0; - int num_cg = 1; - int num_edges = pBNS->num_edges; - int num_vertices = pBNS->num_vertices; /* new c-group bns-ID */ - BNS_VERTEX *vert_ficpoint, *ver_ficpont_prev; /* fictitious vertex describing charge c-group */ - BNS_VERTEX *vertex_cpoint; - BNS_EDGE *edge; /* edge between that vertex and the tautomeric c_point */ - int mask, num_CPoints; - - /* Debug: check overflow */ - if (num_vertices + num_cg >= pBNS->max_vertices) - { - return BNS_VERT_EDGE_OVFL; - } - - /* Count new c-group edges */ - for (c_point = 0, num_CPoints = 0; c_point < num_atoms; c_point++) - { - if (( nType & GetAtomChargeType( at, c_point, NULL, &mask, 0 ) ) && ( mask & nMask ) -#if ( OPPOSITE_CHARGE_IN_CGROUP == 0 ) - && ( at[c_point].charge == nCharge || !at[c_point].charge ) -#endif - ) - { - num_CPoints++; - } - } - - if (!num_CPoints) - { - return 0; - } - - /* Clear the new vertex */ - memset( pBNS->vert + num_vertices, 0, 1 * sizeof( pBNS->vert[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - - /* *old* Make sure the last t-group has the largest t-group ID: - this is necessary to correctly add new edges and vertices for testing augmenting paths - */ - - /**************************************/ - /* initialize new fictitious vertex */ - /* representing c-point group */ - /**************************************/ - - ver_ficpont_prev = pBNS->vert + num_vertices - 1; - - for (cg = 0; cg < num_cg; cg++, ver_ficpont_prev = vert_ficpoint) - { - /* - vert_ficpoint-1 is the last vertex; - vert_ficpoint is the being added vertex - Note: nGroupNumber are not contiguous - */ - vert_ficpoint = pBNS->vert + num_vertices + cg; - vert_ficpoint->iedge = ver_ficpont_prev->iedge + ver_ficpont_prev->max_adj_edges; - vert_ficpoint->max_adj_edges = num_CPoints + BNS_ADD_EDGES; - vert_ficpoint->num_adj_edges = 0; - vert_ficpoint->st_edge.flow = vert_ficpoint->st_edge.flow0 = 0; - vert_ficpoint->st_edge.cap = vert_ficpoint->st_edge.cap0 = 0; - vert_ficpoint->type = BNS_VERT_TYPE_C_GROUP | ( ( nCharge < 0 ) ? BNS_VERT_TYPE_C_NEGATIVE : 0 ); - } - - /************************************************/ - /* Connect c-points to the fictitious vertices */ - /* representing c-point groups; set caps, flows */ - /************************************************/ - cg = 1; - for (c_point = 0; c_point < num_atoms; c_point++) - { - if (( nType & ( type = GetAtomChargeType( at, c_point, NULL, &mask, 0 ) ) ) && ( mask & nMask ) -#if ( OPPOSITE_CHARGE_IN_CGROUP == 0 ) - && ( at[c_point].charge == nCharge || !at[c_point].charge ) -#endif - ) - { - ; - } - else - { - continue; - } - - fictpoint = cg + num_vertices - 1; /* c-group vertex index */ - vert_ficpoint = pBNS->vert + fictpoint; /* c-group vertex */ - vertex_cpoint = pBNS->vert + c_point; /* c_point vertex */ - - /* Debug: check overflow */ - if (fictpoint >= pBNS->max_vertices || - num_edges >= pBNS->max_edges || - vert_ficpoint->num_adj_edges >= vert_ficpoint->max_adj_edges || - vertex_cpoint->num_adj_edges >= vertex_cpoint->max_adj_edges) - { - /* djb-rwth: removing redundant code */ - break; - } - vertex_cpoint->type |= BNS_VERT_TYPE_C_POINT; - if (( KNOWN_ACIDIC_TYPE & type ) && nCharge < 0) - { - vertex_cpoint->type |= pBNS->type_TACN; - } - -#if ( FIX_CPOINT_BOND_CAP != 1 ) /* { */ - /* Set capacity = 1 to the edges from the c_point to the centerpoint(s) */ - /* if their current capacity is zero */ - /* the centerpoint is any adjacent atom that is adjacent to a multiple bond */ - for (k = 0; k < vertex_cpoint->num_adj_edges; k++) - { - int iedge = vertex_cpoint->iedge[k]; - if (!pBNS->edge[iedge].cap) - { - /* single bond, possibly between c_point and centerpoint */ - centerpoint = ( pBNS->edge[iedge].neighbor12 ^ c_point ); - if (centerpoint < pBNS->num_atoms && - pBNS->vert[centerpoint].st_edge.cap >= 1) - { - int bond_type = ( at[c_point].bond_type[k] & BOND_TYPE_MASK ); - if (bond_type == BOND_TAUTOM || - bond_type == BOND_ALTERN || - bond_type == BOND_SINGLE) - { - pBNS->edge[iedge].cap = 1; - } - } - } - } -#endif /* } FIX_CPOINT_BOND_CAP */ - - /* Create a new edge connecting c_point to the new fictitious c-group vertex vert_ficpoint */ - edge = pBNS->edge + num_edges; - edge->cap = 1; - edge->flow = 0; - edge->pass = 0; -#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) - edge->forbidden &= pBNS->edge_forbidden_mask; /* remove previous temporary ban */ -#endif - - /* nCharge = +1: mark edge to c-point having no (+)-moveable charge with flow=1 */ - /* nCharge = -1: mark edge to c-point having -1 moveable charge with flow=1 */ - - if ((nCharge == 1 && at[c_point].charge != 1) || (nCharge == -1 && at[c_point].charge == -1)) /* djb-rwth: addressing LLVM warning */ - /*if ( !CHARGED_CPOINT(at,c_point) )*/ - { - /* Increment new edge flow, update st_edges of the adjacent vertices */ - edge->flow++; - /* Increment c-group vertex st-flow & cap */ - vert_ficpoint->st_edge.flow++; - vert_ficpoint->st_edge.cap++; - /* Increment c-point vertex st-flow & cap */ - vertex_cpoint->st_edge.flow++; - vertex_cpoint->st_edge.cap++; - } - -#if ( FIX_CPOINT_BOND_CAP == 1 ) /* { */ - /* Set capacity = 1 to the edges from the c_point to the centerpoint(s) */ - /* if their current capacity is zero */ - /* the centerpoint is any adjacent atom that is adjacent to a multiple bond */ - for (k = 0; k < vertex_cpoint->num_adj_edges; k++) - { - int iedge = vertex_cpoint->iedge[k]; - VertexFlow nNewCap = vertex_cpoint->st_edge.cap; - centerpoint = ( pBNS->edge[iedge].neighbor12 ^ c_point ); - if (!pBNS->edge[iedge].cap) - { - /* Single bond, possibly between c_point and centerpoint */ - if (centerpoint < pBNS->num_atoms && - pBNS->vert[centerpoint].st_edge.cap >= 1) - { - nNewCap = inchi_min( pBNS->vert[centerpoint].st_edge.cap, nNewCap ); - nNewCap = inchi_min( nNewCap, MAX_BOND_EDGE_CAP ); - pBNS->edge[iedge].cap = nNewCap; - } - } -#if ( FIX_CPOINT_BOND_CAP2 == 1 ) /* multiple bond */ - else - { - if (centerpoint < pBNS->num_atoms && - edge->flow && pBNS->edge[iedge].cap < MAX_BOND_EDGE_CAP) - { - pBNS->edge[iedge].cap++; - } - } -#endif - } -#endif /* } FIX_CPOINT_BOND_CAP */ - - /* Connect edge to c_point and fictpoint and increment the counters of neighbors and edges */ - edge->neighbor1 = c_point; /* the smallest out of v1=endopoint and v2=num_vertices */ - edge->neighbor12 = c_point ^ fictpoint; /* v1 ^ v2 */ - vertex_cpoint->iedge[vertex_cpoint->num_adj_edges] = num_edges; - vert_ficpoint->iedge[vert_ficpoint->num_adj_edges] = num_edges++; - edge->neigh_ord[0] = vertex_cpoint->num_adj_edges++; - edge->neigh_ord[1] = vert_ficpoint->num_adj_edges++; - edge->cap0 = edge->cap; - edge->flow0 = edge->flow; - } - - ret = pBNS->num_vertices; /* new c-group atom number */ - pBNS->num_edges = num_edges; - pBNS->num_vertices += num_cg; - pBNS->num_c_groups += num_cg; - - return ret; -} - - -/****************************************************************************/ -int CreateTGroupInBnStruct( inp_ATOM *at, - int num_atoms, - BN_STRUCT *pBNS, - int nType, - int nMask ) -{ - int ret = 0; - /* ret = ReInitBnStruct( pBNS ); */ - int k, endpoint, tg, centerpoint, fictpoint; - int num_tg = 1; - int num_edges = pBNS->num_edges; - int num_vertices = pBNS->num_vertices; - BNS_VERTEX *vert_ficpoint, *ver_ficpont_prev; /* fictitious vertex describing t-group */ - BNS_VERTEX *vert_endpoint; - BNS_EDGE *edge; /* edge between that vertex and the tautomeric endpoint */ - int mask, num_endpoints, neutral_valence, edge_flow, edge_cap, num_bonds; - - /* Debug: check overflow */ - if (num_vertices + num_tg >= pBNS->max_vertices) - { - return BNS_VERT_EDGE_OVFL; - } - - /* Count new t-group edges */ - for (endpoint = 0, num_endpoints = 0; endpoint < num_atoms; endpoint++) - { - if (( nType & GetAtomChargeType( at, endpoint, NULL, &mask, 0 ) ) && ( mask & nMask ) - ) - { - num_endpoints++; - } - } - - if (!num_endpoints) - { - return 0; - } - - /* Since t-group IDs may be not contiguous, clear all vertices that will be added. - all-zeroes-vertex will be ignored by the BNS - */ - memset( pBNS->vert + num_vertices, 0, num_tg * sizeof( pBNS->vert[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - - /* *old* Make sure the last t-group has the largest t-group ID: - this is necessary to correctly add new edges and vertices for testing augmenting paths - */ - - /**************************************/ - /* Initialize new fictitious vertex */ - /* representing t-point group */ - /**************************************/ - ver_ficpont_prev = pBNS->vert + num_vertices - 1; - - for (tg = 0; tg < num_tg; tg++, ver_ficpont_prev = vert_ficpoint) - { - /* - vert_ficpoint-1 is the last vertex; - vert_ficpoint is the vertex that is being added - Note: nGroupNumber are not contiguous - */ - vert_ficpoint = pBNS->vert + num_vertices + tg; - vert_ficpoint->iedge = ver_ficpont_prev->iedge + ver_ficpont_prev->max_adj_edges; - vert_ficpoint->max_adj_edges = num_endpoints + BNS_ADD_EDGES + BNS_ADD_SUPER_TGROUP; - vert_ficpoint->num_adj_edges = 0; - vert_ficpoint->st_edge.flow = vert_ficpoint->st_edge.flow0 = 0; - vert_ficpoint->st_edge.cap = vert_ficpoint->st_edge.cap0 = 0; - vert_ficpoint->type |= BNS_VERT_TYPE_TGROUP; - } - - tg = 1; - for (endpoint = 0; endpoint < num_atoms; endpoint++) - { - if (( nType & GetAtomChargeType( at, endpoint, NULL, &mask, 0 ) ) && ( mask & nMask )) - { - ; - } - else - { - continue; - } - fictpoint = tg + num_vertices - 1; - vert_ficpoint = pBNS->vert + fictpoint; - vert_endpoint = pBNS->vert + endpoint; - /* Debug: check overflow */ - if (fictpoint >= pBNS->max_vertices || - num_edges >= pBNS->max_edges || - vert_ficpoint->num_adj_edges >= vert_ficpoint->max_adj_edges || - vert_endpoint->num_adj_edges >= vert_endpoint->max_adj_edges) - { - /* djb-rwth: removing redundant code */ - break; - } - - /* Obtain donor/acceptor info */ - neutral_valence = at[endpoint].chem_bonds_valence + at[endpoint].num_H - at[endpoint].charge; - if (neutral_valence != 2 /* O, S, Se, Te */ && - neutral_valence != 3 /* N, P */) - { - /* djb-rwth: removing redundant code */ - break; - } - edge_flow = at[endpoint].num_H; - num_bonds = at[endpoint].valence; - edge_cap = neutral_valence - num_bonds; /* does not allow to reduce -NH3(+) to #N or -OH(+)- to -O- */ - - if (3 == neutral_valence /* N or P */ && 1 < num_bonds) - { - edge_cap++; /* allow -NH2(+)- => -N=, >NH(+)- => >N- */ - } - edge_flow = inchi_min( edge_flow, edge_cap ); - /* - if ( !nGetEndpointInfo( at, endpoint, &eif ) ) { - ret = BNS_BOND_ERR; - break; - } - */ - vert_endpoint->type |= BNS_VERT_TYPE_ENDPOINT; - - /* Create a new edge connecting endpoint to the new fictitious t-group vertex vert_ficpoint */ - edge = pBNS->edge + num_edges; - edge->cap = edge_cap; - edge->flow = edge_flow; - edge->pass = 0; -#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) - edge->forbidden &= pBNS->edge_forbidden_mask; -#endif - - /* Adjust st_flow and st_cap of the adjacent vertices */ - /* Adjust t-group vertex st-flow & cap */ - vert_ficpoint->st_edge.flow += edge->flow; - vert_ficpoint->st_edge.cap += edge->flow; - /* adjust endpoint vertex st-flow & cap */ - vert_endpoint->st_edge.flow += edge->flow; - vert_endpoint->st_edge.cap += edge->flow; - - /* Adjust edge cap & flow according to the number of H and number of bonds */ - for (k = 0; k < vert_endpoint->num_adj_edges; k++) - { - int iedge = vert_endpoint->iedge[k]; - VertexFlow nNewCap = vert_endpoint->st_edge.cap; - if (!pBNS->edge[iedge].cap) - { - /* single bond, possibly between endpoint and centerpoint */ - centerpoint = ( pBNS->edge[iedge].neighbor12 ^ endpoint ); - if (centerpoint < pBNS->num_atoms && - pBNS->vert[centerpoint].st_edge.cap >= 1) - { - nNewCap = inchi_min( pBNS->vert[centerpoint].st_edge.cap, nNewCap ); - nNewCap = inchi_min( nNewCap, MAX_BOND_EDGE_CAP ); - pBNS->edge[iedge].cap = nNewCap; - } - } - } - - /* Connect edge to endpoint and fictpoint and increment the counters of neighbors and edges */ - edge->neighbor1 = endpoint; /* the smallest out of v1=endopoint and v2=num_vertices */ - edge->neighbor12 = endpoint ^ fictpoint; /* v1 ^ v2 */ - vert_endpoint->iedge[vert_endpoint->num_adj_edges] = num_edges; - vert_ficpoint->iedge[vert_ficpoint->num_adj_edges] = num_edges++; - edge->neigh_ord[0] = vert_endpoint->num_adj_edges++; - edge->neigh_ord[1] = vert_ficpoint->num_adj_edges++; - edge->cap0 = edge->cap; - edge->flow0 = edge->flow; - } - - ret = pBNS->num_vertices; /* new t-group atom number */ - pBNS->num_edges = num_edges; - pBNS->num_vertices += num_tg; - pBNS->num_t_groups += num_tg; - - return ret; -} - - -/****************************************************************************/ -int RemoveLastGroupFromBnStruct( inp_ATOM *at, - int num_atoms, - int tg, - BN_STRUCT *pBNS ) -{ - int ret = 0; - /* ret = ReInitBnStruct( pBNS ); */ - int k, endpoint, /*centerpoint, fictpoint,*/ iedge; - int num_edges = pBNS->num_edges; - int num_vertices = pBNS->num_vertices; - BNS_VERTEX *vert_ficpoint /*, *ver_ficpont_prev*/; /* fictitious vertex describing t-group */ - BNS_VERTEX *vert_endpoint; - BNS_EDGE *edge; /* edge between that vertex and the tautomeric endpoint */ - /*int mask, num_endpoints, neutral_valence, edge_flow, edge_cap, num_bonds;*/ - int is_t_group = 0, is_c_group = 0; - - /* Debug: check overflow */ - if (pBNS->num_added_atoms + pBNS->num_c_groups + pBNS->num_t_groups + num_atoms >= pBNS->max_vertices) - { - return BNS_VERT_EDGE_OVFL; - } - - if (tg + 1 != num_vertices) - { - return BNS_VERT_EDGE_OVFL; - } - - vert_ficpoint = pBNS->vert + tg; - - if (vert_ficpoint->type & BNS_VERT_TYPE_TGROUP) - { - is_t_group = 1; - } - if (vert_ficpoint->type & BNS_VERT_TYPE_C_GROUP) - { - is_c_group = 1; - if (vert_ficpoint->type & BNS_VERT_TYPE_C_NEGATIVE) - { - is_c_group = 2; - } - } - - for (k = vert_ficpoint->num_adj_edges - 1; 0 <= k; k--) - { - iedge = vert_ficpoint->iedge[k]; - if (iedge + 1 != num_edges) - { - return BNS_VERT_EDGE_OVFL; - } - edge = pBNS->edge + iedge; - endpoint = edge->neighbor12 ^ tg; - vert_endpoint = pBNS->vert + endpoint; - /* adjust st_flow, st_cap */ - vert_endpoint->st_edge.cap0 = - vert_endpoint->st_edge.cap -= edge->flow; - vert_endpoint->st_edge.flow0 = - vert_endpoint->st_edge.flow -= edge->flow; - if (pBNS->type_TACN && ( vert_endpoint->type & pBNS->type_TACN ) == pBNS->type_TACN) - { - vert_endpoint->type ^= pBNS->type_TACN; - } - if (is_t_group) - { - vert_endpoint->type ^= ( vert_ficpoint->type & BNS_VERT_TYPE_ENDPOINT ); - } - if (is_c_group) - { - vert_endpoint->type ^= ( vert_ficpoint->type & BNS_VERT_TYPE_C_POINT ); - } - /* Remove edge */ - if (edge->neigh_ord[0] + 1 != vert_endpoint->num_adj_edges) - { - return BNS_VERT_EDGE_OVFL; - } - vert_endpoint->num_adj_edges--; - memset( edge, 0, sizeof( *edge ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - num_edges--; - if (1 == is_t_group && endpoint < num_atoms) - { - at->endpoint = 0; - } - if (1 == is_c_group && endpoint < num_atoms) - { - at->c_point = 0; - } - } - memset( vert_ficpoint, 0, sizeof( *vert_ficpoint ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - num_vertices--; - - pBNS->num_edges = num_edges; - pBNS->num_vertices = num_vertices; - if (is_t_group) - { - pBNS->num_t_groups--; - } - if (is_c_group) - { - pBNS->num_c_groups--; - } - - return ret; -} - - - -/****************************************************************************/ -int SetInitCapFlowToCurrent( BN_STRUCT *pBNS ) -{ - int i, j; - BNS_EDGE *pEdge = NULL; - for (i = 0; i < pBNS->num_vertices; i++) - { - pBNS->vert[i].st_edge.flow0 = pBNS->vert[i].st_edge.flow; - pBNS->vert[i].st_edge.cap0 = pBNS->vert[i].st_edge.cap; - for (j = 0; j < pBNS->vert[i].num_adj_edges; j++) - { - pEdge = pBNS->edge + pBNS->vert[i].iedge[j]; - pEdge->cap0 = pEdge->cap; - pEdge->flow0 = pEdge->flow; - } - } - - return 0; -} - - -int ArTypMask[] = -{ - AR_SIMPLE_TYP1, - AR_SIMPLE_MSK1, - AR_SIMPLE_TYP2, - AR_SIMPLE_MSK2, - AR_SIMPLE_TYP3, - AR_SIMPLE_MSK3, - 0, - 0 -}; - - - -/****************************************************************************/ -int SimpleRemoveAcidicProtons( inp_ATOM *at, - int num_atoms, - BN_AATG *pAATG, - int num2remove ) -{ - int i, j, max_j = -1, mask, type, num_removed; - int num[AR_SIMPLE_STEPS + 1], num_tot; - - for (j = 0; ArTypMask[2 * j]; j++) - { - num[max_j = j] = 0; - } - - for (i = 0; i < num_atoms; i++) - { - if (!at[i].charge && at[i].num_H && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) - { - for (j = 0; j <= max_j; j++) - { - if (( type & ArTypMask[2 * j] ) && ( mask && ArTypMask[2 * j + 1] )) - { - num[j] ++; - break; - } - } - } - } - for (j = 0, num_tot = 0; j <= max_j; j++) - { - if (( num_tot += num[j] ) >= num2remove) - { - max_j = j; - break; - } - } - if (!num_tot) - { - return 0; - } - for (i = 0, num_removed = 0; i < num_atoms && num_removed < num2remove; i++) - { - if (!at[i].charge && at[i].num_H && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) - { - for (j = 0; j <= max_j; j++) - { - if (num[j] && ( type & ArTypMask[2 * j] ) && ( mask && ArTypMask[2 * j + 1] )) - { - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - type = GetAtomChargeType(at, i, pAATG->nAtTypeTotals, &mask, 1); /* subtract at[i] */ - num[j] --; - at[i].charge--; - AddOrRemoveExplOrImplH( -1, at, num_atoms, (AT_NUMB) i, pAATG->t_group_info ); - /*at[i].num_H --;*/ - num_removed++; - type = GetAtomChargeType(at, i, pAATG->nAtTypeTotals, &mask, 0); /* add changed at[i] */ /* ! THIS CHANGES pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] */ - break; - } - } - } - } - - /* - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] -= num_removed; - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] += num_removed; - */ - - return num_removed; -} - - -/****************************************************************************/ -int bHasAcidicHydrogen( inp_ATOM *at, int i ) -{ - int bFound = 0, j, type, mask; - if (!at[i].charge && at[i].num_H && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) - { - for (j = 0; ArTypMask[2 * j]; j++) - { - if (( type & ArTypMask[2 * j] ) && ( mask & ArTypMask[2 * j + 1] )) - { - bFound++; - break; - } - } - } - - return bFound; -} - - -/****************************************************************************/ -int bHasOtherExchangableH( inp_ATOM *at, int i ) -{ - int bFound = 0, type, mask; - if (at[i].num_H && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) - { - if (( type & ATT_ATOM_N ) && ( mask & ATBIT_NP_H )) - { - bFound++; - } - } - - return bFound; -} - - -int AaTypMask[] = -{ - AA_SIMPLE_TYP1, - AA_SIMPLE_MSK1, -#if ( FIX_NP_MINUS_BUG == 1 ) - AA_SIMPLE_TYP4, - AA_SIMPLE_MSK4, /* should not follow 0,0 pair */ -#endif - AA_SIMPLE_TYP2, - AA_SIMPLE_MSK2, - AA_SIMPLE_TYP3, - AA_SIMPLE_MSK3, - 0, - 0 -}; - - -/****************************************************************************/ -int SimpleAddAcidicProtons( inp_ATOM *at, - int num_atoms, - BN_AATG *pAATG, - int num2add ) -{ - int i, j, max_j = -1, mask, type, num_added; - int num[AR_SIMPLE_STEPS + 1], num_tot; - - for (j = 0; AaTypMask[2 * j]; j++) - { - num[max_j = j] = 0; - } - - for (i = 0; i < num_atoms; i++) - { - if (at[i].charge == -1 && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) - { - for (j = 0; j <= max_j; j++) - { - if (( type & AaTypMask[2 * j] ) && ( mask && AaTypMask[2 * j + 1] )) - { - num[j] ++; - break; - } - } - } - } - for (j = 0, num_tot = 0; j <= max_j; j++) - { - if (( num_tot += num[j] ) >= num2add) - { - max_j = j; - break; - } - } - if (!num_tot) - { - return 0; - } - for (i = 0, num_added = 0; i < num_atoms && num_added < num2add; i++) - { - if (at[i].charge == -1 && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) - { - for (j = 0; j <= max_j; j++) - { - if (num[j] && ( type & AaTypMask[2 * j] ) && ( mask && AaTypMask[2 * j + 1] )) - { - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - type = GetAtomChargeType(at, i, pAATG->nAtTypeTotals, &mask, 1); /* subtract at[i] */ - num[j] --; - at[i].charge++; - AddOrRemoveExplOrImplH( 1, at, num_atoms, (AT_NUMB) i, pAATG->t_group_info ); - /*at[i].num_H ++;*/ - num_added++; - type = GetAtomChargeType(at, i, pAATG->nAtTypeTotals, &mask, 0); /* add changed at[i] */ - break; - } - } - } - } - - /* - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] += num_added; - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] -= num_added; - */ - - return num_added; -} - - -/****************************************************************************/ -int bHasAcidicMinus( inp_ATOM *at, int i ) -{ - int bFound = 0, j, type, mask; - if (at[i].charge == -1 && ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) )) - { - for (j = 0; AaTypMask[2 * j]; j++) - { - if (( type & AaTypMask[2 * j] ) && ( mask & AaTypMask[2 * j + 1] )) - { - bFound++; - break; - } - } - } - - return bFound; -} - - -/**************************************************************************** -HardRemoveAcidicProtons( ... ) - -Create 2 tautomeric groups: -(1) for O on -C=O, -(2) for the rest of the atoms. -Pull H from (2) to (1); remove later -****************************************************************************/ -int HardRemoveAcidicProtons( CANON_GLOBALS *pCG, - inp_ATOM *at, - int num_atoms, - BN_AATG *pAATG, - int num2remove, - int *nNumCanceledCharges, - BN_STRUCT *pBNS, - BN_DATA *pBD ) -{ - int cg_Plus = 0; - int cg_Minus = 0; - int tg_H_Other = 0; - int tg_H_Acid = 0; - - int ret = 0, ret2; - int nDelta, nNumMoved2AcidH = 0, nNumNeutralized = 0, nPrevNumCharges; /* djb-rwth: removing redundant variables */ - - int nPosCharges, nPosCharges2; - int nNegCharges, nNegCharges2; - /* - int nNumNP_H, nNumNP_H2; - int nNumOS_H, nNumOS_H2; - */ - - nPosCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - nNegCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - /* - nNumNP_H = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + - pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; - nNumOS_H = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + - pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + - pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; - */ - - /* Prevent free exchange H <-> (-) */ - pBNS->type_CN = ( BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_C_NEGATIVE ); - pBNS->type_T = BNS_VERT_TYPE_TGROUP; - pBNS->type_TACN = BNS_VERT_TYPE_ACID; - - /* Create (+) charge group */ - cg_Plus = CreateCGroupInBnStruct( at, num_atoms, pBNS, AR_HARD_TYP_POS, AR_HARD_MSK_POS, 1 ); - - /* create (-) charge group */ - /* - if ( nAtTypeTotals[ATTOT_NUM_CO_Minus] + - nAtTypeTotals[ATTOT_NUM_CS_Minus] + - nAtTypeTotals[ATTOT_NUM_ZO_Minus] + - nAtTypeTotals[ATTOT_NUM_N_Minus] ) - */ - - cg_Minus = CreateCGroupInBnStruct( at, num_atoms, pBNS, AR_HARD_TYP_NEG, AR_HARD_MSK_NEG, -1 ); - - pBNS->type_CN = ( BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_C_NEGATIVE ); - pBNS->type_T = BNS_VERT_TYPE_TGROUP; - pBNS->type_TACN = BNS_VERT_TYPE_ACID; - - /* Create tautomeric group for non-acidic or negatively charged acidic O */ - tg_H_Other = CreateTGroupInBnStruct( at, num_atoms, pBNS, AR_HARD_TYP_HN, AR_HARD_MSK_HN ); - if (tg_H_Other) /* djb-rwth: fixing coverity CID #499503 */ - { - return BNS_PROGRAM_ERR; - } - - /* Create tautomeric group for possibly acidic O */ - tg_H_Acid = CreateTGroupInBnStruct( at, num_atoms, pBNS, AR_HARD_TYP_HA, AR_HARD_MSK_HA ); - if (tg_H_Other >= num_atoms && tg_H_Acid >= num_atoms) - { - /* Find alt path to remove one proton */ - do - { - /* Remove a proton */ - nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; - ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, - at, num_atoms, - tg_H_Other /*nVertDoubleBond*/, - tg_H_Acid /*nVertSingleBond*/, - ALT_PATH_MODE_REM_PROTON ); - if (IS_BNS_ERROR( ret )) - { - return ret; - } - if (ret & 1) - { - nDelta = ( ret & ~3 ) >> 2; - /* djb-rwth: removing redundant code */ - if (nDelta) - { - /* Radical pair has disappeared */ - ; /* goto quick_exit;*/ - } - nNumMoved2AcidH++; - if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + 1) - { - nNumNeutralized += ( nPrevNumCharges - ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - 1 ) ) / 2; - } - } - } while (( ret & 1 ) && nNumMoved2AcidH < num2remove); - - /* Neutralize: remove ion pairs like >N(+)=-O(-) => >N-=O */ - if (( nNumMoved2AcidH /*|| bCancelChargesAlways*/ ) && cg_Minus >= num_atoms && cg_Plus >= num_atoms && - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] > abs( pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] )) - { - do - { - nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; - ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, - at, num_atoms, - cg_Minus /*nVertDoubleBond*/, - cg_Plus /*nVertSingleBond*/, - ALT_PATH_MODE_REM_PROTON ); - if (IS_BNS_ERROR( ret )) - { - return ret; - } - if (ret & 1) - { - nDelta = ( ret & ~3 ) >> 2; - /* djb-rwth: removing redundant code */ - if (nDelta) - { - /* Radical pair has disappeared */ - ; /* goto quick_exit;*/ - } - if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]) - { - nNumNeutralized += ( nPrevNumCharges - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] ) / 2; - } - } - } while (ret & 1); - } - } - - ret = 0; - if (tg_H_Acid >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, tg_H_Acid, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - if (tg_H_Other >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, tg_H_Other, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - if (cg_Minus >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Minus, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - if (cg_Plus >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Plus, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - - pBNS->type_CN = 0; - pBNS->type_T = 0; - pBNS->type_TACN = 0; - - if (ret) - { - return ret; - } - - if (pAATG->nAtTypeTotals[ATTOT_NUM_CO_Minus] + pAATG->nAtTypeTotals[ATTOT_NUM_ZO_Minus] && - pAATG->nAtTypeTotals[ATTOT_NUM_N_Minus]) - { - } - - nPosCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - nNegCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - /* - nNumNP_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + - pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; - nNumOS_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + - pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + - pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; - */ - if (( nPosCharges - nNegCharges ) - ( nPosCharges2 - nNegCharges2 ) != 0) - { - return BNS_PROGRAM_ERR; - } - - if (nNumCanceledCharges) - { -#if ( FIX_CANCEL_CHARGE_COUNT_BUG == 1 ) - *nNumCanceledCharges += 2 * nNumNeutralized; -#else - *nNumCanceledCharges = 2 * nNumNeutralized; -#endif - } - - return nNumMoved2AcidH; -} - - -/****************************************************************************/ -int HardAddAcidicProtons( CANON_GLOBALS *pCG, - inp_ATOM *at, - int num_atoms, - BN_AATG *pAATG, - int num2add, - int *nNumCanceledCharges, - BN_STRUCT *pBNS, - BN_DATA *pBD ) -{ - int cg_Plus = 0; - int cg_Minus_CO = 0; - int cg_Minus_Other = 0; - int tg_H = 0; - - int ret = 0, ret2; - int nDelta, nNumChanges = 0, nNumMoved2AcidMinus = 0, nNumNeutralized = 0, nPrevNumCharges; /* djb-rwth: removing redundant variables */ - - int nPosCharges, nPosCharges2; - int nNegCharges, nNegCharges2; - /* - int nNumNP_H, nNumNP_H2; - int nNumOS_H, nNumOS_H2; - */ - nPosCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - nNegCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - /* - nNumNP_H = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + - pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; - nNumOS_H = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + - pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + - pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; - */ - - /* Prevent free exchange H <-> (-) */ - pBNS->type_CN = ( BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_C_NEGATIVE ); - pBNS->type_T = BNS_VERT_TYPE_TGROUP; - pBNS->type_TACN = BNS_VERT_TYPE_ACID; - - /* Create (+) charge group */ - cg_Plus = CreateCGroupInBnStruct( at, num_atoms, pBNS, AA_HARD_TYP_POS, AA_HARD_MSK_POS, 1 ); - - /* Create (-) charge group */ - /* - if ( nAtTypeTotals[ATTOT_NUM_CO_Minus] + - nAtTypeTotals[ATTOT_NUM_CS_Minus] + - nAtTypeTotals[ATTOT_NUM_ZO_Minus] + - nAtTypeTotals[ATTOT_NUM_N_Minus] ) - */ - cg_Minus_CO = CreateCGroupInBnStruct( at, num_atoms, pBNS, AA_HARD_TYP_CO, AA_HARD_MSK_CO, -1 ); - if (cg_Minus_CO < 0) /* djb-rwth: fixing coverity CID #499474 */ - { - return BNS_PROGRAM_ERR; - } - - cg_Minus_Other = CreateCGroupInBnStruct( at, num_atoms, pBNS, AA_HARD_TYP_NEG, AA_HARD_MSK_NEG, -1 ); - - pBNS->type_CN = ( BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_C_NEGATIVE ); - pBNS->type_T = BNS_VERT_TYPE_TGROUP; - pBNS->type_TACN = BNS_VERT_TYPE_ACID; - - /* Create tautomeric group for all H */ - tg_H = CreateTGroupInBnStruct( at, num_atoms, pBNS, AA_HARD_TYP_H, AA_HARD_MSK_H ); - - if (cg_Minus_Other >= num_atoms && cg_Minus_CO >= num_atoms) - { - /* Find alt path to remove one proton */ - do - { - /* Add a proton */ - nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; - ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, - at, num_atoms, - cg_Minus_Other /*nVertDoubleBond*/, - cg_Minus_CO /*nVertSingleBond*/, - ALT_PATH_MODE_REM_PROTON ); - if (IS_BNS_ERROR( ret )) - { - return ret; - } - if (ret & 1) - { - nDelta = ( ret & ~3 ) >> 2; - nNumChanges += (0 != (ret & 2)); /* djb-rwth: ignoring LLVM warning: variable used */ - if (nDelta) - { - /* Radical pair has disappeared */ - ; /* goto quick_exit;*/ - } - nNumMoved2AcidMinus++; - if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + 1) - { - nNumNeutralized += ( nPrevNumCharges - ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - 1 ) ) / 2; - } - } - } while (( ret & 1 ) && nNumMoved2AcidMinus < num2add); - - /* Neutralize: remove ion pairs like >N(+)=-O(-) => >N-=O */ - if (( nNumMoved2AcidMinus /*|| bCancelChargesAlways*/ ) && - cg_Minus_Other >= num_atoms && cg_Plus >= num_atoms && - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] > abs( pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] )) - { - do - { - nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; - ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, - at, num_atoms, - cg_Minus_Other /*nVertDoubleBond*/, - cg_Plus /*nVertSingleBond*/, - ALT_PATH_MODE_REM_PROTON ); - if (IS_BNS_ERROR( ret )) - { - return ret; - } - if (ret & 1) - { - nDelta = ( ret & ~3 ) >> 2; - nNumChanges += (0 != (ret & 2)); /* djb-rwth: ignoring LLVM warning: variable used */ - if (nDelta) - { - /* Radical pair has disappeared */ - ; /* goto quick_exit;*/ - } - if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]) - { - nNumNeutralized += ( nPrevNumCharges - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] ) / 2; - } - } - } while (ret & 1); - } - } - - ret = 0; - if (tg_H >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, tg_H, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - if (cg_Minus_Other >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Minus_Other, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - if (cg_Minus_CO >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Minus_CO, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - if (cg_Plus >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Plus, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - - pBNS->type_CN = 0; - pBNS->type_T = 0; - pBNS->type_TACN = 0; - - if (ret) - { - return ret; - } - - if (pAATG->nAtTypeTotals[ATTOT_NUM_CO_Minus] + pAATG->nAtTypeTotals[ATTOT_NUM_ZO_Minus] && - pAATG->nAtTypeTotals[ATTOT_NUM_N_Minus]) - { - } - - nPosCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - nNegCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - /* - nNumNP_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + - pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; - nNumOS_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + - pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + - pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; - */ - - if (( nPosCharges - nNegCharges ) - ( nPosCharges2 - nNegCharges2 ) != 0) - { - return BNS_PROGRAM_ERR; - } - - if (nNumCanceledCharges) - { -#if ( FIX_CANCEL_CHARGE_COUNT_BUG == 1 ) - *nNumCanceledCharges += 2 * nNumNeutralized; -#else - *nNumCanceledCharges = 2 * nNumNeutralized; -#endif - } - - return nNumMoved2AcidMinus; -} - - -/**************************************************************************** -HardRemoveHplusNP( ... ) - -Examples include removal of H from tautomeric O -that belongs to the same t-group as N: - ->N(+)=-N=-OH =(taut.) => ->N(+)=-NH-=O =(+charge move) => ->N-=NH(+)-=O => >N-=N-=O + H(+) -****************************************************************************/ -int HardRemoveHplusNP( CANON_GLOBALS *pCG, - inp_ATOM *at, - int num_atoms, - int bCancelChargesAlways, - int *nNumCanceledCharges, - BN_AATG *pAATG, - BN_STRUCT *pBNS, - BN_DATA *pBD ) -{ - - int cg_Plus = 0; - int cg_Minus = 0; - int tg_H = 0; -#if ( MOVE_PPLUS_TO_REMOVE_PROTONS == 1 ) - int cg_PlusP = 0; -#endif -#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) - int nPrevRemovedProtons, nCurrRemovedProtons; -#endif - int ret = 0, ret2; - int nDelta, nNumChanges = 0, nNumRemovedProtons = 0, nNumNeutralized = 0, nPrevNumCharges; /* djb-rwth: ignoring LLVM warning: variable used */ - - int nPosCharges, nPosCharges2; - int nNegCharges, nNegCharges2; - /* - int nNumNP_H, nNumNP_H2; - int nNumOS_H, nNumOS_H2; - */ - - nPosCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - nNegCharges = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - /* - nNumNP_H = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + - pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; - nNumOS_H = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + - pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + - pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; - */ - - /* Prevent free exchange H <-> (-) */ - pBNS->type_CN = ( BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_C_NEGATIVE ); - pBNS->type_T = BNS_VERT_TYPE_TGROUP; - pBNS->type_TACN = BNS_VERT_TYPE_ACID; - - /* Create (+) charge group */ - cg_Plus = CreateCGroupInBnStruct( at, num_atoms, pBNS, PR_HARD_TYP_POS, PR_HARD_MSK_POS, 1 ); - - /* Create (-) charge group */ - /* - if ( nAtTypeTotals[ATTOT_NUM_CO_Minus] + - nAtTypeTotals[ATTOT_NUM_CS_Minus] + - nAtTypeTotals[ATTOT_NUM_ZO_Minus] + - nAtTypeTotals[ATTOT_NUM_N_Minus] ) - */ -#if ( MOVE_PPLUS_TO_REMOVE_PROTONS == 1 ) - cg_PlusP = CreateCGroupInBnStruct( at, num_atoms, pBNS, PR_HARD_TYP_POSP, PR_HARD_MSK_POS, 1 ); -#endif - cg_Minus = CreateCGroupInBnStruct( at, num_atoms, pBNS, PR_HARD_TYP_NEG, PR_HARD_MSK_NEG, -1 ); - - /* Create single tautomeric group */ - tg_H = CreateTGroupInBnStruct( at, num_atoms, pBNS, PR_HARD_TYP_H, PR_HARD_MSK_H ); - if (tg_H < 0) /* djb-rwth: fixing coverity CID #499572 */ - { - return BNS_PROGRAM_ERR; - } - - if (tg_H >= num_atoms && cg_Plus >= num_atoms) - { - -#if ( FIX_N_MINUS_NORN_BUG == 1 ) - /* neutralize: remove ion pairs like >N(+)=-O(-) => >N-=O; >N(+)=-NH(-) => >N-=NH */ - if (( nNumRemovedProtons || bCancelChargesAlways ) && cg_Minus >= num_atoms && cg_Plus >= num_atoms && - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] > abs( pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] )) - { - do - { - nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; -#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) - nPrevRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; -#endif - ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, at, num_atoms, - cg_Minus /*nVertDoubleBond*/, cg_Plus /*nVertSingleBond*/, ALT_PATH_MODE_REM_PROTON ); - if (IS_BNS_ERROR( ret )) - { - return ret; - } -#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) - nCurrRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; - if (nCurrRemovedProtons != nPrevRemovedProtons) - { - return BNS_RADICAL_ERR; - } -#endif - if (ret & 1) - { - nDelta = ( ret & ~3 ) >> 2; - nNumChanges += ( 0 != ( ret & 2 ) ); - if (nDelta) - { - /* radical pair has disappeared */ - ; /* goto quick_exit;*/ - } - if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]) - { - nNumNeutralized += ( nPrevNumCharges - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] ) / 2; - } - } - } while (ret & 1); - } -#endif - - /* Find alt path to remove one proton */ - do - { - /* Remove a proton */ - nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; -#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) - nPrevRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; -#endif - ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, at, num_atoms, - tg_H /*nVertDoubleBond*/, - cg_Plus /*nVertSingleBond*/, - ALT_PATH_MODE_REM_PROTON ); - if (IS_BNS_ERROR( ret )) - { - return ret; - } -#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) - nCurrRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; - if (nCurrRemovedProtons != nPrevRemovedProtons + ( ret & 1 )) - { - return BNS_RADICAL_ERR; - } -#endif - if (ret & 1) - { - nDelta = ( ret & ~3 ) >> 2; - nNumChanges += (0 != (ret & 2)); /* djb-rwth: ignoring LLVM warning: variable used */ - if (nDelta) - { - /* radical pair has disappeared */ - ; /* goto quick_exit;*/ - } - nNumRemovedProtons++; - if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + 1) - { - nNumNeutralized += ( nPrevNumCharges - ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - 1 ) ) / 2; - } - } - } while (ret & 1); - - /* Neutralize: remove ion pairs like >N(+)=-O(-) => >N-=O */ - if (( nNumRemovedProtons || bCancelChargesAlways ) && cg_Minus >= num_atoms && cg_Plus >= num_atoms && - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] > abs( pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] )) - { - do - { - nPrevNumCharges = pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]; -#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) - nPrevRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; -#endif - ret = bExistsAltPath( pCG, pBNS, pBD, pAATG, at, num_atoms, - cg_Minus /*nVertDoubleBond*/, - cg_Plus /*nVertSingleBond*/, - ALT_PATH_MODE_REM_PROTON ); - if (IS_BNS_ERROR( ret )) - { - return ret; - } -#if ( FIX_REM_PROTON_COUNT_BUG == 1 ) - nCurrRemovedProtons = pAATG->t_group_info->tni.nNumRemovedProtons; - if (nCurrRemovedProtons != nPrevRemovedProtons) - { - return BNS_RADICAL_ERR; - } -#endif - if (ret & 1) - { - nDelta = ( ret & ~3 ) >> 2; - nNumChanges += (0 != (ret & 2)); /* djb-rwth: ignoring LLVM warning: variable used */ - if (nDelta) - { - /* Radical pair has disappeared */ - ; /* goto quick_exit;*/ - } - if (nPrevNumCharges > pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES]) - { - nNumNeutralized += ( nPrevNumCharges - pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] ) / 2; - } - } - } while (ret & 1); - } - } - - ret = 0; - if (tg_H >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, tg_H, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - if (cg_Minus >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Minus, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } -#if ( MOVE_PPLUS_TO_REMOVE_PROTONS == 1 ) - if (cg_PlusP >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_PlusP, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } -#endif - if (cg_Plus >= num_atoms) - { - ret2 = RemoveLastGroupFromBnStruct( at, num_atoms, cg_Plus, pBNS ); - if (!ret && ret2) - { - ret = ret2; - } - } - - pBNS->type_CN = 0; - pBNS->type_T = 0; - pBNS->type_TACN = 0; - - if (ret) - { - return ret; - } - - if (pAATG->nAtTypeTotals[ATTOT_NUM_CO_Minus] + pAATG->nAtTypeTotals[ATTOT_NUM_ZO_Minus] && - pAATG->nAtTypeTotals[ATTOT_NUM_N_Minus]) - { - } - - nPosCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] + pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - nNegCharges2 = ( pAATG->nAtTypeTotals[ATTOT_NUM_CHARGES] - pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ) / 2; - /* - nNumNP_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_NP_H] + - pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton]; - nNumOS_H2 = pAATG->nAtTypeTotals[ATTOT_NUM_COH] + - pAATG->nAtTypeTotals[ATTOT_NUM_CSH] + - pAATG->nAtTypeTotals[ATTOT_NUM_ZOH]; - */ - - if (( nPosCharges - nNegCharges ) - ( nPosCharges2 - nNegCharges2 ) != nNumRemovedProtons) - { - return BNS_PROGRAM_ERR; - } - - if (nNumCanceledCharges) - { -#if ( FIX_CANCEL_CHARGE_COUNT_BUG == 1 ) - *nNumCanceledCharges += 2 * nNumNeutralized; -#else - *nNumCanceledCharges = 2 * nNumNeutralized; -#endif - } - - return nNumRemovedProtons; -} - - -/****************************************************************************/ -int mark_at_type( inp_ATOM *atom, int num_atoms, int nAtTypeTotals[] ) -{ - int i, max_num_ions, mask, type; - /*int max_protons, max_O_Minus, num_H = 0, num_CO=0;*/ - - if (nAtTypeTotals) - { - memset( nAtTypeTotals, 0, ATTOT_ARRAY_LEN * sizeof( nAtTypeTotals[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - } - - for (i = 0; i < num_atoms; i++) - { - type = GetAtomChargeType( atom, i, nAtTypeTotals, &mask, 0 ); - atom[i].at_type = type; - /* - num_H += ((type & PR_HARD_TYP_H) && (mask & ATBIT_MSK_H)); - num_CO += ((type & AR_HARD_TYP_HA) && (mask & AR_HARD_MSK_HA)); - */ - } - - if (nAtTypeTotals) - { - /* - max_protons = nAtTypeTotals[ATTOT_NUM_NP_Proton] + - inchi_min(num_H, nAtTypeTotals[ATTOT_NUM_NP_Plus]); - max_O_Minus = nAtTypeTotals[ATTOT_NUM_CO_Minus] + nAtTypeTotals[ATTOT_NUM_CS_Minus] + - nAtTypeTotals[ATTOT_NUM_ZO_Minus] + nAtTypeTotals[ATTOT_NUM_OO_Minus] + - nAtTypeTotals[ATTOT_NUM_ZOO_Minus] + nAtTypeTotals[ATTOT_NUM_NO_Minus] + - nAtTypeTotals[ATTOT_NUM_O_Minus] +nAtTypeTotals[ATTOT_NUM_N_Minus]; - ; - max_num_ions = max_protons + max_O_Minus + nAtTypeTotals[ATTOT_NUM_CHARGES]; - */ - max_num_ions = nAtTypeTotals[ATTOT_NUM_CHARGES]; - } - else - { - max_num_ions = 0; - } - - return max_num_ions; -} - - -/****************************************************************************/ -int RemoveNPProtonsAndAcidCharges( CANON_GLOBALS *pCG, - inp_ATOM *at, - int num_atoms, - BN_AATG *pAATG, - BN_STRUCT *pBNS, - BN_DATA *pBD ) -{ - - /* Prepare data structure */ - int num; - int nNumCanceledCharges = 0; - /* djb-rwth: removing redundant variables */ - T_GROUP_INFO *t_group_info = pAATG->t_group_info; - int ret = 0, bError = 0; - - int bAllowHardRemove = ( t_group_info->bTautFlags & TG_FLAG_TEST_TAUT__SALTS ) && - ( t_group_info->bTautFlags & TG_FLAG_TEST_TAUT2_SALTS ) && - ( t_group_info->bTautFlags & TG_FLAG_MOVE_POS_CHARGES ) && - ( t_group_info->bTautFlags & TG_FLAG_HARD_ADD_REM_PROTONS ); - - if (pAATG->nMarkedAtom && num_atoms < pAATG->nAllocLen) - { - inchi_free( pAATG->nMarkedAtom ); - qzfree( pAATG->nEndPoint ); - memset( pAATG, 0, sizeof( *pAATG ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - } - - if (!pAATG->nMarkedAtom && ( pAATG->nMarkedAtom = (S_CHAR *) inchi_malloc( num_atoms * sizeof( pAATG->nMarkedAtom[0] ) ) )) - { - pAATG->nAllocLen = num_atoms; - pAATG->nNumFound = 0; - } - - /* o TECHMAN-5.1. Remove protons from charged heteroatoms */ - - /* (TECHMAN-5.1a) Simple remove of protons from N, P, and O,S,Se,Te */ - if ((num = pAATG->nAtTypeTotals[ATTOT_NUM_NP_Proton] + pAATG->nAtTypeTotals[ATTOT_NUM_OH_Plus])) /* djb-rwth: addressing LLVM warning */ - { - ret = SimpleRemoveHplusNPO( at, num_atoms, pAATG->nAtTypeTotals, t_group_info ); - if (ret != num) - { - bError = BNS_PROGRAM_ERR; - goto exit_function; - } - /*t_group_info->nNumRemovedProtons += ret;*/ - t_group_info->tni.bNormalizationFlags |= ( ret > 0 ) ? FLAG_PROTON_NPO_SIMPLE_REMOVED : 0; - } - - if (( num = pAATG->nAtTypeTotals[ATTOT_NUM_NP_Plus] ) && bAllowHardRemove) /* djb-rwth: ignoring LLVM warning: variable used */ - { - /* [TECHMAN-5.1b] Hard removing more protons from cationic N; charges may be canceled */ - ret = HardRemoveHplusNP( pCG, at, num_atoms, 1, &nNumCanceledCharges, pAATG, pBNS, pBD ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - /* djb-rwth: removing redundant code */ - /*t_group_info->nNumRemovedProtons += ret;*/ - t_group_info->tni.bNormalizationFlags |= ( ret > 0 ) ? FLAG_PROTON_NP_HARD_REMOVED : 0; - } - - if (pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] > 0) - { - /* o TECHMAN-5.2. Remove protons from neutral heteroatoms */ - - /* (TECHMAN-5.2a) Simple removal */ - ret = SimpleRemoveAcidicProtons( at, num_atoms, pAATG, pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - - /*t_group_info->nNumRemovedProtons += ret;*/ - t_group_info->tni.bNormalizationFlags |= ( ret > 0 ) ? FLAG_PROTON_AC_SIMPLE_REMOVED : 0; - - - if (pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] > 0 && bAllowHardRemove) - { - /* (TECHMAN-5.2b) Hard removal */ - ret = HardRemoveAcidicProtons(pCG, at, num_atoms, pAATG, pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE], &nNumCanceledCharges, pBNS, pBD); - if (IS_BNS_ERROR(ret)) - { - bError = ret; - goto exit_function; - } - if (ret > 0) - { - int ret2 = SimpleRemoveAcidicProtons(at, num_atoms, pAATG, ret); - if (ret2 != ret) - { - bError = BNS_PROGRAM_ERR; - goto exit_function; - } - /*t_group_info->nNumRemovedProtons += ret;*/ - t_group_info->tni.bNormalizationFlags |= (ret > 0) ? FLAG_PROTON_AC_HARD_REMOVED : 0; - /* djb-rwth: removing redundant code */ - } - } - - - } - else - { - if (pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] < 0) - { - ret = SimpleAddAcidicProtons( at, num_atoms, pAATG, -pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - /*t_group_info->nNumRemovedProtons -= ret;*/ - /* - CHECK_TACN == 1 prohibits replacing (-) on N with H unless H can be moved to N - along an alternating path from another heteroatom (t-group will be detected). - */ - t_group_info->tni.bNormalizationFlags |= ( ret > 0 ) ? FLAG_PROTON_AC_SIMPLE_ADDED : 0; - if (pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE] < 0 && bAllowHardRemove) - { - ret = HardAddAcidicProtons( pCG, at, num_atoms, pAATG, -pAATG->nAtTypeTotals[ATTOT_TOT_CHARGE], &nNumCanceledCharges, pBNS, pBD ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - if (ret > 0) - { - int ret2 = SimpleAddAcidicProtons( at, num_atoms, pAATG, ret ); - if (ret2 != ret) - { - bError = BNS_PROGRAM_ERR; - goto exit_function; - } - /*t_group_info->nNumRemovedProtons -= ret;*/ - t_group_info->tni.bNormalizationFlags |= FLAG_PROTON_AC_HARD_ADDED; /* djb-rwth: fixing coverity CID #499527 */ - /* djb-rwth: removing redundant code */ - } - } - } - } - - t_group_info->tni.bNormalizationFlags |= nNumCanceledCharges ? FLAG_PROTON_CHARGE_CANCEL : 0; - -exit_function: - if (bError) - { - ret = IS_BNS_ERROR( bError ) ? bError : BNS_PROGRAM_ERR; - } - - return ret; -} - - -/**************************************************************************** -Main normalization procedure -****************************************************************************/ -int mark_alt_bonds_and_taut_groups( struct tagINCHI_CLOCK *ic, - struct tagCANON_GLOBALS *pCG, - inp_ATOM *at, - inp_ATOM *at_fixed_bonds_out, - int num_atoms, - struct tagInchiTime *ulTimeOutTime, - T_GROUP_INFO *t_group_info, - INCHI_MODE *inpbTautFlags, - INCHI_MODE *inpbTautFlagsDone, - int nebend, - int *ebend ) - - -{ - BN_STRUCT *pBNS = NULL; - BN_DATA *pBD = NULL; - int bError, nChanges, taut_found, salt_found, salt_pass, salt_step, ret, ret2, num, num_changed_bonds; /* djb-rwth: removing redundant variables */ - int max_altp = BN_MAX_ALTP; - int bChangeFlow = ( BNS_EF_CHNG_RSTR | BNS_EF_ALTR_BONDS ); - BNS_FLOW_CHANGES fcd[BNS_MAX_NUM_FLOW_CHANGES + 1]; - C_GROUP_INFO CGroupInfo; - C_GROUP_INFO *c_group_info = &CGroupInfo; - S_GROUP_INFO SGroupInfo; - S_GROUP_INFO *s_group_info = &SGroupInfo; - INCHI_MODE *pbTautFlags = t_group_info ? &t_group_info->bTautFlags : inpbTautFlags; - INCHI_MODE *pbTautFlagsDone = t_group_info ? &t_group_info->bTautFlagsDone : inpbTautFlagsDone; - - int nAtTypeTotals[ATTOT_ARRAY_LEN]; - int nNumOrigTotAtoms; - - BN_AATG aatg; - BN_AATG *pAATG = &aatg; - -#ifdef FIX_AROM_RADICAL /* Added 2011-05-09 IPl */ - int i, n_arom_radicals = 0, *stored_radicals = NULL; -#endif - int at_prot; /* moved from below 2024-09-01 DT */ - - nChanges = 0; - bError = 0; - - memset( c_group_info, 0, sizeof( *c_group_info ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - memset( s_group_info, 0, sizeof( *s_group_info ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - memset( pAATG, 0, sizeof( *pAATG ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - - /*(@nnuk : Nauman Ullah Khan) :: Variable for checking (De)protonation status */ - LOG_NO_ARGS("\n############# Initial state before (De)Protonation (L5373:ichi_bns.c) ###############\n"); - for (at_prot = 0; at_prot < num_atoms; at_prot++) - { - LOG_MULT_ARGS("Atom %d: Element: %s, Num_H: %d, Charge: %hhd, Radical: %d\n", at_prot, at[at_prot].elname, at[at_prot].num_H, at[at_prot].charge, at[at_prot].radical); - } - LOG_NO_ARGS("\n#####################################################################################\n"); - - -#ifdef FIX_AROM_RADICAL /* Added 2011-05-09 IPl */ - for (i = 0; i < num_atoms; i++) - { - if (( at[i].radical == RADICAL_DOUBLET ) && ( at[i].valence == 2 ) && - ( at[i].bond_type[0] == BOND_ALTERN ) && ( at[i].bond_type[1] == BOND_ALTERN )) - { - n_arom_radicals++; - if (!stored_radicals) - { - stored_radicals = (int *) inchi_calloc( num_atoms, sizeof( int ) ); - /* 2011-08-05 explicit cast added due to Evan Bolton */ - if (!stored_radicals) - { - bError = BNS_OUT_OF_RAM; - goto exit_function; - } - stored_radicals[i] = RADICAL_DOUBLET; - at[i].radical = 0; - at[i].num_H++; - } - } - } - -#endif - - if (( *pbTautFlags & TG_FLAG_MOVE_POS_CHARGES ) && num_atoms > 1) - { - /* Charge groups memory allocation */ - c_group_info->c_group = (C_GROUP *) inchi_calloc( num_atoms / 2, sizeof( c_group_info->c_group[0] ) ); - c_group_info->c_candidate = (C_CANDIDATE*) inchi_calloc( num_atoms, sizeof( c_group_info->c_candidate[0] ) ); - if (c_group_info->c_group && c_group_info->c_candidate) - { - c_group_info->max_num_c_groups = num_atoms / 2; - c_group_info->max_num_candidates = num_atoms; - } - else - { - bError = BNS_OUT_OF_RAM; /* error: out of RAM */ - /*printf("BNS_OUT_OF_RAM-1: num_at=%d, c_gr=%lx c_can=%lx\n", num_atoms, c_group_info->c_group, c_group_info->c_candidate);*/ - goto exit_function; - } - } - - if (*pbTautFlags & TG_FLAG_TEST_TAUT__SALTS) - { - if (t_group_info) - { - /* Salt groups memory allocation */ - s_group_info->s_candidate = - (S_CANDIDATE*) inchi_calloc( num_atoms, - sizeof( s_group_info->s_candidate[0] ) ); - if (s_group_info->s_candidate) - { - s_group_info->max_num_candidates = num_atoms; - } - else - { - bError = BNS_OUT_OF_RAM; /* error: out of RAM */ - /*printf("BNS_OUT_OF_RAM-2\n");*/ - goto exit_function; - } - } - } - - if (t_group_info) - { - if (t_group_info->tGroupNumber) - { - inchi_free( t_group_info->tGroupNumber ); - } - t_group_info->tGroupNumber = (AT_NUMB *) inchi_calloc( 2 * (long long)num_atoms + 1, sizeof( t_group_info->tGroupNumber[0] ) ); /* djb-rwth: cast operator added */ - if (!t_group_info->tGroupNumber) - { - /*printf("BNS_OUT_OF_RAM-9\n");*/ - bError = BNS_OUT_OF_RAM; /* error: out of RAM */ - goto exit_function; - } - num = t_group_info->tni.nNumRemovedExplicitH; - memset( &t_group_info->tni, 0, sizeof( t_group_info->tni ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - t_group_info->tni.nNumRemovedExplicitH = num; - } - - /* - again: - */ - - /* Allocate Balanced Network Data Strucures; replace Alternating bonds with Single */ - if (( pBNS = AllocateAndInitBnStruct( at, num_atoms, - BNS_ADD_ATOMS, BNS_ADD_EDGES, - max_altp, &num_changed_bonds ) ) - && - ( pBD = AllocateAndInitBnData( pBNS->max_vertices ) )) - { - - - pBNS->pbTautFlags = pbTautFlags; /* carry through all functions */ - pBNS->pbTautFlagsDone = pbTautFlagsDone; /* carry through all functions */ - - pBNS->ulTimeOutTime = ulTimeOutTime; /* v. 1.05 */ - pBNS->ic = ic; /* v. 1.05 */ - -#if ( BNS_PROTECT_FROM_TAUT == 1 ) - /* Protect bonds to acetyl and nitro */ - SetForbiddenEdges( pBNS, at, num_atoms, BNS_EDGE_FORBIDDEN_MASK, nebend, ebend ); -#endif - - /* Set bonds in case of input "aromatic" bonds or multiple radicals */ -#ifdef FIX_AROM_RADICAL /* Added 2011-05-09 IPl */ - if (n_arom_radicals) - { - ret = BnsAdjustFlowBondsRad( pBNS, pBD, at, num_atoms ); - if (stored_radicals) - { - for (i = 0; i < num_atoms; i++) - { - if (stored_radicals[i]) - { - at[i].radical = stored_radicals[i]; - at[i].num_H--; - } - } - } - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - } -#endif - - ret = BnsAdjustFlowBondsRad( pBNS, pBD, at, num_atoms ); - - /* (here pair(s) of radicals could have disappeared from the atoms) */ - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - pBNS->tot_st_flow += 2 * ret; - - /*return 0;*/ /* debug */ - /* djb-rwth: removing redundant code */ - - if (pBNS->tot_st_cap > pBNS->tot_st_flow) - { - /* has radical */ - bChangeFlow |= BNS_EF_SET_NOSTEREO; - } - - /******************************************************************** - * Remove protons from NH(+), but not PH(+) - * Add protons to COO(-) etc. - * or remove protons from COOH etc to make the organic part neutral - * Note: for now (-) from N(-) can be only canceled or moved to -C=O - ********************************************************************/ - if (( *pbTautFlags & TG_FLAG_VARIABLE_PROTONS ) && - t_group_info && - mark_at_type( at, num_atoms, nAtTypeTotals ) && - nAtTypeTotals[ATTOT_NUM_CHARGES]) - { - /* - the structure is simple to neutralize if it yields exactly - num[H(+)] = num[N,P H(+)] - num[N,S,O(-)] = num[=C-O(-)] + num[C-S(-)] + num[N(-)] + num[other O(-), S(-)] - - and n(p) = num[H(+)] - num[N,S,O(-)] (no protons, no negative N,O,S condition) - - Additional check is needed if: - min{num[N,PH], num[N,P(+), not onium]} > 0 - => possibility to yield more H(+) - - min_charge = orig_charge(P,N,O,S) - n(p) - n(OH,SH) - max_charge = orig_charge(P,N,O,S) - n(p) + n(O,S,N(-)) - */ - - nNumOrigTotAtoms = t_group_info->tni.nNumRemovedExplicitH + num_atoms; - pAATG->nAtTypeTotals = nAtTypeTotals; - pAATG->t_group_info = t_group_info; -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; -#endif - - /***********************************************************/ - /* */ - /* ( D E ) P R O T O N A T I O N */ - /* */ - /***********************************************************/ - - ret = RemoveNPProtonsAndAcidCharges( pCG, at, num_atoms, pAATG, pBNS, pBD ); - -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; -#endif - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - - if (t_group_info->tni.bNormalizationFlags) - { - SetInitCapFlowToCurrent( pBNS ); - if (at_fixed_bonds_out) - { - /* Copy modified initial tautomeric structure for displaying - Warning: implicit H counts in at_fixed_bonds_out include explicit Hs */ - - memcpy(at_fixed_bonds_out, at, nNumOrigTotAtoms * sizeof(at_fixed_bonds_out[0])); - - /* -- will be done in FillOutInputInfAtom() -- - RemoveExcessiveImplicitH( num_atoms, t_group_info->tni.nNumRemovedExplicitH, at_fixed_bonds_out ); - */ - } - } - } - - /****************** Initial bonds normalization ***************/ - - if (*pbTautFlags & TG_FLAG_MOVE_POS_CHARGES) - { - /******************* Find moveable positive charges **********************/ - do - { - /* Cycling while ret>0 added 2004-06-04 */ -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; - CorrectFixing_NH_NH_Bonds( pBNS, at, num_atoms ); -#endif - ret = MarkChargeGroups( pCG, at, num_atoms, - c_group_info, t_group_info, - pBNS, pBD ); - -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; -#endif - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - if (ret) - { - nChanges += ret; - ret2 = AddCGroups2BnStruct( pCG, pBNS, at, num_atoms, c_group_info ); - if (IS_BNS_ERROR( ret2 )) - { - bError = ret2; - goto exit_function; - } - *pbTautFlagsDone |= TG_FLAG_MOVE_POS_CHARGES_DONE; - } - } while (ret > 0); - - -#if ( BNS_RAD_SEARCH == 1 ) -#else - /* moveable charges may allow to cancel radicals -- check it */ - if (pBNS->tot_st_cap > pBNS->tot_st_flow) - { - ret = BnsAdjustFlowBondsRad( pBNS, pBD, at, num_atoms ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - if (ret > 0) - { - /* - pBNS->tot_st_flow += 2*ret; - ret = ReInitBnStruct( pBNS, at, num_atoms, 1 ); - if ( IS_BNS_ERROR( ret ) ) { - bError = ret; - goto exit_function; - } - */ - bError = BNS_RADICAL_ERR; - goto exit_function; - } - } -#endif - } - - /************************************************************************/ - /******** Test bonds for bond tautomerism **************/ - /******** replace moveable bonds with "alternating" bonds **************/ - /************************************************************************/ - ret = BnsTestAndMarkAltBonds( pBNS, pBD, at, num_atoms, fcd, bChangeFlow, 0 ); - - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - /* djb-rwth: removing redundant code */ - - /*********************** End of initial bonds normalization *************/ - - /* djb-rwth: removing redundant code */ - - /* Check for tautomerism */ - /* find new tautomer groups */ - salt_pass = 0; - salt_step = 0; - salt_found = 0; - - /*************************************************************/ - /* */ - /* M A I N C Y C L E B E G I N */ - /* */ - /*************************************************************/ - - do - { - /* djb-rwth: removing redundant code */ - nChanges = 0; - /* djb-rwth: removing redundant code */ - - /**************** Regular bond/H/(-)/positive charges tautomerism cycle begin **************/ - do - { - /* djb-rwth: removing redundant code */ - for (taut_found = 0; - 0 < ( ret = MarkTautomerGroups( pCG, at, num_atoms, - t_group_info, c_group_info, - pBNS, pBD ) ); - taut_found++) - { - ; - } - if (ret < 0) - { - bError = ret; - } - if (taut_found && !salt_pass) - { - *pbTautFlagsDone |= TG_FLAG_TEST_TAUT__ATOMS_DONE; - } - - if (taut_found || salt_found) - { - /****************** repeat bonds normalization ***************/ - ret = ReInitBnStructAddGroups( pCG, pBNS, at, num_atoms, - t_group_info, c_group_info ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } -#if ( BNS_RAD_SEARCH == 1 ) -#else - /* discovered moveable charges and H-atoms may allow to cancel radicals */ - if (pBNS->tot_st_cap > pBNS->tot_st_flow) - { - ret = BnsAdjustFlowBondsRad( pBNS, pBD, at, num_atoms ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - if (ret > 0) - { - /* - pBNS->tot_st_flow += 2*ret; - ret = ReInitBnStruct( pBNS, at, num_atoms, 1 ); - if ( IS_BNS_ERROR( ret ) ) { - bError = ret; - goto exit_function; - } - */ - bError = BNS_RADICAL_ERR; - goto exit_function; - } - } -#endif - /****************** Update bonds normalization ***************/ - if (*pbTautFlags & TG_FLAG_MOVE_POS_CHARGES) - { - /******************* Find moveable charges ***************/ - do - { - /* Cycling while ret>0 added 2004-06-04 */ -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; - CorrectFixing_NH_NH_Bonds( pBNS, at, num_atoms ); -#endif - - ret = MarkChargeGroups( pCG, at, num_atoms, - c_group_info, t_group_info, - pBNS, pBD ); -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; -#endif - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - nChanges += ret; - if (ret > 0) - { - ret2 = ReInitBnStructAddGroups( pCG, pBNS, - at, num_atoms, - t_group_info, - c_group_info ); - if (IS_BNS_ERROR( ret2 )) - { - bError = ret2; - goto exit_function; - } - *pbTautFlagsDone |= TG_FLAG_MOVE_POS_CHARGES_DONE; - } - } while (ret > 0); - } - - /************************************************************************/ - /******** Find moveable bonds: **************/ - /******** test bonds for bond tautomerism **************/ - /******** replace moveable bonds with "alternating" bonds **************/ - /************************************************************************/ - ret = BnsTestAndMarkAltBonds( pBNS, pBD, at, num_atoms, fcd, bChangeFlow, 0 ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - goto exit_function; - } - nChanges += ret; - /****************** End of update bonds normalization ***************/ - - } - salt_found = 0; - } while (taut_found && !bError); - - - /**************** Regular bond/H/(-)/positive charges tautomerism cycle end **************/ - - if (bError) - { - break; - } - - - /******************* 'Salt' tautomerism permitted *************************/ - if (*pbTautFlags & TG_FLAG_TEST_TAUT__SALTS) - { - - if (*pbTautFlags & TG_FLAG_TEST_TAUT2_SALTS) - { - /*********** Requested one or more "salt" attachement migrartion test ********/ - if (!nChanges && salt_pass && salt_step) - { - break; /* done */ - } - if (!salt_step) - { - /* Salt step 0: process one attachment migrartion */ -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; - CorrectFixing_NH_NH_Bonds( pBNS, at, num_atoms ); -#endif - salt_found = MarkSaltChargeGroups( pCG, at, num_atoms, - s_group_info, - t_group_info, - c_group_info, - pBNS, pBD ); -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; -#endif - if (salt_found < 0) - { - bError = salt_found; - break; - } - else - { - if (salt_found > 0) - { - *pbTautFlagsDone |= TG_FLAG_TEST_TAUT__SALTS_DONE; - } - } - salt_step = !salt_found; - /* if new 'salt' atoms have been found then repeat regular taut. search - * MarkTautomerGroups() and do not perform salt step 1 - * if new 'salt' atoms have NOT been found then switch to salt step 1 - * and never repeat salt step 0 for the current structure - */ - } - - if (salt_step /*|| - (t_group_info->tni.bNormalizationFlags & FLAG_NORM_CONSIDER_TAUT)*/) - { - /* Salt step 1: process more than one attachment migration */ -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; - CorrectFixing_NH_NH_Bonds( pBNS, at, num_atoms ); -#endif - salt_found = MarkSaltChargeGroups2( pCG, at, num_atoms, - s_group_info, - t_group_info, - c_group_info, - pBNS, pBD ); -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; -#endif - if (salt_found < 0) - { - bError = salt_found; - break; - } - else - { - if (salt_found == 1 || salt_found == 5) - { - *pbTautFlagsDone |= TG_FLAG_TEST_TAUT2_SALTS_DONE; - if (salt_found == 5) - { - *pbTautFlagsDone |= TG_FLAG_TEST_TAUT3_SALTS_DONE; - } - /* salt_found == 2 => only negative charges involved */ - } - } - } - - salt_pass++; - } - else - { - /* !( *pbTautFlags & TG_FLAG_TEST_TAUT2_SALTS ) */ - /*************** Requested only one attachement migration test **********/ - if (!nChanges && salt_pass) - { - /* One attachment migration */ - break; - } - /* Salt step 0: process one attachment migration */ -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask |= BNS_EDGE_FORBIDDEN_TEMP; - CorrectFixing_NH_NH_Bonds( pBNS, at, num_atoms ); -#endif - salt_found = MarkSaltChargeGroups( pCG, at, num_atoms, - s_group_info, - t_group_info, - c_group_info, - pBNS, pBD ); -#if ( RESET_EDGE_FORBIDDEN_MASK == 0 ) - pBNS->edge_forbidden_mask &= ~BNS_EDGE_FORBIDDEN_TEMP; -#endif - if (salt_found < 0) - { - bError = salt_found; - break; - } - else - { - if (salt_found > 0) - { - *pbTautFlagsDone |= TG_FLAG_TEST_TAUT__SALTS_DONE; - } - } - salt_pass++; - } /* ( *pbTautFlags & TG_FLAG_TEST_TAUT2_SALTS ) */ - } /* ( *pbTautFlags & TG_FLAG_TEST_TAUT__SALTS ) */ - } while (salt_found && !bError); - - /*************************************************************/ - /* */ - /* M A I N C Y C L E E N D */ - /* */ - /*************************************************************/ - - - if (*pbTautFlags & TG_FLAG_MERGE_TAUT_SALTS) - { - if (!bError && s_group_info /*&& s_group_info->num_candidates > 0*/) - { - ret = MergeSaltTautGroups( pCG, at, num_atoms, s_group_info, - t_group_info, c_group_info, pBNS ); - if (ret < 0) - { - bError = ret; - } - else - { - if (ret > 0) - { - *pbTautFlagsDone |= TG_FLAG_MERGE_TAUT_SALTS_DONE; - } - } - } - } - - if (!bError && t_group_info && - ( t_group_info->bTautFlags & TG_FLAG_VARIABLE_PROTONS ) && - ( t_group_info->bTautFlagsDone & ( TG_FLAG_FOUND_ISOTOPIC_ATOM_DONE | TG_FLAG_FOUND_ISOTOPIC_H_DONE ) )) - { - ret = MakeIsotopicHGroup( at, num_atoms, s_group_info, t_group_info ); - if (ret < 0) - { - bError = ret; - } - } - - /* Success */ - - remove_alt_bond_marks( at, num_atoms ); - - /************************************************ - * Temporarily ignore all non-alternating bonds - * and mark non-ring alt bonds non-stereogenic - ************************************************/ - - ReInitBnStructForAltBns( pBNS, at, num_atoms, 0 ); - MarkRingSystemsAltBns( pBNS, 0 ); - MarkNonStereoAltBns( pBNS, at, num_atoms, 0 ); -#if ( FIX_EITHER_DB_AS_NONSTEREO == 1 ) - /* second time unknown ("Either") alternating bonds are treated as non-stereogenic */ - /* stereobonds bonds that lost stereo get "Either" stereo_type */ - ReInitBnStructForAltBns( pBNS, at, num_atoms, 1 ); - MarkRingSystemsAltBns( pBNS, 1 ); - MarkNonStereoAltBns( pBNS, at, num_atoms, 1 ); -#endif - } - else - { - bError = BNS_OUT_OF_RAM; - /*printf("BNS_OUT_OF_RAM-3\n");*/ - } - - /*(@nnuk : Nauman Ullah Khan) */ - LOG_NO_ARGS("\n################# Modified state after (De)Protonation (L6014:ichi_bns.c) ################\n"); - for (at_prot = 0; at_prot < num_atoms; at_prot++) - { - LOG_MULT_ARGS("Atom %d: Element: %s, Num_H: %d, Charge: %hhd, Radical: %d\n", at_prot, at[at_prot].elname, at[at_prot].num_H, at[at_prot].charge, at[at_prot].radical); - } - LOG_NO_ARGS("\n##########################################################################################\n"); - -exit_function: - - /* djb-rwth: ignoring LLVM warning: variables used to store functions return values */ - pBNS = DeAllocateBnStruct(pBNS); - pBD = DeAllocateBnData(pBD); - /*#if ( MOVE_CHARGES == 1 )*/ - if (c_group_info) - { - if (c_group_info->c_group) - { - inchi_free( c_group_info->c_group ); - } - if (c_group_info->c_candidate) - { - inchi_free( c_group_info->c_candidate ); - } - } - /*#endif*/ - if (s_group_info && s_group_info->s_candidate) - { - inchi_free( s_group_info->s_candidate ); - } - if (pAATG && pAATG->nMarkedAtom) - { - inchi_free( pAATG->nMarkedAtom ); - qzfree( pAATG->nEndPoint ); - /*qzfree( pAATG->nAtTypeTotals );*/ /* nAtTypeTotals is a stack array */ - } - if (t_group_info && t_group_info->tGroupNumber) - { - inchi_free( t_group_info->tGroupNumber ); - t_group_info->tGroupNumber = NULL; - } - - if (!bError && num_atoms == 1 && at[0].at_type == ATT_PROTON && t_group_info && !t_group_info->tni.nNumRemovedExplicitH) - { - /* remove single isolated proton */ - t_group_info->tni.nNumRemovedProtons = 1; - t_group_info->tni.bNormalizationFlags |= FLAG_PROTON_SINGLE_REMOVED; - if (at[0].iso_atw_diff) - { -#if ( FIX_CURE53_ISSUE_NULL_DEREFERENCE_MAKE_A_COPY_OF_T_GROUP_INFO==1 || defined(FIX_IMPOSSIBLE_H_ISOTOPE_BUG) ) - if (at[0].iso_atw_diff <= NUM_H_ISOTOPES) - { - /* djb-rwth: possible false positive oss-fuzz issue #39064660 */ - t_group_info->tni.nNumRemovedProtonsIsotopic[at[0].iso_atw_diff - 1] ++; - } -#else - t_group_info->tni.nNumRemovedProtonsIsotopic[at[0].iso_atw_diff - 1] ++; -#endif - } - if (at_fixed_bonds_out) - { - memcpy(at_fixed_bonds_out, at, num_atoms * sizeof(at_fixed_bonds_out[0])); - } - /*num_atoms --;*/ - } - - - /* - Additional currently unused info: - - nOrigDelta > 0: original structure has been changed - due to fiund augmenting path(s) - nChanges > 0: either alt. bonds or taut. groups have been found - */ - -#ifdef FIX_AROM_RADICAL /* Added 2011-05-09 IPl */ - if (stored_radicals) - { - inchi_free( stored_radicals ); - } -#endif - - return bError ? bError : num_atoms; /* ret = 0 => success, any other => error */ -} - - -/****************************************************************************/ -int nMaxFlow2Check( BN_STRUCT *pBNS, int iedge ) -{ - BNS_EDGE *pEdge = pBNS->edge + iedge; - int nMaxFlow = ( pEdge->cap & EDGE_FLOW_MASK ); /* edge cap */ - - if (nMaxFlow > MAX_BOND_EDGE_CAP) - { - nMaxFlow = MAX_BOND_EDGE_CAP; - } - return nMaxFlow; -} - - -/****************************************************************************/ -int nCurFlow2Check( BN_STRUCT *pBNS, int iedge ) -{ - BNS_EDGE *pEdge = pBNS->edge + iedge; - int nCurFlow = ( pEdge->flow & EDGE_FLOW_MASK ); /* edge flow */ - return nCurFlow; -} - - -/****************************************************************************/ -int nMinFlow2Check( BN_STRUCT *pBNS, int iedge ) -{ - BNS_EDGE *pEdge = pBNS->edge + iedge; - Vertex v1 = pEdge->neighbor1; - Vertex v2 = v1 ^ pEdge->neighbor12; - int f12 = ( pEdge->flow & EDGE_FLOW_MASK ); - int rescap1, rescap2, rescap12, i, iedge_i; - - if (f12 > 0) - { - for (i = 0, rescap1 = 0; i < pBNS->vert[v1].num_adj_edges; i++) - { - iedge_i = pBNS->vert[v1].iedge[i]; - if (iedge_i == iedge) - { - continue; - } - rescap1 += ( pBNS->edge[iedge_i].cap & EDGE_FLOW_MASK ) - ( pBNS->edge[iedge_i].flow & EDGE_FLOW_MASK ); - } - for (i = 0, rescap2 = 0; i < pBNS->vert[v2].num_adj_edges; i++) - { - iedge_i = pBNS->vert[v2].iedge[i]; - if (iedge_i == iedge) - { - continue; - } - rescap2 += ( pBNS->edge[iedge_i].cap & EDGE_FLOW_MASK ) - ( pBNS->edge[iedge_i].flow & EDGE_FLOW_MASK ); - } - rescap12 = inchi_min( rescap1, rescap2 ); - rescap12 = inchi_min( rescap12, f12 ); - return f12 - rescap12; - } - - return 0; -} - - -/****************************************************************************/ -int bSetBondsAfterCheckOneBond( BN_STRUCT *pBNS, - BNS_FLOW_CHANGES *fcd, - int nTestFlow, - inp_ATOM *at, - int num_atoms, - int bChangeFlow0 ) -{ - int ifcd, iedge, new_flow, ret_val, nChanges = 0, bError = 0; - int bChangeFlow; - Vertex v1, v2; - int ineigh1, ineigh2; - BNS_EDGE *pEdge; - - bChangeFlow0 &= ~BNS_EF_CHNG_RSTR; /* do not change pEdge flow in SetBondType */ - if (!bChangeFlow0) - { - return 0; - } - - bChangeFlow = ( bChangeFlow0 & ~BNS_EF_SET_NOSTEREO ); - - /* Find the next to the last changed */ - if (bChangeFlow0 & BNS_EF_SET_NOSTEREO) - { - for (ifcd = 0; NO_VERTEX != ( iedge = fcd[ifcd].iedge ); ifcd++) /* djb-rwth: ignoring LLVM warning: variable used */ - { - iedge = fcd[ifcd].iedge; - pEdge = pBNS->edge + iedge; - if (!pEdge->pass) - { - continue; - } - - if (!ifcd && nTestFlow >= 0) - { - new_flow = nTestFlow; - } - else - { - new_flow = (int) pEdge->flow; - } - - v1 = pEdge->neighbor1; - v2 = pEdge->neighbor12 ^ v1; - if (v1 < num_atoms && v2 < num_atoms && new_flow != pEdge->flow0) - { - if (( pBNS->vert[v1].st_edge.cap0 == pBNS->vert[v1].st_edge.flow0 ) != - ( pBNS->vert[v1].st_edge.cap == pBNS->vert[v1].st_edge.flow ) || - ( pBNS->vert[v2].st_edge.cap0 == pBNS->vert[v2].st_edge.flow0 ) != - ( pBNS->vert[v2].st_edge.cap == pBNS->vert[v2].st_edge.flow )) - { - bChangeFlow |= BNS_EF_SET_NOSTEREO; - nChanges |= BNS_EF_SET_NOSTEREO; - } - } - } - } - else - { - for (ifcd = 0; NO_VERTEX != ( iedge = fcd[ifcd].iedge ); ifcd++) /* djb-rwth: ignoring LLVM warning: variable used */ - { - ; - } - } - - /* restore in reversed order to correctly handle vertex changed more than once */ - for (ifcd -= 1; 0 <= ifcd; ifcd--) - { - - iedge = fcd[ifcd].iedge; - pEdge = pBNS->edge + iedge; - if (!pEdge->pass) - { - continue; - } - - if (!ifcd && nTestFlow >= 0) - { - new_flow = nTestFlow; - } - else - { - new_flow = (int) pEdge->flow; - } - - v1 = pEdge->neighbor1; - v2 = pEdge->neighbor12 ^ v1; - if (v1 < num_atoms && v2 < num_atoms && bChangeFlow && new_flow != pEdge->flow0) - { - ineigh1 = pEdge->neigh_ord[0]; - ineigh2 = pEdge->neigh_ord[1]; - ret_val = SetAtomBondType( pEdge, &at[v1].bond_type[ineigh1], &at[v2].bond_type[ineigh2], new_flow - pEdge->flow0, bChangeFlow ); - if (!IS_BNS_ERROR( ret_val )) - { - nChanges |= ( ret_val > 0 ); - } - else - { - bError = ret_val; - } - } - pEdge->pass = 0; - } - - return bError ? bError : nChanges; -} - - -/****************************************************************************/ -int bRestoreFlowAfterCheckOneBond( BN_STRUCT *pBNS, BNS_FLOW_CHANGES *fcd ) -{ - int ifcd, iedge; - Vertex v1, v2; - BNS_EDGE *pEdge; - - /* Find the next to the last changed */ - for (ifcd = 0; NO_VERTEX != ( iedge = fcd[ifcd].iedge ); ifcd++) /* djb-rwth: ignoring LLVM warning: variable used */ - { - ; - } - - /* Restore in reversed order to correctly handle vertex changed more than once */ - for (ifcd -= 1; 0 <= ifcd; ifcd--) - { - /* Restore edge flow & cap */ - iedge = fcd[ifcd].iedge; - pEdge = pBNS->edge + iedge; - pEdge->flow = fcd[ifcd].flow; - pEdge->cap = fcd[ifcd].cap; - pEdge->pass = 0; - - /* Restore st-flow, cap */ - if (NO_VERTEX != ( v1 = fcd[ifcd].v1 )) - { - pBNS->vert[v1].st_edge.flow = fcd[ifcd].flow_st1; - pBNS->vert[v1].st_edge.cap = fcd[ifcd].cap_st1; - pBNS->vert[v1].st_edge.pass = 0; - } - if (NO_VERTEX != ( v2 = fcd[ifcd].v2 )) - { - pBNS->vert[v2].st_edge.flow = fcd[ifcd].flow_st2; - pBNS->vert[v2].st_edge.cap = fcd[ifcd].cap_st2; - pBNS->vert[v2].st_edge.pass = 0; - } - } - - return 0; -} - - -/****************************************************************************/ -int bSetFlowToCheckOneBond( BN_STRUCT *pBNS, - int iedge, - int flow, - BNS_FLOW_CHANGES *fcd ) -{ - BNS_EDGE *pEdge = pBNS->edge + iedge; - int f12 = ( pEdge->flow & EDGE_FLOW_MASK ); /* the original flow */ - int ifcd = 0; - int nDots = 0; - int i, iedge_i; - - fcd[ifcd].iedge = NO_VERTEX; - - if (f12 < flow) - { - /* Increase edge flow: Grab flow from the neighbors and delete it: set flow12=cap12 = 0 */ - /************************************************************************************/ - /* For example, simulate a new fixed double bond in place of a single bond and */ - /* creates ONE or NONE (in case of a radical on adjacent atom) augmenting paths and */ - /* makes it impossible for the BNS to set same flow as it originally was */ - /************************************************************************************/ - Vertex v1 = pEdge->neighbor1; - Vertex v2 = v1 ^ pEdge->neighbor12; - Vertex v_i; /* neighbor of v1 or v2 */ - BNS_EDGE *pEdge_i; - int delta1, delta2, f, st_edge_rescap; - - if (( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) < flow || - ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) < flow) - { - return BNS_CANT_SET_BOND; - } - if (( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ) < f12 || - ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ) < f12) - { - return BNS_CAP_FLOW_ERR; - } - - fcd[ifcd].iedge = iedge; - fcd[ifcd].flow = pEdge->flow; - fcd[ifcd].cap = pEdge->cap; - - fcd[ifcd].v1 = v1; - fcd[ifcd].flow_st1 = pBNS->vert[v1].st_edge.flow; - fcd[ifcd].cap_st1 = pBNS->vert[v1].st_edge.cap; - - fcd[ifcd].v2 = v2; - fcd[ifcd].flow_st2 = pBNS->vert[v2].st_edge.flow; - fcd[ifcd].cap_st2 = pBNS->vert[v2].st_edge.cap; - - fcd[++ifcd].iedge = NO_VERTEX; /* mark the end of the fcd[] data */ - pEdge->pass |= 64; - - delta1 = delta2 = flow - f12; - - if (f12 > 0) - { - /* Remove old edge flow from the flow and cap of the adjacent vertices' st-edges */ - pBNS->vert[v1].st_edge.cap = ( ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v1].st_edge.cap & ~EDGE_FLOW_ST_MASK ); - pBNS->vert[v2].st_edge.cap = ( ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v2].st_edge.cap & ~EDGE_FLOW_ST_MASK ); - pBNS->vert[v1].st_edge.flow = ( ( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v1].st_edge.flow & ~EDGE_FLOW_ST_MASK ); - pBNS->vert[v2].st_edge.flow = ( ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v2].st_edge.flow & ~EDGE_FLOW_ST_MASK ); - /* Delete current edge flow and capacity */ - pEdge->flow = ( pEdge->flow & ~EDGE_FLOW_MASK ); - } - pEdge->cap = ( pEdge->cap & ~EDGE_FLOW_MASK ); - - /* Grab the adjacent vertex1 radical (st_edge_rescap) if it exists */ - st_edge_rescap = ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) - ( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ); - while (st_edge_rescap && delta1) - { - st_edge_rescap--; /* grab the radical */ - delta1--; - pBNS->vert[v1].st_edge.cap = ( ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v1].st_edge.cap & ~EDGE_FLOW_ST_MASK ); - nDots--; - } - - /* Grab the adjacent vertex2 radical (st_edge_rescap) if it exists */ - st_edge_rescap = ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) - ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ); - while (st_edge_rescap && delta2) - { - st_edge_rescap--; /* grab the radical */ - delta2--; - pBNS->vert[v2].st_edge.cap = ( ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v2].st_edge.cap & ~EDGE_FLOW_ST_MASK ); - nDots--; - } - - /* Grab flows from v1 neighbors */ - for (i = 0; delta1 && i < pBNS->vert[v1].num_adj_edges; i++) - { - iedge_i = pBNS->vert[v1].iedge[i]; - if (iedge_i == iedge) - { - continue; - } - pEdge_i = pBNS->edge + iedge_i; - if (IS_FORBIDDEN( pEdge_i->forbidden, pBNS )) - { - continue; - } - f = ( pEdge_i->flow & EDGE_FLOW_MASK ); - if (f) - { - v_i = pEdge_i->neighbor12 ^ v1; - - fcd[ifcd].iedge = iedge_i; - fcd[ifcd].flow = pEdge_i->flow; - fcd[ifcd].cap = pEdge_i->cap; - - fcd[ifcd].v1 = v_i; - fcd[ifcd].flow_st1 = pBNS->vert[v_i].st_edge.flow; - fcd[ifcd].cap_st1 = pBNS->vert[v_i].st_edge.cap; - - fcd[ifcd].v2 = NO_VERTEX; - fcd[ifcd].flow_st2 = 0; - fcd[ifcd].cap_st2 = 0; - - fcd[++ifcd].iedge = NO_VERTEX; /* mark the end of the fcd[] data */ - pEdge_i->pass |= 64; - - while (f && delta1) - { - f--; - delta1--; - pEdge_i->flow = ( ( pEdge_i->flow & EDGE_FLOW_MASK ) - 1 ) | ( pEdge_i->flow & ~EDGE_FLOW_MASK ); - pBNS->vert[v_i].st_edge.flow = ( ( pBNS->vert[v_i].st_edge.flow & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v_i].st_edge.flow & ~EDGE_FLOW_ST_MASK ); - /* next 2 lines added 01-22-2002 */ - pBNS->vert[v1].st_edge.cap = ( ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v1].st_edge.cap & ~EDGE_FLOW_ST_MASK ); - pBNS->vert[v1].st_edge.flow = ( ( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v1].st_edge.flow & ~EDGE_FLOW_ST_MASK ); - - nDots++; - } - } - } - - /* Grab flows from v2 neighbors */ - for (i = 0; delta2 && i < pBNS->vert[v2].num_adj_edges; i++) - { - iedge_i = pBNS->vert[v2].iedge[i]; - if (iedge_i == iedge) - { - continue; - } - pEdge_i = pBNS->edge + iedge_i; - if (IS_FORBIDDEN( pEdge_i->forbidden, pBNS )) - { - continue; - } - f = ( pEdge_i->flow & EDGE_FLOW_MASK ); - if (f) - { - v_i = pEdge_i->neighbor12 ^ v2; - - fcd[ifcd].iedge = iedge_i; - fcd[ifcd].flow = pEdge_i->flow; - fcd[ifcd].cap = pEdge_i->cap; - - fcd[ifcd].v1 = v_i; - fcd[ifcd].flow_st1 = pBNS->vert[v_i].st_edge.flow; - fcd[ifcd].cap_st1 = pBNS->vert[v_i].st_edge.cap; - - fcd[ifcd].v2 = NO_VERTEX; - fcd[ifcd].flow_st2 = 0; - fcd[ifcd].cap_st2 = 0; - - fcd[++ifcd].iedge = NO_VERTEX; /* mark the end of the fcd[] data */ - pEdge_i->pass |= 64; - - while (f && delta2) - { - f--; - delta2--; - pEdge_i->flow = ( ( pEdge_i->flow & EDGE_FLOW_MASK ) - 1 ) | ( pEdge_i->flow & ~EDGE_FLOW_MASK ); - pBNS->vert[v_i].st_edge.flow = ( ( pBNS->vert[v_i].st_edge.flow & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v_i].st_edge.flow & ~EDGE_FLOW_ST_MASK ); - /* next 2 lines added 01-22-2002 */ - pBNS->vert[v2].st_edge.cap = ( ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v2].st_edge.cap & ~EDGE_FLOW_ST_MASK ); - pBNS->vert[v2].st_edge.flow = ( ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ) - 1 ) | ( pBNS->vert[v2].st_edge.flow & ~EDGE_FLOW_ST_MASK ); - - nDots++; - } - } - } - if (delta1 || delta2) - { - return BNS_CANT_SET_BOND; - } - } - - if (f12 >= flow) - { - /* Decrease edge flow: Redirect flow to the neighbors and delete it on the edge: set flow12=cap12 = 0 */ - /* f12==flow fixes flow through the edge so that BNS cannot change it */ - /**********************************************************************************************/ - /* For example, simulate a removal of a double bond and create ONE or NONE augmenting path */ - /* Make it impossible for BNS to set same flow as it originally was */ - /**********************************************************************************************/ - Vertex v1 = pEdge->neighbor1; - Vertex v2 = ( v1 ^ pEdge->neighbor12 ); - int delta; - /* if NOT (st-cap >= st-flow >= f12 >= flow) then error in the BN structure */ - if (( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ) < f12 || - ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ) < f12 || - ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) < flow || - ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) < flow) - { - return BNS_CAP_FLOW_ERR; - } - fcd[ifcd].iedge = iedge; - fcd[ifcd].flow = pEdge->flow; - fcd[ifcd].cap = pEdge->cap; - - fcd[ifcd].v1 = v1; - fcd[ifcd].flow_st1 = pBNS->vert[v1].st_edge.flow; - fcd[ifcd].cap_st1 = pBNS->vert[v1].st_edge.cap; - - fcd[ifcd].v2 = v2; - fcd[ifcd].flow_st2 = pBNS->vert[v2].st_edge.flow; - fcd[ifcd].cap_st2 = pBNS->vert[v2].st_edge.cap; - - fcd[++ifcd].iedge = NO_VERTEX; /* mark the end of the fcd[] data */ - pEdge->pass |= 64; - - delta = f12 - flow; - - /* Remove current edge flow from st-edges */ - /* -- seem to be a bug -- - pBNS->vert[v1].st_edge.flow = ((pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK)-delta) | (pBNS->vert[v1].st_edge.flow & ~EDGE_FLOW_ST_MASK); - pBNS->vert[v2].st_edge.flow = ((pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK)-delta) | (pBNS->vert[v2].st_edge.flow & ~EDGE_FLOW_ST_MASK); - */ - - /* Replacement to the above 2 lines 01-16-2002 */ - /* Remove old edge flow from the flow of the adjacent vertices' st-edges */ - - pBNS->vert[v1].st_edge.flow = ( ( pBNS->vert[v1].st_edge.flow & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v1].st_edge.flow & ~EDGE_FLOW_ST_MASK ); - pBNS->vert[v2].st_edge.flow = ( ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK ) - f12 ) | ( pBNS->vert[v2].st_edge.flow & ~EDGE_FLOW_ST_MASK ); - - /* Sdded 01-16-2002: reduce st-cap if new flow > 0 */ - /* Remove new edge flow from the cap of the adjacent vertices' st-edges */ - pBNS->vert[v1].st_edge.cap = ( ( pBNS->vert[v1].st_edge.cap & EDGE_FLOW_ST_MASK ) - flow ) | ( pBNS->vert[v1].st_edge.cap & ~EDGE_FLOW_ST_MASK ); - pBNS->vert[v2].st_edge.cap = ( ( pBNS->vert[v2].st_edge.cap & EDGE_FLOW_ST_MASK ) - flow ) | ( pBNS->vert[v2].st_edge.cap & ~EDGE_FLOW_ST_MASK ); - - /* delete current edge flow and capacity */ - pEdge->flow = ( pEdge->flow & ~EDGE_FLOW_MASK ); - pEdge->cap = ( pEdge->cap & ~EDGE_FLOW_MASK ); - nDots = 2 * delta; - } - - return nDots; -} - - -/**************************************************************************** -bAddNewVertex( ... ) - -Connect new (fictitious, temporary) vertex to nVertDoubleBond by a new edge -Add radical (set st-cap=1) to the new vertex, set cap=1 to the new edge -Add radical (set st-cap=1) to nVertSingleBond -Find augmenting path connecting new vertex to nVertSingleBond -This corresponds to moving H-atom from nVertSingleBond to nVertDoubleBond -****************************************************************************/ -int bAddNewVertex( BN_STRUCT *pBNS, - int nVertDoubleBond, - int nCap, - int nFlow, - int nMaxAdjEdges, - int *nDots ) -{ - Vertex vlast = pBNS->num_vertices - 1; - Vertex vnew = pBNS->num_vertices; - Vertex v2 = nVertDoubleBond; - BNS_VERTEX *pVert2 = pBNS->vert + v2; /* pointer to an old vertex */ - BNS_VERTEX *pNewVert = pBNS->vert + vnew; /* pointer to a new vertex */ - - EdgeIndex iedge = pBNS->num_edges; - BNS_EDGE *pEdge = pBNS->edge + iedge; /* pointer to a new edge */ - - if (iedge >= pBNS->max_edges || vnew >= pBNS->max_vertices) - { - return BNS_VERT_EDGE_OVFL; /* edges or vertices overflow */ - } - if (( pBNS->vert[vlast].iedge - pBNS->iedge ) + pBNS->vert[vlast].max_adj_edges + nMaxAdjEdges >= pBNS->max_iedges) - { - return BNS_VERT_EDGE_OVFL; /* iedges overflow */ - } - if (pVert2->num_adj_edges >= pVert2->max_adj_edges || nMaxAdjEdges <= 0) - { - return BNS_VERT_EDGE_OVFL; /* neighbors overflow */ - } - - /* Fill out the new edge, set its cap and flow, connect */ - /* memset( pEdge, 0, sizeof(*pEdge) ); */ - pEdge->cap = pEdge->cap0 = nCap; - pEdge->flow = pEdge->flow0 = nFlow; - pEdge->pass = 0; - pEdge->neighbor1 = v2; - pEdge->neighbor12 = v2 ^ vnew; - pEdge->forbidden = 0; - - /* Fill out the new vertex */ - /* memset( pNewVert, 0, sizeof(*pNewVert) ); */ - pNewVert->max_adj_edges = nMaxAdjEdges; - pNewVert->num_adj_edges = 0; - pNewVert->st_edge.cap0 = pNewVert->st_edge.cap = nCap; - pNewVert->st_edge.flow0 = pNewVert->st_edge.flow = nFlow; - pNewVert->st_edge.pass = 0; /* add initialization; added 2006-03-25 */ - pNewVert->iedge = pBNS->vert[vlast].iedge + pBNS->vert[vlast].max_adj_edges; - pNewVert->type = BNS_VERT_TYPE_TEMP; - *nDots += nCap - nFlow; - - pEdge->neigh_ord[v2 > vnew] = pVert2->num_adj_edges; - pEdge->neigh_ord[v2 < vnew] = pNewVert->num_adj_edges; - - /* Connect new edge to v2 */ - pVert2->iedge[pVert2->num_adj_edges++] = iedge; - /* Connect new edge to vnew */ - pNewVert->iedge[pNewVert->num_adj_edges++] = iedge; - - /* Fix v2 flow and cap */ - *nDots -= (int) pVert2->st_edge.cap - (int) pVert2->st_edge.flow; - pVert2->st_edge.flow += nFlow; - if (pVert2->st_edge.cap < pVert2->st_edge.flow) - { - pVert2->st_edge.cap = pVert2->st_edge.flow; - } - *nDots += (int) pVert2->st_edge.cap - (int) pVert2->st_edge.flow; - - pBNS->num_edges++; - pBNS->num_vertices++; - - return vnew; -} - - -/****************************************************************************/ -int AddNewEdge( BNS_VERTEX *p1, - BNS_VERTEX *p2, - BN_STRUCT *pBNS, - int nEdgeCap, - int nEdgeFlow ) -{ - int ip1 = (int) ( p1 - pBNS->vert ); - int ip2 = (int) ( p2 - pBNS->vert ); - int ie = pBNS->num_edges; - BNS_EDGE *e = pBNS->edge + ie; - - /* Debug: check bounds */ - if (ip1 >= pBNS->max_vertices || ip1 < 0 || - ip2 >= pBNS->max_vertices || ip2 < 0 || - ie >= pBNS->max_edges || ie < 0 || - ( p1->iedge - pBNS->iedge ) < 0 || - ( p1->iedge - pBNS->iedge ) + p1->max_adj_edges > pBNS->max_iedges || - ( p2->iedge - pBNS->iedge ) < 0 || - ( p2->iedge - pBNS->iedge ) + p2->max_adj_edges > pBNS->max_iedges || - p1->num_adj_edges >= p1->max_adj_edges || - p2->num_adj_edges >= p2->max_adj_edges) - { - return BNS_VERT_EDGE_OVFL; - } - - /* Clear the edge */ - memset( e, 0, sizeof( *e ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - - /* Connect */ - e->neighbor1 = inchi_min( ip1, ip2 ); - e->neighbor12 = ip1 ^ ip2; - p1->iedge[p1->num_adj_edges] = ie; - p2->iedge[p2->num_adj_edges] = ie; - e->neigh_ord[ip1 > ip2] = p1->num_adj_edges++; - e->neigh_ord[ip1 < ip2] = p2->num_adj_edges++; - e->cap = e->cap0 = nEdgeCap; - e->flow = e->flow0 = nEdgeFlow; - p1->st_edge.flow += nEdgeFlow; - p2->st_edge.flow += nEdgeFlow; - if (p1->st_edge.cap < p1->st_edge.flow) - { - p1->st_edge.cap = p1->st_edge.flow; - } - if (p2->st_edge.cap < p2->st_edge.flow) - { - p2->st_edge.cap = p2->st_edge.flow; - } - pBNS->num_edges++; - - return ie; -} - - -/****************************************************************************/ -BNS_IEDGE GetEdgeToGroupVertex( BN_STRUCT *pBNS, Vertex v1, AT_NUMB type ) -{ - if (v1 < pBNS->num_atoms) - { - Vertex v2; - BNS_EDGE *pEdge1; - BNS_VERTEX *pVert1 = pBNS->vert + v1; - int i = pVert1->num_adj_edges - 1; - - while (0 <= i) - { - pEdge1 = pBNS->edge + pVert1->iedge[i]; - v2 = pEdge1->neighbor12 ^ v1; - if (pBNS->vert[v2].type == type) - { - return IS_FORBIDDEN( pEdge1->forbidden, pBNS ) ? NO_VERTEX : pVert1->iedge[i]; - } - i--; - } - return NO_VERTEX; /* not found t-group */ - } - else - { - if (v1 < pBNS->num_vertices) - { - return NO_VERTEX; - } - } - - return BNS_VERT_EDGE_OVFL; -} - - -/****************************************************************************/ -Vertex GetGroupVertex( BN_STRUCT *pBNS, Vertex v1, AT_NUMB type ) -{ - if (v1 < pBNS->num_atoms) - { - Vertex v2; - BNS_EDGE *pEdge1; - BNS_VERTEX *pVert1 = pBNS->vert + v1; - int i = pVert1->num_adj_edges - 1; - - AT_NUMB type2; - - if (type == BNS_VERT_TYPE_ENDPOINT) - { - type2 = BNS_VERT_TYPE_TGROUP; - } - else - { - if (type == BNS_VERT_TYPE_C_POINT) - { - type2 = BNS_VERT_TYPE_C_GROUP; - } - else - { - type2 = 0; - } - } - - if (( pVert1->type & type ) == type) - { - while (0 <= i) - { - pEdge1 = pBNS->edge + pVert1->iedge[i]; - v2 = pEdge1->neighbor12 ^ v1; - if (pBNS->vert[v2].type == type2) - { - if (IS_FORBIDDEN( pEdge1->forbidden, pBNS )) - { - return NO_VERTEX; - } - return v2; - } - i--; - } - } - return BNS_BOND_ERR; /* not found t-group */ - } - else - { - if (v1 < pBNS->num_vertices) - { - return NO_VERTEX; - } - } - - return BNS_VERT_EDGE_OVFL; -} - - -/****************************************************************************/ -int bAddStCapToAVertex( BN_STRUCT *pBNS, - Vertex v1, - Vertex v2, - VertexFlow *nOldCapVertSingleBond, - int *nDots, - int bAdjacentDonors ) -{ - BNS_VERTEX *pVert1 = pBNS->vert + v1; - BNS_VERTEX *pVert; - BNS_EDGE *pEdge; - Vertex v; - int i, n; - VertexFlow nNewCap; - - /* Change v1: increment its st-cap */ - n = 0; - nOldCapVertSingleBond[n++] = pVert1->st_edge.cap; - /*if ( pVert1->st_edge.cap == pVert1->st_edge.flow ) {*/ - pVert1->st_edge.cap++; - *nDots += 1; - - /*}*/ - /* increment caps of adjacent edges if - (1) the neighbor has st-cap != 0 and - (2) (edge cap==0) OR (nSumEdgeCap < pVert1->st_edge.cap && pVert->st_edge.flow > pVert1->st_edge.cap) - */ - if (!( pVert1->type & BNS_VERT_TYPE_ANY_GROUP )) - { - /* - AT_NUMB nSumEdgeCap = 0; - for ( i = 0; i < pVert1->num_adj_edges; i ++ ) { - pEdge = pBNS->edge + pVert1->iedge[i]; - nSumEdgeCap += pEdge->cap; - } - */ - /* do not increment caps of t-group or c-group edges */ - for (i = 0; i < pVert1->num_adj_edges; i++) - { - pEdge = pBNS->edge + pVert1->iedge[i]; - nOldCapVertSingleBond[n++] = pEdge->cap; /* save edge cap */ - v = pEdge->neighbor12 ^ v1; - if (v == v2 && !bAdjacentDonors) - { - continue; - } - pVert = pBNS->vert + v; - if (pVert->type & BNS_VERT_TYPE_ANY_GROUP) - continue; - nNewCap = inchi_min( pVert->st_edge.cap, pVert1->st_edge.cap ); - nNewCap = inchi_min( nNewCap, MAX_BOND_EDGE_CAP ); - pEdge->cap = nNewCap; /* change edge cap */ - /* - if ( pVert->st_edge.cap > 0 && !pEdge->cap ) { - pEdge->cap ++; - } else - if ( pVert->st_edge.flow > pVert1->st_edge.cap && - pEdge->cap < MAX_BOND_EDGE_CAP && - nSumEdgeCap < pVert1->st_edge.cap ) { - pEdge->cap ++; - } - */ - } - } - - return n; /* number of elements in nOldCapVertSingleBond[*] */ -} - - -#define BNS_CHK_ALTP_NO_ALTPATH 0 -#define BNS_CHK_ALTP_SAME_TGROUP 1 -#define BNS_CHK_ALTP_SAME_VERTEX 2 -#define BNS_CHK_ALTP_SET_SUCCESS 4 - - -/****************************************************************************/ -int bSetBnsToCheckAltPath( BN_STRUCT *pBNS, - int nVertDoubleBond, - int nVertSingleBond, - AT_NUMB type, - int path_type, - ALT_PATH_CHANGES *apc, - BNS_FLOW_CHANGES *fcd, - int *nDots ) -{ - - if (!pBNS->vert[nVertDoubleBond].st_edge.flow && - - !( path_type == ALT_PATH_MODE_REM2H_CHG || - path_type == ALT_PATH_MODE_ADD2H_CHG || - path_type == ALT_PATH_MODE_REM2H_TST || - path_type == ALT_PATH_MODE_ADD2H_TST ) - ) - { - return BNS_CHK_ALTP_NO_ALTPATH; - } - else - { - Vertex vNew; - Vertex v1 = nVertSingleBond; - Vertex v2 = nVertDoubleBond; - - BNS_VERTEX *pVert1 = pBNS->vert + v1; - BNS_VERTEX *pVert2 = pBNS->vert + v2; - int n, bAdjacentDonors = 0; - int ifcd = 0; - - Vertex t1 = NO_VERTEX; - Vertex t2 = NO_VERTEX; - int iapc; - - /*#if ( TEST_REMOVE_S_ATOMS == 1 )*/ /* && ALT_PATH_MODE_4_SALT == path_type */ - if (( *pBNS->pbTautFlags & TG_FLAG_TEST_TAUT2_SALTS ) && - ALT_PATH_MODE_4_SALT2 == path_type && - ( BNS_VERT_TYPE_ENDPOINT & type )) - { - /* - --------------------------------------------------------- - \ action | DB action (v2) | SB action (v1) | - vertex \ | accept H @ vertex | donate H @ vertex | - type \ | nVertDoubleBond | nVertSingleBond | - ----------------+-------------------+-------------------+ - -ZH (v1) | error | -ZH(.) | - (cap>0 on edge | | increment | - except v1-v2) | | st-cap on Z | - ----------------+-------------------+-------------------+ - =Z (v2) | =Z-(.) | error | - (st-flow>0) | add fict vertex | | - | with st-cap=1 | | - ----------------+-------------------+-------------------+ - endpoint | T(.) | T-(.) | - of t-group | increment | add fict vertex | - represented | st-cap on T | with st-cap=1 | - by fictitious | | | - vertex T | | | - --------------------------------------------------------- - */ - - int bSet_v1; /* indicator: v1 has been set */ - int bSet_v2; /* indicator: v2 has been set */ - int i; - - Vertex v1t = NO_VERTEX; - Vertex v2t = NO_VERTEX; - Vertex v1Act, v2Act; - Vertex v; - - memset( apc, 0, sizeof( *apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - fcd[ifcd].iedge = NO_VERTEX; - *nDots = 0; - - if (v1 == v2) - { - return BNS_CHK_ALTP_SAME_VERTEX; - } - - /* Check whether v1 has neighbors adjacent to multiple bonds */ - for (i = 0, n = 0; i < pVert1->num_adj_edges; i++) - { - v = ( pBNS->edge + pVert1->iedge[i] )->neighbor12 ^ v1; /* v is adjacent to v1 */ - if (v == v2) - { - continue; /* ignore connection to v2 */ - } - n += ( pBNS->vert[v].st_edge.cap > 0 ); - } - if (!n) - { - return BNS_CHK_ALTP_NO_ALTPATH; /* the vertex cannot have flow */ - } - - v1Act = v1; - v2Act = v2; - - /* find t-group that contains v1 */ - if (( pVert1->type & type ) == type) - { - v1t = GetGroupVertex( pBNS, v1, type ); - if (IS_BNS_ERROR( v1t )) - { - return v1t; - } - if (v1t != NO_VERTEX) - { - v1Act = v1t; - } - } - /* Find t-group that contains v2 */ - if (( pVert2->type & type ) == type) - { - v2t = GetGroupVertex( pBNS, v2, type ); - if (IS_BNS_ERROR( v2t )) - { - return v2t; - } - if (v2t != NO_VERTEX) - { - v2Act = v2t; - } - } - if (v1t != NO_VERTEX && v1t == v2t) - { - return BNS_CHK_ALTP_SAME_TGROUP; - } - - bSet_v1 = bSet_v2 = 0; - /* create new edges adjacent to v1t or v2 */ - iapc = 0; - if (v1t != NO_VERTEX) - { - /* Create new edge and vertex, connect to v1t */ - vNew = bAddNewVertex( pBNS, v1t, 1, 0, 1, nDots ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[iapc] = vNew; - apc->bSetNew[iapc] = 1; - bSet_v1 = 1; - iapc++; - } - if (v2t == NO_VERTEX) - { - /* Create new edge and vertex, connect to v2 */ - vNew = bAddNewVertex( pBNS, v2, 1, 0, 1, nDots ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[iapc] = vNew; - apc->bSetNew[iapc] = 1; - bSet_v2 = 1; - iapc++; - } - - /* Add st-cap to v1 and/or v2t */ - iapc = 0; - if (!bSet_v1) - { - /* Add st-cap to v1 */ - if (v1t != NO_VERTEX) /* djb-rwth: addressing coverity CID #499551 -- condition properly written */ - { - return BNS_BOND_ERR; - } - n = bAddStCapToAVertex( pBNS, v1, v2Act, apc->nOldCapsVert[iapc], nDots, 0 ); - apc->bSetOldCapsVert[iapc] = n; - apc->vOldVert[iapc] = v1; - iapc++; - } - if (!bSet_v2) - { - /* Add st-cap to v2t */ - if (v2t == NO_VERTEX) - { - return BNS_BOND_ERR; - } - n = bAddStCapToAVertex( pBNS, v2t, v1Act, apc->nOldCapsVert[iapc], nDots, 0 ); - apc->bSetOldCapsVert[iapc] = n; - apc->vOldVert[iapc] = v2t; - iapc++; - } - if (*nDots < 0 || *nDots % 2) - { - return BNS_SET_ALTP_ERR; - } - return BNS_CHK_ALTP_SET_SUCCESS; - } - - /* ( *pBNS->pbTautFlags & TG_FLAG_TEST_TAUT2_SALTS ) */ - - /*#endif*/ - - /* ( TEST_REMOVE_S_ATOMS == 1 && ALT_PATH_MODE_4_SALT == path_type ) */ - - if (path_type == ALT_PATH_MODE_REM2H_CHG || - path_type == ALT_PATH_MODE_ADD2H_CHG || - path_type == ALT_PATH_MODE_REM2H_TST || - path_type == ALT_PATH_MODE_ADD2H_TST) - { - /* added 2004-03-18 */ - - int bDonors = ( path_type == ALT_PATH_MODE_REM2H_CHG ) || ( path_type == ALT_PATH_MODE_REM2H_TST ); - - int bSet_v1; /* indicator: v1 has been set */ - int bSet_v2; /* indicator: v2 has been set */ - int i, cap = 1; - Vertex v1t = NO_VERTEX; - Vertex v2t = NO_VERTEX; - Vertex v1Act, v2Act; - Vertex v; - - memset( apc, 0, sizeof( *apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - fcd[ifcd].iedge = NO_VERTEX; - *nDots = 0; - /* - if ( v1 == v2 ) { - return BNS_CHK_ALTP_SAME_VERTEX; - } - */ - - /* Check whether v1 and v2 have proper neighbors */ - for (i = 0, n = bAdjacentDonors = 0; i < pVert1->num_adj_edges; i++) - { - v = ( pBNS->edge + pVert1->iedge[i] )->neighbor12 ^ v1; /* v is adjacent to v1 */ - /* do not ignore connection to v2 - if ( v == v2 ) - continue; - */ - n += bDonors ? ( pBNS->vert[v].st_edge.cap > 0 ) - : ( ( pBNS->edge + pVert1->iedge[i] )->flow > 0 ); - bAdjacentDonors += bDonors ? ( v == v2 ) && ( ( pBNS->edge + pVert1->iedge[i] )->flow < MAX_BOND_EDGE_CAP ) : 0; - /* two donors connected by a single or double bond */ - } - - if (!n && !bAdjacentDonors) - { - return BNS_CHK_ALTP_NO_ALTPATH; /* the vertex cannot have flow */ - } - for (i = 0, n = bAdjacentDonors = 0; i < pVert2->num_adj_edges; i++) - { - v = ( pBNS->edge + pVert2->iedge[i] )->neighbor12 ^ v2; /* v is adjacent to v2 */ - /* do not ignore connection to v1 - if ( v == v1 ) - continue; - */ - n += bDonors ? ( pBNS->vert[v].st_edge.cap > 0 ) : ( ( pBNS->edge + pVert2->iedge[i] )->flow > 0 ); - bAdjacentDonors += bDonors ? ( v == v1 ) && ( ( pBNS->edge + pVert2->iedge[i] )->flow < MAX_BOND_EDGE_CAP ) : 0; - /* two donors connected by a single or double bond */ - } - - if (!n && !bAdjacentDonors) - { - return BNS_CHK_ALTP_NO_ALTPATH; /* the vertex cannot have flow */ - } - - v1Act = v1; - v2Act = v2; - - /* Find t-group that contains v1 */ - if (( pVert1->type & type ) == type) - { - v1t = GetGroupVertex( pBNS, v1, type ); - if (BNS_BOND_ERR == v1t) - { - v1t = NO_VERTEX; - } - else - { - if (IS_BNS_ERROR( v1t )) - { - return v1t; - } - else - { - if (v1t != NO_VERTEX) - { - v1Act = v1t; - } - } - } - } - - /* Find t-group that contains v2 */ - if (( pVert2->type & type ) == type) - { - v2t = GetGroupVertex( pBNS, v2, type ); - if (BNS_BOND_ERR == v2t) - { - v2t = NO_VERTEX; - } - else - { - if (IS_BNS_ERROR( v2t )) - { - return v2t; - } - else - { - if (v2t != NO_VERTEX) - { - v2Act = v2t; - } - } - } - } - - if (v1t != NO_VERTEX && v1t == v2t) - { - cap = 2; /* same t-group */ - } - - /* bAddNewVertex: (bDonors != 0) == (vit != NO_VERTEX), i=1,2 */ - bSet_v1 = bSet_v2 = 0; - /* create new edges adjacent to v1t or v2 */ - iapc = 0; - if (( bDonors != 0 ) == ( v1t != NO_VERTEX )) - { - /* Create new edge and vertex, connect to v1Act */ - vNew = bAddNewVertex( pBNS, v1Act, cap, 0, 1, nDots ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[iapc] = vNew; - apc->bSetNew[iapc] = 1; - bSet_v1 = 1; - iapc++; - } - if (( bDonors != 0 ) == ( v2t != NO_VERTEX ) && cap == 1) - { - /* Create new edge and vertex, connect to v2Act; do not do it if cap==2 */ - vNew = bAddNewVertex( pBNS, v2Act, cap, 0, 1, nDots ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[iapc] = vNew; - apc->bSetNew[iapc] = 1; - bSet_v2 = 1; - iapc++; - } - else - { - if (( bDonors != 0 ) == ( v2t != NO_VERTEX )) - { - bSet_v2 = 1; - } - } - - /* Add st-cap to v1 and/or v2t */ - iapc = 0; - /* If cap=2 then just increment st_cap 2 times */ - if (!bSet_v1) - { - /* Add st-cap to v1 */ - if (( bDonors != 0 ) == ( v1t != NO_VERTEX )) - { - return BNS_BOND_ERR; - } - n = bAddStCapToAVertex( pBNS, v1Act, v2Act, apc->nOldCapsVert[iapc], nDots, bAdjacentDonors ); - apc->bSetOldCapsVert[iapc] = n; - apc->vOldVert[iapc] = v1Act; - iapc++; - } - if (!bSet_v2) - { - /* Add st-cap to v2t */ - if (( bDonors != 0 ) == ( v2t != NO_VERTEX )) - { - return BNS_BOND_ERR; - } - n = bAddStCapToAVertex( pBNS, v2Act, v1Act, apc->nOldCapsVert[iapc], nDots, bAdjacentDonors ); - apc->bSetOldCapsVert[iapc] = n; - apc->vOldVert[iapc] = v2Act; - iapc++; - } - if (*nDots < 0 || *nDots % 2) - { - return BNS_SET_ALTP_ERR; - } - return BNS_CHK_ALTP_SET_SUCCESS; - } - - if (path_type == ALT_PATH_MODE_REM_PROTON) - { - /* added 2004-03-05 */ - if (v1 >= 0 && v2 >= 0 && - ( pVert1->type & BNS_VERT_TYPE_ANY_GROUP ) && - ( pVert2->type & BNS_VERT_TYPE_ANY_GROUP )) - { - /* Create new edge and vertex, connect to v2 */ - if (( pBNS->vert[v1].type & BNS_VERT_TYPE_C_GROUP ) && - ( pBNS->vert[v1].st_edge.flow == 2 * pBNS->vert[v1].num_adj_edges )) - { - /* so far in a charge group max edge flow = 1 2004-03-08 */ - return BNS_CHK_ALTP_NO_ALTPATH; - } - memset( apc, 0, sizeof( *apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - fcd[ifcd].iedge = NO_VERTEX; - *nDots = 0; - iapc = 0; - - vNew = bAddNewVertex( pBNS, v2, 1, 0, 1, nDots ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[iapc] = vNew; - apc->bSetNew[iapc] = 1; - /*iapc ++;*/ - /* add st-cap (dot) to v1 */ - n = bAddStCapToAVertex( pBNS, v1, v2, apc->nOldCapsVert[iapc], nDots, 0 ); - apc->bSetOldCapsVert[iapc] = n; - apc->vOldVert[iapc] = v1; - iapc++; - return BNS_CHK_ALTP_SET_SUCCESS; - } - } - -#if ( NEUTRALIZE_ENDPOINTS == 1 ) /* { */ - - *nDots = 0; - memset( apc, 0, sizeof( *apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - fcd[ifcd].iedge = NO_VERTEX; - - if (type & BNS_VERT_TYPE_ENDPOINT) - { - BNS_IEDGE iedge; - AT_NUMB type2; - int ret2; - /* prohibit charge movement */ - type2 = BNS_VERT_TYPE_C_GROUP; - iedge = GetEdgeToGroupVertex( pBNS, v1, type2 ); - if (iedge != NO_VERTEX) - { - /* Set flow=1 on an edge to a c-group vertex to make sure - there is no positive charge when moving tautomeric H-atoms */ - ret2 = bSetFlowToCheckOneBond( pBNS, iedge, 1, fcd + ifcd ); - if (IS_BNS_ERROR( ret2 )) - { - return ret2; - } - *nDots += ret2; - while (fcd[ifcd].iedge != NO_VERTEX) - { - ifcd++; - } - } - - iedge = GetEdgeToGroupVertex( pBNS, v2, type2 ); - - if (iedge != NO_VERTEX) - { - /* Set flow=1 on an edge to a c-group vertex to make sure - there is no positive charge when moving tautomeric H-atoms */ - - ret2 = bSetFlowToCheckOneBond( pBNS, iedge, 1, fcd + ifcd ); - - if (IS_BNS_ERROR( ret2 )) - { - return ret2; - } - *nDots += ret2; - while (fcd[ifcd].iedge != NO_VERTEX) - { - ifcd++; - } - } - - /* Set hydrogen counts */ - type2 = BNS_VERT_TYPE_TGROUP; - iedge = GetEdgeToGroupVertex( pBNS, v1, type2 ); - if (iedge != NO_VERTEX) - { - /* Set flow=1 on an edge to a t-group vertex to make sure there is - a moveable hydrogen atom or (-) on v1 when moving tautomeric H-atoms */ -#if ( FIX_H_CHECKING_TAUT == 1 ) - ret2 = bSetFlowToCheckOneBond( pBNS, iedge, 1, fcd + ifcd ); - if (IS_BNS_ERROR( ret2 )) - { - return ret2; - } - *nDots += ret2; - while (fcd[ifcd].iedge != NO_VERTEX) - { - ifcd++; - } -#else - t1 = pBNS->edge[iedge].neighbor12 ^ v1; -#endif - } - - iedge = GetEdgeToGroupVertex( pBNS, v2, type2 ); - if (iedge != NO_VERTEX) - { - /* Set flow=0 on an edge to a t-group vertex to make sure there is - no moveable hydrogen atom or (-) on v2 when moving tautomeric H-atoms */ -#if ( FIX_H_CHECKING_TAUT == 1 ) - ret2 = bSetFlowToCheckOneBond( pBNS, iedge, 0, fcd + ifcd ); - if (IS_BNS_ERROR( ret2 )) - { - return ret2; - } - *nDots += ret2; - while (fcd[ifcd].iedge != NO_VERTEX) - { - ifcd++; - } -#else - t2 = pBNS->edge[iedge].neighbor12 ^ v2; -#endif - } - -#if ( FIX_H_CHECKING_TAUT == 1 ) -#else - if (t1 == t2 && t1 != NO_VERTEX) - { - return BNS_CHK_ALTP_SAME_TGROUP; - } -#endif - - iapc = 0; - /* Create new edge and vertex with cap=1 at v2 and/or t1 */ - if (t1 != NO_VERTEX) - { - /* Create new edge and vertex, connect to t1 */ - vNew = bAddNewVertex( pBNS, t1, 1/*cap*/, 0/*flow*/, 1/*max_adj_edges*/, nDots ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[iapc] = vNew; - apc->bSetNew[iapc] = 1; - iapc++; - } - if (t2 == NO_VERTEX) - { - /* Create new edge and vertex, connect to v2 */ - vNew = bAddNewVertex( pBNS, v2, 1/*cap*/, 0/*flow*/, 1/*max_adj_edges*/, nDots ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[iapc] = vNew; - apc->bSetNew[iapc] = 1; - iapc++; - } - - /* Add st-cap to v1 and/or v2t */ - iapc = 0; - if (t1 == NO_VERTEX) - { - /* Add st-cap to v1 */ - n = bAddStCapToAVertex( pBNS, v1, (Vertex) ( t2 == NO_VERTEX ? v2 : t2 ), apc->nOldCapsVert[iapc], nDots, 0 ); /* djb-rwth: addressing coverity CID #499501 -- condition works as expected for t2 == -2 */ - apc->bSetOldCapsVert[iapc] = n; - apc->vOldVert[iapc] = v1; - iapc++; - } - if (t2 != NO_VERTEX) - { - /* Add st-cap to t2 */ - n = bAddStCapToAVertex( pBNS, t2, (Vertex) ( t1 == NO_VERTEX ? v1 : t1 ), apc->nOldCapsVert[iapc], nDots, 0 ); - apc->bSetOldCapsVert[iapc] = n; - apc->vOldVert[iapc] = t2; - iapc++; - } - } - else - { - /* Create new edge and vertex, connect to v2 */ - vNew = bAddNewVertex( pBNS, v2, 1 /* cap*/, 0 /* flow */, 1 /* max_adj_edges */, nDots ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[0] = vNew; - apc->bSetNew[0] = 1; - - /* add st-cap to v1 */ - n = bAddStCapToAVertex( pBNS, v1, v2, apc->nOldCapsVert[0], nDots, 0 ); - apc->bSetOldCapsVert[0] = n; - apc->vOldVert[0] = v1; - } -#else /* } NEUTRALIZE_ENDPOINTS == 0 {*/ - - *nDots = 0; - memset( apc, 0, sizeof( *apc ) ); - fcd[ifcd].iedge = NO_VERTEX; - - /* Create new edge and vertex, connect to v2 */ - vNew = bAddNewVertex( pBNS, v2, 1 /* cap*/, 0 /* flow */, 1 /* max_adj_edges */, nDots, 0 ); - if (IS_BNS_ERROR( vNew )) - { - return vNew; - } - apc->vNewVertex[0] = vNew; - apc->bSetNew[0] = 1; - - /* Add st-cap to v1 */ - n = bAddStCapToAVertex( pBNS, v1, v2, apc->nOldCapsVert[0], nDots ); - apc->bSetOldCapsVert[0] = n; - apc->vOldVert[0] = v1; -#endif /* } NEUTRALIZE_ENDPOINTS */ - - if (*nDots < 0 || *nDots % 2) - { - return BNS_SET_ALTP_ERR; - } - return BNS_CHK_ALTP_SET_SUCCESS; - } - - /*return BNS_CHK_ALTP_NO_ALTPATH;*/ -} - - -/****************************************************************************/ -int bRestoreBnsAfterCheckAltPath( BN_STRUCT *pBNS, - ALT_PATH_CHANGES *apc, - int bChangeFlow ) - /* int nVertDoubleBond, int nVertSingleBond, int nNewVertex, AT_NUMB *nOldCapVertSingleBond */ -{ - BNS_EDGE *pEdge; - Vertex vNew; - Vertex vOld; - BNS_VERTEX *pOldVert; - BNS_VERTEX *pNewVert; - int i, j, n; /* djb-rwth: removing redundant variables */ - - /* djb-rwth: removing redundant code */ - - if (bChangeFlow & BNS_EF_UPD_H_CHARGE) - { - /* Remove new temp. vertices and edges connectong them to the structure */ - for (i = sizeof( apc->bSetNew ) / sizeof( apc->bSetNew[0] ) - 1; 0 <= i; i--) - { - if (apc->bSetNew[i]) - { - vNew = apc->vNewVertex[i]; - pNewVert = pBNS->vert + vNew; - for (j = 0; j < pNewVert->num_adj_edges; j++) - { - pEdge = pBNS->edge + pNewVert->iedge[j]; - vOld = pEdge->neighbor12 ^ vNew; - pOldVert = pBNS->vert + vOld; - pOldVert->st_edge.flow -= pEdge->flow; - pOldVert->st_edge.cap -= pEdge->flow; - /* disconnect new edge from pOldVert */ - pOldVert->iedge[--pOldVert->num_adj_edges] = 0; - /* clear the new edge */ - memset( pEdge, 0, sizeof( *pEdge ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - /* and decrement the total number of edges */ - pBNS->num_edges--; - } - /* Clear the new vertex */ - memset( pNewVert, 0, sizeof( *pNewVert ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - /* and decrement the total number of vertices - (new vertice ids are contiguous) */ - pBNS->num_vertices--; - /* djb-rwth: removing redundant code */ - } - } - - /* Restore changed caps of old vertices */ - for (i = sizeof( apc->bSetOldCapsVert ) / sizeof( apc->bSetOldCapsVert[0] ) - 1; - 0 <= i; - i--) - { - if ((n = apc->bSetOldCapsVert[i])) /* djb-rwth: addressing LLVM warning */ - { - pOldVert = pBNS->vert + apc->vOldVert[i]; - if (pOldVert->st_edge.flow <= apc->nOldCapsVert[i][0]) - { - pOldVert->st_edge.cap = apc->nOldCapsVert[i][0]; - n--; - /* djb-rwth: removing redundant code */ - for (j = 0; j < n && j < pOldVert->num_adj_edges; j++) - { - pEdge = pBNS->edge + pOldVert->iedge[j]; - pEdge->cap = apc->nOldCapsVert[i][j + 1]; - } - } - } - } - } - else - { - /* Restore changed caps of old vertices */ - for (i = sizeof( apc->bSetOldCapsVert ) / sizeof( apc->bSetOldCapsVert[0] ) - 1; 0 <= i; i--) - { - if ((n = apc->bSetOldCapsVert[i])) /* djb-rwth: addressing LLVM warning */ - { - pOldVert = pBNS->vert + apc->vOldVert[i]; - pOldVert->st_edge.cap = apc->nOldCapsVert[i][0]; - n--; - /* djb-rwth: removing redundant code */ - for (j = 0; j < n && j < pOldVert->num_adj_edges; j++) - { - pEdge = pBNS->edge + pOldVert->iedge[j]; - pEdge->cap = apc->nOldCapsVert[i][j + 1]; - } - } - } - - /* Remove new temp. vertices and edges connectong them to the structure */ - for (i = sizeof( apc->bSetNew ) / sizeof( apc->bSetNew[0] ) - 1; 0 <= i; i--) - { - if (apc->bSetNew[i]) - { - vNew = apc->vNewVertex[i]; - pNewVert = pBNS->vert + vNew; - for (j = 0; j < pNewVert->num_adj_edges; j++) - { - pEdge = pBNS->edge + pNewVert->iedge[j]; - vOld = pEdge->neighbor12 ^ vNew; - pOldVert = pBNS->vert + vOld; - /* disconnect new edge from pOldVert */ - pOldVert->iedge[--pOldVert->num_adj_edges] = 0; - /* clear the new edge */ - memset( pEdge, 0, sizeof( *pEdge ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - /* and decrement the total number of edges */ - pBNS->num_edges--; - } - /* Clear the new vertex */ - memset( pNewVert, 0, sizeof( *pNewVert ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - /* and decrement the total number of vertices (new vertice ids are contiguous */ - pBNS->num_vertices--; - /* djb-rwth: removing redundant code */ - } - } - } - - return 0; -} - - -/****************************************************************************/ -int bExistsAnyAltPath( CANON_GLOBALS *pCG, - BN_STRUCT *pBNS, - BN_DATA *pBD, - inp_ATOM *at, - int num_atoms, - int nVert2, - int nVert1, - int path_type ) -{ - int nRet1, nRet2; - - nRet1 = bExistsAltPath( pCG, pBNS, pBD, NULL, at, num_atoms, nVert2, nVert1, path_type ); - - if (nRet1 > 0) - { - return nRet1; - } - - nRet2 = bExistsAltPath( pCG, pBNS, pBD, NULL, at, num_atoms, nVert1, nVert2, path_type ); - - if (nRet2 > 0) - { - return nRet2; - } - if (IS_BNS_ERROR( nRet1 )) - { - return nRet1; - } - if (IS_BNS_ERROR( nRet2 )) - { - return nRet2; - } - - return 0; -} - - -#define ALT_PATH_TAUTOM 1 -#define ALT_PATH_CHARGE 2 -#define ALT_PATH_4_SALT 3 - - -/****************************************************************************/ -int bIsBnsEndpoint( BN_STRUCT *pBNS, int v ) -{ - int i, vt; - BNS_VERTEX *pVert; /* vertices */ - BNS_EDGE *pEdge; /* edges */ - - if (0 <= v && v < pBNS->num_atoms && ( pVert = pBNS->vert + v ) && ( pVert->type & BNS_VERT_TYPE_ENDPOINT )) - { - for (i = pVert->num_adj_edges - 1; 0 <= i; i--) - { - pEdge = pBNS->edge + pVert->iedge[i]; - vt = pEdge->neighbor12 ^ v; - if (pBNS->vert[vt].type & BNS_VERT_TYPE_TGROUP) - { - return !IS_FORBIDDEN( pEdge->forbidden, pBNS ); - } - } - } - - return 0; -} - - -#if ( BNS_RAD_SEARCH == 1 ) - - -/****************************************************************************/ -int bRadChangesAtomType( BN_STRUCT *pBNS, - BN_DATA *pBD, - Vertex v, - Vertex v_1, - Vertex v_2 ) -{ - - EdgeIndex iuv; - Vertex v_O, v_ChgOrH; - - /* The previous atom along the path: should be a terminal atom */ - if (v_1 == NO_VERTEX) - { - v_1 = GetPrevVertex( pBNS, v, pBD->SwitchEdge, &iuv ); - } - v_O = v_1 / 2 - 1; - - if (v_O < 0 || v_O >= pBNS->num_atoms) - { - return 0; - } - - /* Make sure v_O is a terminal atom: its second neighbor is not an atom */ - if (pBNS->vert[pBNS->edge[pBNS->vert[v_O].iedge[1]].neighbor12 ^ v_O].type & BNS_VERT_TYPE_ATOM) - { - return 0; - } - - /* The next to previous vertex vertex along the path: should be a Charge or Taut group vertex */ - if (v_2 == NO_VERTEX) - { - v_2 = GetPrevVertex( pBNS, v_1, pBD->SwitchEdge, &iuv ); - } - - v_ChgOrH = v_2 / 2 - 1; - if (v_ChgOrH < pBNS->num_atoms) - { - return 0; - } - - /* Make sure v_ChgOrH is a charge or taut_group */ - if (pBNS->vert[v_ChgOrH].type & ( BNS_VERT_TYPE_TGROUP | BNS_VERT_TYPE_C_GROUP )) - { - return 1; - } - - return 0; -} - - -/****************************************************************************/ -int RegisterRadEndpoint( BN_STRUCT *pBNS, BN_DATA *pBD, Vertex u ) -{ - EdgeIndex iuv; - int i, num_found; - Vertex v, w; - Vertex u_last, v2; - switch (pBD->bRadSrchMode) - { - case RAD_SRCH_NORM: - /* Go backwards along alt path and stop at the 1st found atom (not a fictitious vertex) */ - /* we need only vertices where a radical may be moved, therefore exclude u%2=1 (odd) vertices */ - /* atom number = u/2-1; u = 0 or 1 is 's' or 't' vertices, respectively, they are not atoms */ - num_found = 0; - while (u > Vertex_t && ( u % 2 || u / 2 > pBNS->num_atoms )) - { - u = GetPrevVertex( pBNS, u, pBD->SwitchEdge, &iuv ); - } - w = u / 2 - 1; /* Check whether u is a radical endpoint */ - if (Vertex_t < u && w < pBNS->num_atoms && - pBNS->vert[w].st_edge.cap == ( pBNS->vert[w].st_edge.flow & EDGE_FLOW_ST_MASK )) - { - /* u is an atom; it is not a radical atom */ - /* now search for the starting radical atom by following the path back from u */ - v = u_last = u; - while (v > Vertex_t) - { - u = v; - v = GetPrevVertex( pBNS, u, pBD->SwitchEdge, &iuv ); /* Radical endpoint */ - } - /* Check whether u is a radical atom */ - if (!( u % 2 ) && Vertex_t < u && - ( u = u / 2 - 1 ) < pBNS->num_atoms && - pBNS->vert[u].st_edge.cap > ( pBNS->vert[u].st_edge.flow & EDGE_FLOW_ST_MASK )) - { - /* at pBNS->vert[u] we have found the radical that originated the path */ - /* pBD->RadEndpoints[2k] is the radical, pBD->RadEndpoints[2k+1] is the farthest atom */ - /* to which the radical may be moved (farthest reachable atom) */ - - /* add *all* atoms that may receive radical from u_rad */ - /* exception: at2 in: ==(+/-/H)---at1==at2(possible rad endpoint) if pBNS->type_TACN */ - for (v = u_last; v > Vertex_t; v = GetPrevVertex( pBNS, v, pBD->SwitchEdge, &iuv )) - { - if (!( v % 2 ) && ( v2 = v / 2 - 1 ) < pBNS->num_atoms && - pBNS->vert[v2].st_edge.cap == ( pBNS->vert[v2].st_edge.flow & EDGE_FLOW_ST_MASK )) - { - /* Check exception */ - if (pBNS->type_TACN && - bRadChangesAtomType( pBNS, pBD, v, NO_VERTEX, NO_VERTEX )) - { - continue; - } - /* Add */ - for (i = 0; i < pBD->nNumRadEndpoints; i += 2) - { - /* Check whether this pair, (u,w), has already been saved */ - if (u == pBD->RadEndpoints[i] && - v2 == pBD->RadEndpoints[i + 1]) - { - break; - } - } - if (i >= pBD->nNumRadEndpoints) - { - /* Add new (u,w) pair */ - if (pBD->nNumRadEndpoints + 2 <= pBD->max_num_vertices) - { - /* add */ - pBD->RadEndpoints[pBD->nNumRadEndpoints++] = u; /* radical */ - pBD->RadEndpoints[pBD->nNumRadEndpoints++] = v2; /* endpoint */ - num_found++; - /*return 1;*/ /* registered */ - } - else - { - return BNS_VERT_EDGE_OVFL; - } - } - } - } - if (num_found) - { - return 1; - } - } - } - break; - - case RAD_SRCH_FROM_FICT: - /* Find the nearest atom accessible from a fictitious vertex */ - /* go backwards along alt path and stop at the 1st found atom (not a fictitious vertex) */ - - v = u; - w = NO_VERTEX; /* the nearest atom -- radical-endpoint */ - u = NO_VERTEX; /* fictitious vertex carrying a radical */ - - while (v > Vertex_t) - { - u = v; - if (!( v % 2 ) && v / 2 <= pBNS->num_atoms && - pBNS->vert[v / 2 - 1].st_edge.cap - pBNS->vert[v / 2 - 1].st_edge.flow < 2) - { - w = v; /* vertex w is atom that may be singlet or doublet but not triplet */ - } - v = GetPrevVertex( pBNS, u, pBD->SwitchEdge, &iuv ); - } - v = u / 2 - 1; /* vertex u may be the radical from which the path originated; w is the nearest atom */ - if (w == NO_VERTEX || u == NO_VERTEX || w % 2 || u == w || v < pBNS->num_atoms || - pBNS->vert[v].st_edge.cap == pBNS->vert[v].st_edge.flow || - ( w = w / 2 - 1 ) >= pBNS->num_atoms) - { - break; /* reject */ - } - u = v; - /* At pBNS->vert[u] we have found the radical that originated the path, w is the nearest atom */ - for (i = 0; i < pBD->nNumRadEndpoints; i += 2) - { - if (u == pBD->RadEndpoints[i] && - w == pBD->RadEndpoints[i + 1]) - { - break; /* this pair has already been stored */ - } - } - if (i >= pBD->nNumRadEndpoints) - { - /* A new pair has been found */ - if (pBD->nNumRadEndpoints + 2 <= pBD->max_num_vertices) - { - /* Add */ - pBD->RadEndpoints[pBD->nNumRadEndpoints++] = u; /* radical */ - pBD->RadEndpoints[pBD->nNumRadEndpoints++] = w; /* endpoint */ - return 1; /* registered */ - } - else - { - return BNS_VERT_EDGE_OVFL; - } - } - break; - } - - return 0; /* rejected */ -} - - -/****************************************************************************/ -int cmp_rad_endpoints( const void *a1, const void *a2 ) -{ - /* Vertex radical_vertex, radical_endpoint */ - const Vertex *p1 = (const Vertex *) a1; - const Vertex *p2 = (const Vertex *) a2; - - if (p1[0] < p2[0]) - { - return -1; - } - if (p1[0] > p2[0]) - { - return 1; - } - if (p1[1] < p2[1]) - { - return -1; - } - if (p1[1] > p2[1]) - { - return 1; - } - - return 0; -} - - -/****************************************************************************/ -int RemoveRadEndpoints( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at ) -{ - BNS_EDGE *e; - EdgeIndex ie; - BNS_VERTEX *p1, *p2; - Vertex v1, v2; - int i, delta, rad; - - for (i = pBD->nNumRadEdges - 1; 0 <= i; i--) - { - ie = pBD->RadEdges[i]; - if (ie < 0 || ie >= pBNS->num_edges) - { - goto error_exit; - } - e = pBNS->edge + ie; - v1 = e->neighbor1; - v2 = e->neighbor12 ^ v1; /* v2 > v1 <=> v2 was added later */ - if (ie + 1 != pBNS->num_edges || - v1 < 0 || v1 >= pBNS->num_vertices || - v2 < 0 || v2 >= pBNS->num_vertices) - { - goto error_exit; - } - p1 = pBNS->vert + v1; - p2 = pBNS->vert + v2; - - if (p2->iedge[p2->num_adj_edges - 1] != ie || - p1->iedge[p1->num_adj_edges - 1] != ie) - { - goto error_exit; - } - - p2->num_adj_edges--; - p1->num_adj_edges--; - p2->iedge[p2->num_adj_edges] = 0; - p1->iedge[p1->num_adj_edges] = 0; - p2->st_edge.flow -= e->flow; - p1->st_edge.flow -= e->flow; - - if (!p2->num_adj_edges && v2 >= pBNS->num_atoms) - { - if (v2 + 1 != pBNS->num_vertices) - { - goto error_exit; - } - memset( p2, 0, sizeof( *p2 ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - pBNS->num_vertices--; - } - - if (!p1->num_adj_edges && v1 >= pBNS->num_atoms) - { - if (v1 + 1 != pBNS->num_vertices) - { - goto error_exit; - } - memset( p1, 0, sizeof( *p1 ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - pBNS->num_vertices--; - } - - if (at && v1 < pBNS->num_atoms) - { - delta = p1->st_edge.cap - p1->st_edge.flow; - rad = at[v1].radical; - switch (delta) - { - case 0: - if (rad == RADICAL_DOUBLET) - { - rad = 0; - } - break; - case 1: - if (rad != RADICAL_DOUBLET) - { - rad = RADICAL_DOUBLET; - } - } - at[v1].radical = rad; - } - memset( e, 0, sizeof( *e ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - pBNS->num_edges--; - } - pBD->nNumRadEdges = 0; - pBD->nNumRadicals = 0; - pBD->bRadSrchMode = RAD_SRCH_NORM; - return 0; - -error_exit: - - return BNS_PROGRAM_ERR; -} - - -/****************************************************************************/ -int RestoreRadicalsOnly( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at ) -{ - BNS_EDGE *e; - EdgeIndex ie; - BNS_VERTEX *p1, *p2; - Vertex v1, v2; - int i, delta, rad; - int p1_num_adj_edges, p2_num_adj_edges; - - for (i = pBD->nNumRadEdges - 1; 0 <= i; i--) - { - ie = pBD->RadEdges[i]; - if (ie < 0 || ie >= pBNS->num_edges) - { - goto error_exit; - } - e = pBNS->edge + ie; - v1 = e->neighbor1; /* atom */ - v2 = e->neighbor12 ^ v1; /* v2 > v1 <=> v2 was added later */ - if (v1 < 0 || v1 >= pBNS->num_atoms || - v2 < pBNS->num_atoms || v2 >= pBNS->num_vertices) - { - goto error_exit; - } - p1 = pBNS->vert + v1; - p2 = pBNS->vert + v2; - - p1_num_adj_edges = e->neigh_ord[0]; - p2_num_adj_edges = e->neigh_ord[1]; - - if (p2->iedge[p2_num_adj_edges] != ie || - p1->iedge[p1_num_adj_edges] != ie) - { - goto error_exit; - } - - if (at && v1 < pBNS->num_atoms) - { - delta = p1->st_edge.cap - p1->st_edge.flow + e->flow; - rad = at[v1].radical; - switch (delta) - { - case 0: - if (rad == RADICAL_DOUBLET) - rad = 0; - break; - case 1: - if (rad != RADICAL_DOUBLET) - rad = RADICAL_DOUBLET; - } - at[v1].radical = rad; - } - } - return 0; - -error_exit: - - return BNS_PROGRAM_ERR; -} - - -/****************************************************************************/ -int SetRadEndpoints( BN_STRUCT *pBNS, BN_DATA *pBD, BRS_MODE bRadSrchMode ) -{ - int ret, i, j, k, delta; /* djb-rwth: removing redundant variables */ - BNS_VERTEX *pRad, *pEndp; - Vertex wRad, vRad, vEndp, nNumRadicals; - int nDots = 0 /* added initialization, 2006-03 */, nNumEdges; - - if (pBNS->tot_st_cap <= pBNS->tot_st_flow) - { - return 0; - } - - pBD->nNumRadEndpoints = 0; - pBD->nNumRadEdges = 0; - pBD->bRadSrchMode = bRadSrchMode; - pBNS->alt_path = pBNS->altp[0]; - pBNS->bChangeFlow = 0; - ret = BalancedNetworkSearch( pBNS, pBD, BNS_EF_RAD_SRCH ); - ReInitBnData( pBD ); - ReInitBnStructAltPaths( pBNS ); - if (!ret && pBD->nNumRadEndpoints >= 2) - { - /* Sort by radical locations */ - qsort( pBD->RadEndpoints, pBD->nNumRadEndpoints / 2, 2 * sizeof( pBD->RadEndpoints[0] ), cmp_rad_endpoints ); - /* djb-rwth: removing redundant code */ - nNumRadicals = 0; - - /* Create new vertices (type=BNS_VERT_TYPE_TEMP) and edges with flow=cap=1 */ - /* connecting the new vertices radical vertices */ - for (i = 0; i < pBD->nNumRadEndpoints; i = j) - { - wRad = pBD->RadEndpoints[i]; - pRad = pBNS->vert + wRad; - delta = pRad->st_edge.cap - ( pRad->st_edge.flow & EDGE_FLOW_ST_MASK ); - if (delta <= 0) - { - delta = 1; - } - nNumEdges = 0; - for (j = i; j < pBD->nNumRadEndpoints && wRad == pBD->RadEndpoints[j]; j += 2) - { - nNumEdges++; - } - /* Add new aux vertex to the radical atom/vertex */ - vRad = bAddNewVertex( pBNS, wRad, delta, delta, nNumEdges + 1, &nDots ); - if (IS_BNS_ERROR( vRad )) - { - ret = vRad; - goto error_exit; - } - pRad = pBNS->vert + vRad; - pBD->RadEdges[pBD->nNumRadEdges++] = pRad->iedge[pRad->num_adj_edges - 1]; - /* Replace references to vertex wRad with vRad */ - for (k = i, nNumEdges = 0; k < j; k += 2) /* djb-rwth: ignoring LLVM warning: variable used */ - { - pBD->RadEndpoints[k] = vRad; - } - nNumRadicals++; - } - /* All vRad vertex indices should be in the range vFirstNewVertex...vFirstNewVertex+nNumRadicals-1 */ - /* connect new vertices to the radical endpoints thus replacing radicals with even-length alternating cycles */ - for (i = 0; i < pBD->nNumRadEndpoints; i = j) - { - vRad = pBD->RadEndpoints[i]; - pRad = pBNS->vert + vRad; - for (j = i; j < pBD->nNumRadEndpoints && vRad == pBD->RadEndpoints[j]; j += 2) - { - /* Connect vew vertex pRad to radical endpoints */ - vEndp = pBD->RadEndpoints[j + 1]; - pEndp = pBNS->vert + vEndp; - ret = AddNewEdge( pRad, pEndp, pBNS, 1, 0 ); - if (IS_BNS_ERROR( ret )) - { - goto error_exit; - } - pBD->RadEdges[pBD->nNumRadEdges++] = ret; - } - } - pBD->nNumRadicals = nNumRadicals; - return nNumRadicals; /* done */ - } - - return 0; /* nothing to do */ - -error_exit: - RemoveRadEndpoints( pBNS, pBD, NULL ); - - return ret; -} - - -#define MAX_NUM_RAD 256 - - -/****************************************************************************/ -int SetRadEndpoints2( CANON_GLOBALS *pCG, - BN_STRUCT *pBNS, - BN_DATA *pBD, - BRS_MODE bRadSrchMode ) -{ - int ret = 0, i, j, k, n, delta = 1; /* djb-rwth: removing redundant variables */ - BNS_VERTEX *pRad, *pEndp; - Vertex wRad, vRad, vEndp, nNumRadicals; - Vertex vRadList[MAX_NUM_RAD], vRadEqul[MAX_NUM_RAD]; - int nNumRad = 0; - int edge_flow; - int nDots = 0 /* added initialization, 2006-03 */, nNumEdges; - NodeSet VertSet; - - if (pBNS->tot_st_cap <= pBNS->tot_st_flow) - { - return 0; - } - - /* Find all radicals: their vertices have st_cap-st_flow=delta */ - /* save radical atom numbers in vRadList[] and remove radical by making st_cap=st_flow */ - for (i = 0; i < pBNS->num_atoms; i++) - { - if (pBNS->vert[i].st_edge.cap - delta == ( pBNS->vert[i].st_edge.flow & EDGE_FLOW_ST_MASK )) - { - if (nNumRad < MAX_NUM_RAD) - { - pBNS->vert[i].st_edge.cap -= delta; - pBNS->tot_st_cap -= delta; - vRadList[nNumRad] = i; /* radical position; i > j <=> vRadList[i] > vRadList[j] */ - vRadEqul[nNumRad] = nNumRad; /* the smallest radical atom that has reachable - * atoms in common with this radical atom - * always keep vRadEqul[nNumRad] <= nNumRad */ - nNumRad++; - } - } - } - - if (pBNS->tot_st_cap - pBNS->tot_st_flow > nNumRad) - { - return BNS_CAP_FLOW_ERR; /* extra st_cap on non-atoms or program error */ - } - - memset( &VertSet, 0, sizeof( VertSet ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - - /* Find reachable atoms by enabling each radical separately */ - for (j = 0; j < nNumRad; j++) - { - i = vRadList[j]; - pBD->nNumRadEndpoints = 0; - pBD->nNumRadEdges = 0; - pBD->bRadSrchMode = bRadSrchMode; - pBNS->alt_path = pBNS->altp[0]; - pBNS->bChangeFlow = 0; - pBNS->vert[i].st_edge.cap += delta; /* enable single radical */ - pBNS->tot_st_cap += delta; - ret = BalancedNetworkSearch( pBNS, pBD, BNS_EF_RAD_SRCH ); /* find reachable atoms */ - ReInitBnData( pBD ); - ReInitBnStructAltPaths( pBNS ); - pBD->bRadSrchMode = RAD_SRCH_NORM; - pBNS->vert[i].st_edge.cap -= delta; /* disable single radical */ - pBNS->tot_st_cap -= delta; - if (IS_BNS_ERROR( ret )) - { - goto error_exit; - } - else - { - if (ret) - { - ret = BNS_RADICAL_ERR; /* found augmenting path: should not happen since only one radical was enabled */ - goto error_exit; - } - } - if (!ret && pBD->nNumRadEndpoints >= 2) - { - /* Sort by: primary_key=radical locations, secondary_key=radical endoint */ - - qsort( pBD->RadEndpoints, pBD->nNumRadEndpoints / 2, 2 * sizeof( pBD->RadEndpoints[0] ), cmp_rad_endpoints ); - - if (pBD->RadEndpoints[0] != i || pBD->RadEndpoints[pBD->nNumRadEndpoints - 2] != i) - { - ret = BNS_RADICAL_ERR; /* more than one radical vertex */ - goto error_exit; - } - if (nNumRad > 1) - { - /* If more than one radical then save reachable atoms in bitmaps to allow */ - /* faster finding whether same atoms are reachable by two or more radicals */ - /* Later merge such sets */ - if (NULL == VertSet.bitword) - { - SetBitCreate( pCG ); - if (!NodeSetCreate( pCG, &VertSet, pBNS->num_atoms, nNumRad )) - { - ret = BNS_OUT_OF_RAM; /* out of RAM */ - goto error_exit; - } - } - - NodeSetFromRadEndpoints( pCG, &VertSet, j, pBD->RadEndpoints, pBD->nNumRadEndpoints ); - - /* Do not allow any radical center be treated as a reachable atom: */ - - RemoveFromNodeSet( pCG, &VertSet, j, vRadList, nNumRad ); - } - } - } - - /* Restore radical st_cap so that st_cap-st_flow=delta */ - for (j = 0; j < nNumRad; j++) - { - i = vRadList[j]; - pBNS->vert[i].st_edge.cap += delta; - pBNS->tot_st_cap += delta; - } - - /* Merge lists that have common radical endpoints */ - /* defect: if vertex sets i and j do not intersect they will be compared 2 times */ - /* total up to nNumRad*(nNumRad-1)/2 calls to DoNodeSetsIntersect() */ - if (nNumRad > 1) - { - for (i = 0; i < nNumRad; i++) - { - if (vRadEqul[i] != i) - { - continue; - } - do - { - n = 0; - for (j = i + 1; j < nNumRad; j++) - { - if (vRadEqul[j] != j) - { - continue; - } - if (DoNodeSetsIntersect( &VertSet, i, j )) - { - AddNodeSet2ToNodeSet1( &VertSet, i, j ); - vRadEqul[j] = i; /* Set j was copied to set i; i < j */ - n++; - } - } - } while (n); - } - /* Fill out pBD->RadEndpoints[] */ - for (i = 0, n = 0; i < nNumRad; i++) - { - if (i == vRadEqul[i]) - { - if (!IsNodeSetEmpty( &VertSet, i )) - { - /* Store equivalent radicals */ - for (j = i + 1; j < nNumRad; j++) - { - if (i == vRadEqul[j]) - { - pBD->RadEndpoints[n++] = vRadList[i]; - pBD->RadEndpoints[n++] = -vRadList[j] - 2; /* equivalent radical, alvays not zero */ - } - } - /* Store endpoints */ - n = AddNodesToRadEndpoints( pCG, &VertSet, i, pBD->RadEndpoints, vRadList[i], n, pBD->max_len_Pu_Pv ); - if (n < 0) - { - ret = BNS_RADICAL_ERR; /* pBD->RadEndpoints overflow */ - goto error_exit; - } - } - else - { - pBD->RadEndpoints[n++] = vRadList[i]; - pBD->RadEndpoints[n++] = -1; /* immobile radical, only one edge to add */ - } - } - } - pBD->nNumRadEndpoints = n; - NodeSetFree( pCG, &VertSet ); - } - else - { - if (nNumRad == 1 && !pBD->nNumRadEndpoints) - { - /* 2006-07-30: a single radical; no possible endpoint found */ - for (i = 0, n = 0; i < nNumRad; i++) - { - pBD->RadEndpoints[n++] = vRadList[i]; - pBD->RadEndpoints[n++] = -1; /* immobile radical, only one edge to add */ - } - pBD->nNumRadEndpoints = n; - } - } - - if (!ret && pBD->nNumRadEndpoints >= 2) - { - /* Already sorted by radical locations */ - /* djb-rwth: removing redundant code */ - nNumRadicals = 0; - /************************************************************************** - * Create new vertices (type=BNS_VERT_TYPE_TEMP) and edges with flow=cap=1 - * connecting the new vertices radical vertices - * - * - * Original structure: atom A is a radical center A==B--C*--D==E - * A*--B==C--D==E atoms C and E are reachable: A==B--C===D--E* - * - * Resultant temporary structure: - * A---B==C--D==E - * || / / - * || / / The additional new vertex (*) and its - * || / / 3 edges replace the radical with alternating - * || / / circuits that allow same bond changes - * || / / as moving the radical to atoms C or E. - * ||// "Double bonds" here have edge cap=1, flow=1 - * (*) "Single bonds" have edge cap=1, flow=0 - * - * The "equivalent radical centers" (which have at least one reachable atom - * in common) are connected to (*) with "double bonds" (edge cap=1, flow=1). - * Reachable non-radical atoms are connected by edges with cap=1, flow=0 - * After running BNS to find alt.path a "double bond" from (*) may move - * to another atom thus muving the radical. - * - * Number of additional (*) vertices = number of sets of - * "equivalent radical centers". - * Each such a set may include one or more radical centers. - * - * The radicals will be re-created in RemoveRadEndpoints() - ***************************************************************************/ - for (i = 0; i < pBD->nNumRadEndpoints; i = j) - { - wRad = pBD->RadEndpoints[i]; - pRad = pBNS->vert + wRad; - delta = pRad->st_edge.cap - ( pRad->st_edge.flow & EDGE_FLOW_ST_MASK ); - if (delta <= 0) - { - delta = 1; - } - nNumEdges = 0; - for (j = i; j < pBD->nNumRadEndpoints && wRad == pBD->RadEndpoints[j]; j += 2) - { - nNumEdges += ( pBD->RadEndpoints[j + 1] != -1 ); /* immobile radicals have one edge only */ - } - /* Add new aux vertex to the radical atom/vertex making st_cap-st_flow=0 */ - /* in case of immobile radical there will be no additional eddges since nNumEdges=0 */ - vRad = bAddNewVertex( pBNS, wRad, delta, delta, nNumEdges + 1, &nDots ); - if (IS_BNS_ERROR( vRad )) - { - ret = vRad; - goto error_exit; - } - pRad = pBNS->vert + vRad; - pBD->RadEdges[pBD->nNumRadEdges++] = pRad->iedge[pRad->num_adj_edges - 1]; - /* replace references to vertex wRad with vRad */ - for (k = i, nNumEdges = 0; k < j; k += 2) /* djb-rwth: ignoring LLVM warning: variable used */ - { - pBD->RadEndpoints[k] = vRad; - } - nNumRadicals++; - } - /* All vRad vertex indices should be in the range vFirstNewVertex...vFirstNewVertex+nNumRadicals-1 */ - /* connect new vertices to the radical endpoints thus replacing radicals with even-length alternating cycles */ - for (i = 0; i < pBD->nNumRadEndpoints; i = j) - { - vRad = pBD->RadEndpoints[i]; - pRad = pBNS->vert + vRad; - for (j = i; j < pBD->nNumRadEndpoints && vRad == pBD->RadEndpoints[j]; j += 2) - { - /* connect vew vertex pRad to radical endpoints */ - vEndp = pBD->RadEndpoints[j + 1]; - if (vEndp == -1) - continue; - if (vEndp < 0) - { - edge_flow = 1; - vEndp = -vEndp - 2; /* equivalent radical centers */ - } - else - { - edge_flow = 0; - } - pEndp = pBNS->vert + vEndp; - ret = AddNewEdge( pRad, pEndp, pBNS, 1, edge_flow ); - if (IS_BNS_ERROR( ret )) - { - goto error_exit; - } - pBD->RadEdges[pBD->nNumRadEdges++] = ret; - } - } - pBD->nNumRadicals = nNumRadicals; - return nNumRadicals; /* done */ - } - return 0; /* nothing to do */ - -error_exit: - RemoveRadEndpoints( pBNS, pBD, NULL ); - NodeSetFree( pCG, &VertSet ); - - return ret; -} - - -#else -/****************************************************************************/ -int SetRadEndpoints( BN_STRUCT *pBNS, BN_DATA *pBD, BRS_MODE bRadSrchMode ) -{ - return 0; -} -int RemoveRadEndpoints( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at ) -{ - return 0; -} -int SetRadEndpoints2( CANON_GLOBALS *pCG, BN_STRUCT *pBNS, BN_DATA *pBD, BRS_MODE bRadSrchMode ) -{ - return 0; -} -#endif - - -/**************************************************************************** -bExistsAltPath( ... ) - -Return value ret bits if not IS_BNS_ERROR(ret): - -ret & 1 => Success -ret & 2 => Bonds changed to Alt -(ret & ~3) >> 2 => nDelta: number of removed dots -****************************************************************************/ -int bExistsAltPath( CANON_GLOBALS *pCG, - BN_STRUCT *pBNS, - BN_DATA *pBD, - BN_AATG *pAATG, - inp_ATOM *at, - int num_atoms, - int nVertDoubleBond, - int nVertSingleBond, - int path_type ) -{ - ALT_PATH_CHANGES apc; - int ret, ret_val, bError, bSuccess, bChangeFlow = 0, nDots, nDelta, bDoMarkChangedBonds = 1; - int bAdjustRadicals = 0; - AT_NUMB type; - BNS_FLOW_CHANGES fcd[4 * BNS_MAX_NUM_FLOW_CHANGES + 1]; - ENDPOINT_INFO eif; -#if ( KETO_ENOL_TAUT == 1 ) - ENDPOINT_INFO eif2; -#endif - - /* Initialize */ - switch (path_type) - { - case ALT_PATH_MODE_TAUTOM: - /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = BNS_EF_CHNG_RSTR; - if (!at[nVertSingleBond].endpoint && - ( !nGetEndpointInfo( at, nVertSingleBond, &eif ) || !eif.cDonor )) - { - return 0; - } - if (!at[nVertDoubleBond].endpoint && - ( !nGetEndpointInfo( at, nVertDoubleBond, &eif ) || !eif.cAcceptor )) - { - return 0; - } - break; - -#if ( TAUT_PT_22_00 == 1 ) - case ALT_PATH_MODE_TAUTOM_PT_22_00: - /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = BNS_EF_CHNG_RSTR; - if (!at[nVertSingleBond].endpoint && - (!nGetEndpointInfo_PT_22_00(at, nVertSingleBond, &eif) || !eif.cDonor)) - return 0; - if (!at[nVertDoubleBond].endpoint && - (!nGetEndpointInfo_PT_22_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) - return 0; - break; -#endif - -#if ( TAUT_PT_16_00 == 1 ) - case ALT_PATH_MODE_TAUTOM_PT_16_00: - /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = BNS_EF_CHNG_RSTR; - if (!at[nVertSingleBond].endpoint && - (!nGetEndpointInfo_PT_16_00(at, nVertSingleBond, &eif) || !eif.cDonor)) - return 0; - if (!at[nVertDoubleBond].endpoint && - (!nGetEndpointInfo_PT_16_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) - return 0; - break; -#endif - -#if ( TAUT_PT_06_00 == 1 ) - case ALT_PATH_MODE_TAUTOM_PT_06_00: - /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = BNS_EF_CHNG_RSTR; - if (!at[nVertSingleBond].endpoint && - (!nGetEndpointInfo_PT_06_00(at, nVertSingleBond, &eif) || !eif.cDonor)) - return 0; - if (!at[nVertDoubleBond].endpoint && - (!nGetEndpointInfo_PT_06_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) - return 0; - break; -#endif - -#if ( TAUT_PT_39_00 == 1 ) - case ALT_PATH_MODE_TAUTOM_PT_39_00: - /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = BNS_EF_CHNG_RSTR; - if (!at[nVertSingleBond].endpoint && - (!nGetEndpointInfo_PT_39_00(at, nVertSingleBond, &eif) || !eif.cDonor)) - return 0; - if (!at[nVertDoubleBond].endpoint && - (!nGetEndpointInfo_PT_39_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) - return 0; - break; -#endif - -#if ( TAUT_PT_13_00 == 1 ) - case ALT_PATH_MODE_TAUTOM_PT_13_00: - /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = BNS_EF_CHNG_RSTR; - if (!at[nVertSingleBond].endpoint && - (!nGetEndpointInfo_PT_13_00(at, nVertSingleBond, &eif) || !eif.cDonor)) - return 0; - if (!at[nVertDoubleBond].endpoint && - (!nGetEndpointInfo_PT_13_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) - return 0; - break; -#endif - -#if ( TAUT_PT_18_00 == 1 ) - case ALT_PATH_MODE_TAUTOM_PT_18_00: - /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = BNS_EF_CHNG_RSTR; - if (!at[nVertSingleBond].endpoint && - (!nGetEndpointInfo_PT_18_00(at, nVertSingleBond, &eif) || !eif.cDonor)) - return 0; - if (!at[nVertDoubleBond].endpoint && - (!nGetEndpointInfo_PT_18_00(at, nVertDoubleBond, &eif) || !eif.cAcceptor)) - return 0; - break; -#endif - - -#if ( KETO_ENOL_TAUT == 1 ) - case ALT_PATH_MODE_TAUTOM_KET: - /* Check for alt path allowing to move H and (-). Purpose: confirm possible tautomerism */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = BNS_EF_CHNG_RSTR; - - if (!at[nVertSingleBond].endpoint && - ( !nGetEndpointInfo_KET( at, nVertSingleBond, &eif ) || !eif.cDonor )) - { - return 0; - } - if (!at[nVertDoubleBond].endpoint && - ( !nGetEndpointInfo_KET( at, nVertDoubleBond, &eif2 ) || !eif2.cAcceptor )) - { - return 0; - } - /* - if ( eif.cKetoEnolCode + eif2.cKetoEnolCode != 3 ) - return 0; - */ - break; - -#endif - case ALT_PATH_MODE_CHARGE: - /* Find alt path allowing to move (+). Purpose: establish "charge groups", - mark alt. bonds due to (+) charge movement */ - type = BNS_VERT_TYPE_C_POINT; - bChangeFlow = ( BNS_EF_CHNG_RSTR | BNS_EF_ALTR_BONDS ); - break; - - case ALT_PATH_MODE_4_SALT: - case ALT_PATH_MODE_4_SALT2: - /* Find alt paths allowing to move (-) and H between "acidic oxygen atoms". - Purpose: mark alt bonds due to this "long range" tautomerism. */ - type = BNS_VERT_TYPE_ENDPOINT; - bChangeFlow = ( BNS_EF_CHNG_RSTR | BNS_EF_ALTR_BONDS ); - if (!bIsBnsEndpoint( pBNS, nVertSingleBond ) /* !at[nVertSingleBond].endpoint*/ && - ( !nGetEndpointInfo( at, nVertSingleBond, &eif ) || !eif.cDonor )) - { - return 0; - } - if (!bIsBnsEndpoint( pBNS, nVertDoubleBond ) /* !at[nVertDoubleBond].endpoint*/ && - ( !nGetEndpointInfo( at, nVertDoubleBond, &eif ) || !eif.cAcceptor )) - { - return 0; - } - memset( &apc, 0, sizeof( apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - break; - - case ALT_PATH_MODE_REM2H_CHG: - bChangeFlow |= BNS_EF_ALTR_BONDS; /* fall through */ - case ALT_PATH_MODE_REM2H_TST: - bChangeFlow |= BNS_EF_CHNG_RSTR; - type = BNS_VERT_TYPE_ENDPOINT; - /* Allow non-tautomeric donors or any tautomeric atom */ - if (!bIsBnsEndpoint( pBNS, nVertSingleBond ) /* not linked to a t-group or the edge forbidden */ && - ( !nGetEndpointInfo( at, nVertSingleBond, &eif ) || !eif.cDonor )) /* not a donor */ - { - return 0; - } - if (!bIsBnsEndpoint( pBNS, nVertDoubleBond ) /* not connected to a t-group */ && - ( !nGetEndpointInfo( at, nVertDoubleBond, &eif ) || !eif.cDonor )) - { - return 0; - } - memset( &apc, 0, sizeof( apc ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - break; - - case ALT_PATH_MODE_ADD2H_CHG: - bChangeFlow |= BNS_EF_ALTR_BONDS; /* fall through */ - case ALT_PATH_MODE_ADD2H_TST: - bChangeFlow |= BNS_EF_CHNG_RSTR; - type = BNS_VERT_TYPE_ENDPOINT; - /* Allow non-tautomeric acceptors or any tautomeric atom */ - if (!bIsBnsEndpoint( pBNS, nVertSingleBond ) /* !at[nVertSingleBond].endpoint*/ && - ( !nGetEndpointInfo( at, nVertSingleBond, &eif ) || !eif.cAcceptor )) - { - return 0; - } - if (!bIsBnsEndpoint( pBNS, nVertDoubleBond ) /* !at[nVertSingleBond].endpoint*/ && - ( !nGetEndpointInfo( at, nVertDoubleBond, &eif ) || !eif.cAcceptor )) - { - return 0; - } - break; - - case ALT_PATH_MODE_REM_PROTON: - /* alt path is between the t-group (nVertDoubleBond) and - the (+)-charge group (nVertSingleBond) */ - type = 0; - /*bDoMarkChangedBonds = 0;*/ - bChangeFlow = ( BNS_EF_SAVE_ALL | BNS_EF_UPD_H_CHARGE ) | BNS_EF_ALTR_NS; /* added BNS_EF_ALTR_NS: set non-stereo altern non-ring bonds 2004-07-02*/ - break; - default: - type = 0; - bChangeFlow = BNS_EF_CHNG_RSTR; - break; - } - - bError = 0; - bSuccess = 0; - nDelta = 0; - - ret = SetRadEndpoints2( pCG, pBNS, pBD, RAD_SRCH_NORM ); - if (IS_BNS_ERROR( ret )) - { - return ret; - } - - /* Set BNS to check alt path */ - ret = bSetBnsToCheckAltPath( pBNS, nVertDoubleBond, nVertSingleBond, type, path_type, &apc, fcd, &nDots ); - switch (ret) - { - case BNS_CHK_ALTP_NO_ALTPATH: - ret = RemoveRadEndpoints( pBNS, pBD, NULL ); - return ret; - case BNS_CHK_ALTP_SAME_TGROUP: - bSuccess = 1; - goto reinit_BNS; - case BNS_CHK_ALTP_SAME_VERTEX: - ret = RemoveRadEndpoints( pBNS, pBD, NULL ); - return ret ? ret : 1; /* very strange ... set a breakpoint here */ - case BNS_CHK_ALTP_SET_SUCCESS: - break; /* actually check the existence of the altpath */ - case BNS_CANT_SET_BOND: - goto reinit_BNS; - default: - ret_val = RemoveRadEndpoints( pBNS, pBD, NULL ); /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - if (IS_BNS_ERROR( ret )) - { - return ret; - } - return BNS_PROGRAM_ERR; - } - - bAdjustRadicals = ( ( bChangeFlow & BNS_EF_UPD_RAD_ORI ) && !( bChangeFlow & BNS_EF_RSTR_FLOW ) ); - - /***************************************************************** - * nDots = 2 for ALT_PATH_CHARGE (checking moveable positive charges) - * Now nDots for ALT_PATH_TAUTOM or ALT_PATH_4_SALT can be greater - * because some of the bonds are effectively removed and dots - * (vertex st-caps) may be added - * -- to make sure there is no (+) charge on a tautomeric endpoint - * -- to fix positions of moveable tautomeric attachements - * (H and (-)-charges) at the ends of an alt path - */ - - /* Run BNS */ - - ret = RunBalancedNetworkSearch( pBNS, pBD, bChangeFlow ); - - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - else if (ret > 0) - { - if (2 * ret >= nDots) - { - nDelta = 2 * ret - nDots; /* non-zero means augmentation created another alt. path -- between radicals */ - if (pAATG && pAATG->nMarkedAtom) - { - if (pAATG->nAtTypeTotals && ( bChangeFlow & BNS_EF_UPD_H_CHARGE )) - { - memset( pAATG->nMarkedAtom, 0, num_atoms * sizeof( pAATG->nMarkedAtom[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - /* Mark atoms that have charge or H changed, check their input types (that is, before changes), - and subtract their input charge/H from nAtTypeTotals */ - SubtractOrChangeAtHChargeBNS( pBNS, at, num_atoms, pAATG->nAtTypeTotals, pAATG->nMarkedAtom, NULL, 1 ); - /* ZChange charges and/or H, update t_group_info, do not check types or change nAtTypeTotals */ - /* Atom types will be checked and nAtTypeTotals will be changed in - AddChangedAtHChargeBNS() later */ - SubtractOrChangeAtHChargeBNS( pBNS, at, num_atoms, NULL, NULL, pAATG->t_group_info, 0 ); - } - else - { - if (!pAATG->nAtTypeTotals) - { - bDoMarkChangedBonds = MarkAtomsAtTautGroups( pBNS, num_atoms, pAATG, nVertSingleBond, nVertDoubleBond ); - if (bDoMarkChangedBonds < 0) - { - bError = bDoMarkChangedBonds; - bDoMarkChangedBonds = 0; - } - } - } - } - if (bDoMarkChangedBonds) - { - /* Mark bonds that were changed to configure bond testing */ - ret_val = bSetBondsAfterCheckOneBond( pBNS, fcd, -1, at, num_atoms, bChangeFlow ); - if (IS_BNS_ERROR( ret_val )) - { - bError = ret_val; - } - /*ret = SetBondsRestoreBnStructFlow( pBNS, at, num_atoms, bChangeFlow );*/ - /* mark all other changed bonds */ - ret = SetBondsFromBnStructFlow( pBNS, at, num_atoms, bChangeFlow ); - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - else - { - if (!( ret & 1 ) && !( ret_val & 1 )) - { - bSuccess = 1; - } - else - { - if ((( ( ret & 1 ) || ( ret_val & 1 ) ) && - ( bChangeFlow & BNS_EF_ALTR_BONDS )) || ( bChangeFlow & BNS_EF_UPD_H_CHARGE )) /* djb-rwth: addressing LLVM warning */ - { - /* Some bonds have been changed to alternating */ - bSuccess = 3; - } - else - { - bError = BNS_BOND_ERR; - } - } - } - if (!bError && pAATG && pAATG->nMarkedAtom && ( bChangeFlow & BNS_EF_UPD_H_CHARGE )) - { - /* Update radicals to avoid errors in atom type check in AddChangedAtHChargeBNS() */ - if (bAdjustRadicals) - { - ret_val = RestoreRadicalsOnly( pBNS, pBD, at ); - if (IS_BNS_ERROR( ret_val )) - { - bError = ret_val; - } - } - /* Check atom types of marked atoms and add charge/H changes to nAtTypeTotals */ - /* Changing atoms were marked in the 1st call to SubtractOrChangeAtHChargeBNS(..., 1) above */ - AddChangedAtHChargeBNS( at, num_atoms, pAATG->nAtTypeTotals, pAATG->nMarkedAtom ); - if (bChangeFlow & BNS_EF_CHNG_FLOW) - { - /* Eliminate ambiguities in already changed flow: - replace (+)--N==(-) with (+)==N--(-) (both represent neutral N) */ - EliminatePlusMinusChargeAmbiguity( pBNS, num_atoms ); - } - } - } - } - - ret = RestoreBnStructFlow( pBNS, bChangeFlow & BNS_EF_CHNG_RSTR ); - - if (IS_BNS_ERROR( ret )) - { - bError = ret; - } - } - -reinit_BNS: - - /* --- Reinitialize to repeat the calculations --- */ - bRestoreBnsAfterCheckAltPath( pBNS, &apc, bChangeFlow & BNS_EF_UPD_H_CHARGE ); - bRestoreFlowAfterCheckOneBond( pBNS, fcd ); - ret_val = RemoveRadEndpoints( pBNS, pBD, bAdjustRadicals ? at : NULL ); - ReInitBnStructAltPaths( pBNS ); - - return bError ? bError : ret_val ? ret_val : ( bSuccess + 4 * nDelta ); -} - - -/****************************************************************************/ -BN_STRUCT* AllocateAndInitBnStruct( inp_ATOM *at, - int num_atoms, - int nMaxAddAtoms, - int nMaxAddEdges, - int max_altp, - int *pNum_changed_bonds ) -{ - BN_STRUCT *pBNS = NULL; - BNS_VERTEX *vert; - - int neigh, num_changed_bonds = 0; - U_CHAR bond_type, bond_mark; - - int i, j, k, n_edges, num_bonds, num_edges, f1, f2, edge_cap, edge_flow, st_flow; /* djb-rwth: removing redundant variables */ - int tot_st_cap, tot_st_flow; - int max_tg, max_edges, max_vertices, len_alt_path, max_iedges, num_altp; -#if ( BNS_RAD_SEARCH == 1 ) - int num_rad = 0; - - nMaxAddEdges += 1; -#endif -#if ( FIX_NUM_TG == 1 ) - max_tg = inchi_max( num_atoms / 2, 5 ); -#else - max_tg = num_atoms; -#endif - num_changed_bonds = 0; - - for (i = 0, num_bonds = 0; i < num_atoms; i++) - { - /*(@nnuk : Nauman Ullah Khan) */ - LOG_NO_ARGS("\n################# (L8916:ichi_bns.c) ###################\n"); - LOG_MULT_ARGS("Number of changed bonds (Start): %d\n", num_changed_bonds); - LOG_NO_ARGS("\n########################################################\n"); - - num_bonds += at[i].valence; -#if ( BNS_RAD_SEARCH == 1 ) - num_rad += ( at[i].radical == RADICAL_DOUBLET ); -#endif - } - /* Each atom has enough edges to belong to a tautomeric group + nMaxAddEdges */ - /* number of atoms is large enough to accommodate max. possible number of t-groups + nMaxAddAtoms */ - /* max_altp cannot be larger than BN_MAX_ALTP = 16 */ - num_edges = ( num_bonds /= 2 ); - /* +1 for a super-tautomeric group */ - max_vertices = num_atoms + nMaxAddAtoms + max_tg + 1; - /* +max_tg for edges between t-groups and super-tautomeric group */ - max_edges = num_edges + ( nMaxAddEdges + NUM_KINDS_OF_GROUPS )*max_vertices + max_tg; -#if ( BNS_RAD_SEARCH == 1 ) - if (num_rad) - { - max_vertices *= 2; - max_edges *= 2; - } -#endif - max_iedges = 2 * max_edges; - len_alt_path = max_vertices + iALTP_HDR_LEN + 1; /* may overflow if an edge is traversed in 2 directions */ - - if (!( pBNS = (BN_STRUCT *) inchi_calloc( 1, sizeof( BN_STRUCT ) ) ) || - !( pBNS->edge = (BNS_EDGE *) inchi_calloc( max_edges, sizeof( BNS_EDGE ) ) ) || - !( pBNS->vert = (BNS_VERTEX *) inchi_calloc( max_vertices, sizeof( BNS_VERTEX ) ) ) || - !( pBNS->iedge = (BNS_IEDGE *) inchi_calloc( max_iedges, sizeof( BNS_IEDGE ) ) )) - { - return DeAllocateBnStruct( pBNS ); - } - /* Alt path init */ - for (num_altp = 0; num_altp < max_altp && num_altp < BN_MAX_ALTP; num_altp++) - { - if (!( pBNS->altp[num_altp] = (BNS_ALT_PATH*) inchi_calloc( len_alt_path, sizeof( BNS_ALT_PATH ) ) )) - { - return DeAllocateBnStruct( pBNS ); - } - ALTP_ALLOCATED_LEN( pBNS->altp[num_altp] ) = len_alt_path; - pBNS->len_alt_path = len_alt_path; /* ??? duplication ??? */ - /* re-init */ - ALTP_DELTA( pBNS->altp[num_altp] ) = 0; - ALTP_START_ATOM( pBNS->altp[num_altp] ) = NO_VERTEX; - ALTP_END_ATOM( pBNS->altp[num_altp] ) = NO_VERTEX; - ALTP_PATH_LEN( pBNS->altp[num_altp] ) = 0; - } - pBNS->alt_path = NULL; - pBNS->num_altp = 0; - pBNS->max_altp = num_altp; - - /* Fill vertices (no connectivity) */ - pBNS->vert[0].iedge = pBNS->iedge; - for (i = 0; i < num_atoms; i++) - { - k = pBNS->vert[i].max_adj_edges = at[i].valence + ( nMaxAddEdges + NUM_KINDS_OF_GROUPS ); - pBNS->vert[i + 1].iedge = pBNS->vert[i].iedge + k; - } - pBNS->num_atoms = num_atoms; /* number of real atoms */ - pBNS->num_added_atoms = 0; - pBNS->num_t_groups = 0; /* number of added t-groups */ - pBNS->num_c_groups = 0; - pBNS->nMaxAddAtoms = nMaxAddAtoms; - pBNS->nMaxAddEdges = nMaxAddEdges; - - pBNS->num_vertices = num_atoms; /* current number of vertices, a sum of - pBNS->num_atoms - pBNS->num_t_groups - pBNS->num_added_atoms */ - pBNS->max_vertices = max_vertices; - - - pBNS->num_bonds = num_bonds; /* number of real edges (bonds) */ - pBNS->max_edges = max_edges; - pBNS->max_iedges = max_iedges; - - /* - To remove t-groups and added atoms: - In atoms i = 0..pBNS->num_atoms-1 - pBNS->vert[i].num_adj_edges = pBNS->vert[i].max_adj_edges - pBNS->nMaxAddEdges - NUM_KINDS_OF_GROUPS; - pBNS->num_vertices = pBNS->num_atoms; - pBNS->num_edges = pBNS->num_bonds; - pBNS->num_added_atoms = 0; - pBNS->num_t_groups = 0; - pBNS->num_added_edges = 0; - - ALTP_DELTA(pBNS->alt_path) = 0; - ALTP_START_ATOM(pBNS->alt_path) = NO_VERTEX; - ALTP_END_ATOM(pBNS->alt_path) = NO_VERTEX; - ALTP_PATH_LEN(pBNS->alt_path) = 0; - */ - - /* Fill edges and connectivity */ - tot_st_cap = tot_st_flow = 0; - for (i = 0, n_edges = 0; i < num_atoms; i++) - { - vert = &pBNS->vert[i]; - /* djb-rwth: removing redundant code */ - st_flow = 0; - /* djb-rwth: removing redundant code */ - for (j = 0; j < at[i].valence; j++) - { - neigh = at[i].neighbor[j]; - /* find this bond at the neighbor */ - for (k = 0; k < at[neigh].valence; k++) - { - if (at[neigh].neighbor[k] == i) - { - break; - } - } - bond_type = ( at[i].bond_type[j] & BOND_TYPE_MASK ); - bond_mark = ( at[i].bond_type[j] & ~BOND_TYPE_MASK ); - if (bond_type != BOND_SINGLE && bond_type != BOND_DOUBLE && - bond_type != BOND_TRIPLE /*&& bond_type != BOND_ALTERN*/) - { - /* Make Unknown or Alternating bonds single */ - bond_type = 1; - at[i].bond_type[j] = bond_mark | bond_type; - num_changed_bonds++; - } - if (neigh > i) - { - /* This is the first time we encounter this bond */ - f1 = MAX_AT_FLOW( at[i] ); - f2 = MAX_AT_FLOW( at[neigh] ); - edge_flow = bond_type - 1; - if (edge_flow > MAX_BOND_EDGE_CAP) - { - /* djb-rwth: removing redundant code */ - edge_flow = 0; /* BNS will determine flows (that is, bonds) */ - edge_cap = AROM_BOND_EDGE_CAP; - } - else - { -#if ( 0 && KETO_ENOL_TAUT == 1 ) /* ????? */ - edge_cap = inchi_max( f1, f2 ); -#else - edge_cap = inchi_min( f1, f2 ); -#endif - edge_cap = inchi_min( edge_cap, MAX_BOND_EDGE_CAP ); /* max capacity = 2 means up to triple bond */ - } - - pBNS->edge[n_edges].neighbor1 = (AT_NUMB) i; - pBNS->edge[n_edges].neighbor12 = (AT_NUMB) ( i ^ neigh ); - pBNS->edge[n_edges].flow = pBNS->edge[n_edges].flow0 = edge_flow; - pBNS->edge[n_edges].cap = pBNS->edge[n_edges].cap0 = edge_cap; - pBNS->edge[n_edges].neigh_ord[0] = j; - pBNS->edge[n_edges].neigh_ord[1] = k; - pBNS->edge[n_edges].pass = 0; - pBNS->edge[n_edges].forbidden = 0; - - vert->iedge[j] = pBNS->vert[neigh].iedge[k] = n_edges++; - } - else - { - /* This is the second time we encounter this bond. It was stored at */ - int iedge = pBNS->vert[neigh].iedge[k]; - edge_cap = pBNS->edge[iedge].cap; /* djb-rwth: ignoring LLVM warning: variable used */ - edge_flow = pBNS->edge[iedge].flow; - } - st_flow += edge_flow; - /* djb-rwth: removing redundant code */ - } - vert->num_adj_edges = j; - vert->st_edge.cap = - vert->st_edge.cap0 = MAX_AT_FLOW( at[i] ); - vert->st_edge.flow = - vert->st_edge.flow0 = st_flow; - vert->type = BNS_VERT_TYPE_ATOM; - tot_st_cap += vert->st_edge.cap; - tot_st_flow += vert->st_edge.flow; - } - *pNum_changed_bonds = num_changed_bonds / 2; - - pBNS->num_edges = n_edges; /* number of edges */ - pBNS->num_added_edges = 0; - - /*(@nnuk : Nauman Ullah Khan) */ - LOG_NO_ARGS("\n################# (L9108:ichi_bns.c) ################\n"); - for (i = 0, num_bonds = 0; i < num_atoms; i++) { - - LOG_MULT_ARGS("Element : %s, Number of changed bonds (End): %d\n", at[i].elname, *pNum_changed_bonds); - } - LOG_NO_ARGS("\n#####################################################\n"); - - pBNS->tot_st_cap = tot_st_cap; - pBNS->tot_st_flow = tot_st_flow; - - return pBNS; -} - - -/****************************************************************************/ -BN_STRUCT* DeAllocateBnStruct( BN_STRUCT *pBNS ) -{ - int i; - if (pBNS) - { - if (pBNS->edge) - { - inchi_free( pBNS->edge ); - } - for (i = 0; i < pBNS->max_altp && i < BN_MAX_ALTP; i++) - { - if (pBNS->altp[i]) - { - inchi_free( pBNS->altp[i] ); - } - } - if (pBNS->vert) - { - if (pBNS->vert[0].iedge) - { - inchi_free( pBNS->vert[0].iedge ); - } - inchi_free( pBNS->vert ); - } - inchi_free( pBNS ); - } - - return NULL; -} - - -/****************************************************************************/ -int ReInitBnStructAltPaths( BN_STRUCT *pBNS ) -{ - int i; - for (i = 0; i < pBNS->max_altp && i < BN_MAX_ALTP; i++) - { - if (pBNS->altp[i]) - { - ALTP_DELTA( pBNS->altp[i] ) = 0; - ALTP_PATH_LEN( pBNS->altp[i] ) = 0; - ALTP_START_ATOM( pBNS->altp[i] ) = NO_VERTEX; - ALTP_END_ATOM( pBNS->altp[i] ) = NO_VERTEX; - } - } - pBNS->alt_path = NULL; - pBNS->num_altp = 0; - return i; -} - - -/****************************************************************************/ -int ReInitBnStructAddGroups( CANON_GLOBALS *pCG, - BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - T_GROUP_INFO *tgi, - C_GROUP_INFO *cgi ) -{ - int ret; - /* strip all t-groups and c-groups */ - ret = ReInitBnStruct( pBNS, at, num_atoms, 0 ); - if (ret) - { - ret = BNS_REINIT_ERR; - goto exit_function; - } - /*#if ( MOVE_CHARGES == 1 )*/ - if (*pBNS->pbTautFlags & TG_FLAG_MOVE_POS_CHARGES) - { - /* Add c-groups */ - ret = AddCGroups2BnStruct( pCG, pBNS, at, num_atoms, cgi ); - if (IS_BNS_ERROR( ret )) - { - goto exit_function; - } - } - /*#endif*/ - /* Add t-groups */ - ret = AddTGroups2BnStruct( pCG, pBNS, at, num_atoms, tgi ); - if (IS_BNS_ERROR( ret )) - { - goto exit_function; - } - -exit_function: - - return ret; -} - - -/****************************************************************************/ -int ReInitBnStruct( BN_STRUCT *pBNS, - inp_ATOM *at, - int num_at, - int bRemoveGroupsFromAtoms ) -{ - int i, vfict, kfict, iedgefict, endpoint, centerpoint, iedge, k; - int ret = 0; - if (pBNS) - { - if (pBNS->vert && pBNS->edge) - { - /* Debug */ - for (k = 0, i = 0; k < pBNS->num_edges; k++) - { - if (pBNS->edge[k].pass) - { - i++; - } - } - ret += i * 100; - /* Restore flow and cap on edges to vertices connected to fictitious atoms */ - for (vfict = pBNS->num_atoms; vfict < pBNS->num_vertices; vfict++) - { - for (kfict = 0; kfict < pBNS->vert[vfict].num_adj_edges; kfict++) - { - iedgefict = pBNS->vert[vfict].iedge[kfict]; /* fictitious edge to the endpoint */ - endpoint = pBNS->edge[iedgefict].neighbor12 ^ vfict; /* the endpoint */ - /* To simlify restore cap and flow in ALL edges to the endpoint */ - if (bRemoveGroupsFromAtoms && endpoint < num_at) - { - at[endpoint].c_point = 0; - at[endpoint].endpoint = 0; - } - for (k = 0; k < pBNS->vert[endpoint].num_adj_edges; k++) - { - iedge = pBNS->vert[endpoint].iedge[k]; /* edge to endpoint */ - centerpoint = pBNS->edge[iedge].neighbor12 ^ endpoint; - pBNS->edge[iedge].cap = pBNS->edge[iedge].cap0; - pBNS->edge[iedge].flow = pBNS->edge[iedge].flow0; - pBNS->edge[iedge].pass = 0; -#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) - pBNS->edge[iedge].forbidden &= pBNS->edge_forbidden_mask; -#endif - pBNS->vert[centerpoint].st_edge.cap = pBNS->vert[centerpoint].st_edge.cap0; - pBNS->vert[centerpoint].st_edge.flow = pBNS->vert[centerpoint].st_edge.flow0; - } - pBNS->vert[endpoint].st_edge.cap = pBNS->vert[endpoint].st_edge.cap0; - pBNS->vert[endpoint].st_edge.flow = pBNS->vert[endpoint].st_edge.flow0; - pBNS->vert[endpoint].type &= BNS_VERT_TYPE_ATOM; - } - } - /* Reset number of neighbors */ - if (pBNS->num_edges > pBNS->num_bonds) - { - for (i = 0; i < pBNS->num_atoms; i++) - { - pBNS->vert[i].num_adj_edges = - pBNS->vert[i].max_adj_edges - pBNS->nMaxAddEdges - NUM_KINDS_OF_GROUPS; - } - } - } - else - { - ret += 2; - } - if (!pBNS->edge) - { - ret += 4; - } - if (!pBNS->iedge) - { - ret += 8; - } - - ReInitBnStructAltPaths( pBNS ); - - pBNS->num_vertices = pBNS->num_atoms; - pBNS->num_edges = pBNS->num_bonds; - pBNS->num_added_atoms = 0; - pBNS->num_t_groups = 0; - pBNS->num_c_groups = 0; - pBNS->num_added_edges = 0; - } - else - { - ret += 1; - } - - return ret; -} - - -/****************************************************************************/ -int CompTGroupNumber( const void *tg1, const void *tg2, void *p ) -{ - return (int) ( (const T_GROUP *) tg1 )->nGroupNumber - (int) ( (const T_GROUP *) tg2 )->nGroupNumber; -} - - -/****************************************************************************/ -int CompCGroupNumber( const void *cg1, const void *cg2, void *p ) -{ - return (int) ( (const C_GROUP *) cg1 )->nGroupNumber - (int) ( (const C_GROUP *) cg2 )->nGroupNumber; -} - - -/****************************************************************************/ -int AddTGroups2BnStruct( CANON_GLOBALS *pCG, - BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - T_GROUP_INFO *tgi ) -{ - int ret = 0; - /* ret = ReInitBnStruct( pBNS ); */ - if (tgi && tgi->num_t_groups && tgi->t_group) - { - int i, k, endpoint, centerpoint, fictpoint; - int num_tg = tgi->num_t_groups; - int num_edges = pBNS->num_edges; - int num_vertices = pBNS->num_vertices; - BNS_VERTEX *vert_ficpoint, *ver_ficpont_prev; /* fictitious vertex describing t-group */ - BNS_VERTEX *vert_endpoint; - BNS_EDGE *edge; /* edge between that vertex and the tautomeric endpoint */ - int nMaxTGroupNumber = 0; - ENDPOINT_INFO eif; - - /* Debug: check overflow */ - if (num_vertices + num_tg >= pBNS->max_vertices) - { - return BNS_VERT_EDGE_OVFL; - } - /* Find the largest t-group ID */ - for (i = 0; i < num_tg; i++) - { - if (tgi->t_group[i].nGroupNumber > nMaxTGroupNumber) - { - nMaxTGroupNumber = tgi->t_group[i].nGroupNumber; - } - } - /* Since t-group IDs may be not contiguous, clear all vertices that will be added. - all-zeroes-vertex will be ignored by the BNS - */ - memset( pBNS->vert + num_vertices, 0, nMaxTGroupNumber * sizeof( pBNS->vert[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - /* Make sure the last t-group has the largest t-group ID: - this is necessary to correctly add new edges - and vertices for testing augmenting paths */ -#if ( bRELEASE_VERSION != 1 ) - insertions_sort( pCG, tgi->t_group, num_tg, sizeof( tgi->t_group[0] ), CompTGroupNumber ); - for (i = 1; i < num_tg; i++) - { - if (1 != tgi->t_group[i].nGroupNumber - tgi->t_group[i - 1].nGroupNumber) - { - return BNS_BOND_ERR; - } - } -#else - if (nMaxTGroupNumber != tgi->t_group[num_tg - 1].nGroupNumber) - { - insertions_sort( pCG, tgi->t_group, num_tg, sizeof( tgi->t_group[0] ), CompTGroupNumber ); - } -#endif - /* Initialize new fictitious vertices */ - ver_ficpont_prev = pBNS->vert + num_vertices - 1; - - for (i = 0; i < num_tg; i++, ver_ficpont_prev = vert_ficpoint) - { - /* - vert_ficpoint-1 is the last vertex; - vert_ficpoint is the vertex that is being added - Note: nGroupNumber are not contiguous - */ - vert_ficpoint = pBNS->vert + num_vertices + tgi->t_group[i].nGroupNumber - 1; - vert_ficpoint->iedge = ver_ficpont_prev->iedge + ver_ficpont_prev->max_adj_edges; - vert_ficpoint->max_adj_edges = tgi->t_group[i].nNumEndpoints + BNS_ADD_EDGES + BNS_ADD_SUPER_TGROUP; - vert_ficpoint->num_adj_edges = 0; - vert_ficpoint->st_edge.flow = vert_ficpoint->st_edge.flow0 = 0; - vert_ficpoint->st_edge.cap = vert_ficpoint->st_edge.cap0 = 0; - vert_ficpoint->type = BNS_VERT_TYPE_TGROUP; - } - - for (endpoint = 0; endpoint < num_atoms; endpoint++) - { - if (!at[endpoint].endpoint) - { - continue; - } - fictpoint = at[endpoint].endpoint + num_vertices - 1; - vert_ficpoint = pBNS->vert + fictpoint; - vert_endpoint = pBNS->vert + endpoint; - /* Debug: check overflow */ - if (fictpoint >= pBNS->max_vertices || - num_edges >= pBNS->max_edges || - vert_ficpoint->num_adj_edges >= vert_ficpoint->max_adj_edges || - vert_endpoint->num_adj_edges >= vert_endpoint->max_adj_edges) - { - ret = BNS_VERT_EDGE_OVFL; - break; - } - /* Obtain donor/acceptor info */ - if (!nGetEndpointInfo(at, endpoint, &eif) -#if ( TAUT_PT_22_00 == 1 ) - && !((tgi->bTautFlags & TG_FLAG_PT_22_00) && nGetEndpointInfo_PT_22_00(at, endpoint, &eif)) -#endif -#if ( TAUT_PT_16_00 == 1 ) - && !((tgi->bTautFlags & TG_FLAG_PT_16_00) && nGetEndpointInfo_PT_16_00(at, endpoint, &eif)) -#endif -#if ( TAUT_PT_06_00 == 1 ) - && !((tgi->bTautFlags & TG_FLAG_PT_06_00) && nGetEndpointInfo_PT_06_00(at, endpoint, &eif)) -#endif -#if ( TAUT_PT_39_00 == 1 ) - && !((tgi->bTautFlags & TG_FLAG_PT_39_00) && nGetEndpointInfo_PT_39_00(at, endpoint, &eif)) -#endif -#if ( TAUT_PT_13_00 == 1 ) - && !((tgi->bTautFlags & TG_FLAG_PT_13_00) && nGetEndpointInfo_PT_13_00(at, endpoint, &eif)) -#endif -#if ( TAUT_PT_18_00 == 1 ) - && !((tgi->bTautFlags & TG_FLAG_PT_18_00) && nGetEndpointInfo_PT_18_00(at, endpoint, &eif)) -#endif - ) { -#if ( KETO_ENOL_TAUT == 1 ) - if (!( ( tgi->bTautFlags & TG_FLAG_KETO_ENOL_TAUT ) && - nGetEndpointInfo_KET( at, endpoint, &eif ) )) -#endif - { - ret = BNS_BOND_ERR; - break; - } - } - - vert_endpoint->type |= BNS_VERT_TYPE_ENDPOINT; - - /* Set capacity = 1 to the edges from the endpoint to the centerpoint(s) */ - for (k = 0; k < vert_endpoint->num_adj_edges; k++) - { - int iedge = vert_endpoint->iedge[k]; - if (!pBNS->edge[iedge].cap) - { - /* Single bond, possibly between endpoint and centerpoint */ - centerpoint = ( pBNS->edge[iedge].neighbor12 ^ endpoint ); - if (centerpoint < pBNS->num_atoms && - pBNS->vert[centerpoint].st_edge.cap >= 1) - { - int bond_type = ( at[endpoint].bond_type[k] & BOND_TYPE_MASK ); - if (bond_type == BOND_TAUTOM || - bond_type == BOND_ALTERN || - bond_type == BOND_ALT12NS || - bond_type == BOND_SINGLE) - { - pBNS->edge[iedge].cap = 1; - } - } - } - } - - /* Create a new edge connecting endpoint to the new fictitious t-group vertex vert_ficpoint */ - edge = pBNS->edge + num_edges; - edge->cap = 1; - edge->flow = 0; - edge->pass = 0; -#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) - edge->forbidden &= pBNS->edge_forbidden_mask; -#endif - /* Later include case when the charge change allows the endpoint to become tautomeric */ - /* mark endoint having moveable H atom with flow=1 */ - - /* -- old "no charges" version -- */ - /* if (at[endpoint].chem_bonds_valence == at[endpoint].valence) */ - /* -- the following line takes charges into account -- */ - if (eif.cDonor) /* means the endpoint has an H-atom to donate */ - { - /* increment edge flow */ - edge->flow++; - /* increment one vertex st-flow & cap */ - vert_ficpoint->st_edge.flow++; - vert_ficpoint->st_edge.cap++; - /* increment another vertex st-flow & cap */ - vert_endpoint->st_edge.flow++; - vert_endpoint->st_edge.cap++; - } - /* Connect edge to endpoint and fictpoint and increment the counters of neighbors and edges */ - edge->neighbor1 = endpoint; /* the smallest out of v1=endopoint and v2=num_vertices */ - edge->neighbor12 = endpoint ^ fictpoint; /* v1 ^ v2 */ - vert_endpoint->iedge[vert_endpoint->num_adj_edges] = num_edges; - vert_ficpoint->iedge[vert_ficpoint->num_adj_edges] = num_edges++; - edge->neigh_ord[0] = vert_endpoint->num_adj_edges++; - edge->neigh_ord[1] = vert_ficpoint->num_adj_edges++; - edge->cap0 = edge->cap; - edge->flow0 = edge->flow; - } - - pBNS->num_edges = num_edges; - pBNS->num_vertices += nMaxTGroupNumber; - pBNS->num_t_groups = num_tg; - } - - return ret; -} - - -/*#if ( MOVE_CHARGES == 1 )*/ /* { */ - - - /****************************************************************************/ -int AddCGroups2BnStruct( CANON_GLOBALS *pCG, - BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - C_GROUP_INFO *cgi ) -{ - int ret = 0; - /* ret = ReInitBnStruct( pBNS ); */ - if (cgi && cgi->num_c_groups && cgi->c_group) - { - int i, k, c_point, centerpoint, fictpoint; - int num_cg = cgi->num_c_groups; - int num_edges = pBNS->num_edges; - int num_vertices = pBNS->num_vertices; - BNS_VERTEX *vert_ficpoint, *ver_ficpont_prev; /* fictitious vertex describing charge c-group */ - BNS_VERTEX *vertex_cpoint; - BNS_EDGE *edge; /* edge between that vertex and the tautomeric c_point */ - int nMaxCGroupNumber = 0; - - /* Debug: check overflow */ - if (num_vertices + num_cg >= pBNS->max_vertices) - { - return BNS_VERT_EDGE_OVFL; - } - /* Find the largest t-group ID */ - for (i = 0; i < num_cg; i++) - { - if (cgi->c_group[i].nGroupNumber > nMaxCGroupNumber) - { - nMaxCGroupNumber = cgi->c_group[i].nGroupNumber; - } - } - /* Since t-group IDs may be not contiguous, clear all vertices that will be added. - all-zeroes-vertex will be ignored by the BNS - */ - memset( pBNS->vert + num_vertices, 0, nMaxCGroupNumber * sizeof( pBNS->vert[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - /* Make sure the last t-group has the largest t-group ID: - this is necessary to correctly add new edges and vertices for testing augmenting paths - */ -#if ( bRELEASE_VERSION != 1 ) - insertions_sort( cgi->c_group, num_cg, sizeof( cgi->c_group[0] ), CompCGroupNumber ); - for (i = 1; i < num_cg; i++) - { - if (1 != cgi->c_group[i].nGroupNumber - cgi->c_group[i - 1].nGroupNumber) - { - return BNS_BOND_ERR; - } - } -#else - if (nMaxCGroupNumber != cgi->c_group[num_cg - 1].nGroupNumber) - { - insertions_sort( pCG, cgi->c_group, num_cg, - sizeof( cgi->c_group[0] ), - CompCGroupNumber ); - } -#endif - /**************************************/ - /* initialize new fictitious vertices */ - /* representing c-point groups */ - /**************************************/ - ver_ficpont_prev = pBNS->vert + num_vertices - 1; - - for (i = 0; i < num_cg; i++, ver_ficpont_prev = vert_ficpoint) - { - /* - vert_ficpoint-1 is the last vertex; - vert_ficpoint is the being added vertex - Note: nGroupNumber are not contiguous - */ - vert_ficpoint = pBNS->vert + num_vertices + cgi->c_group[i].nGroupNumber - 1; - vert_ficpoint->iedge = ver_ficpont_prev->iedge + ver_ficpont_prev->max_adj_edges; - vert_ficpoint->max_adj_edges = cgi->c_group[i].num_CPoints + BNS_ADD_EDGES; - vert_ficpoint->num_adj_edges = 0; - vert_ficpoint->st_edge.flow = vert_ficpoint->st_edge.flow0 = 0; - vert_ficpoint->st_edge.cap = vert_ficpoint->st_edge.cap0 = 0; - vert_ficpoint->type = BNS_VERT_TYPE_C_GROUP; - } - - /************************************************/ - /* Connect c-points to the fictitious vertices */ - /* representing c-point groups; set caps, flows */ - /************************************************/ - for (c_point = 0; c_point < num_atoms; c_point++) - { - if (!at[c_point].c_point) - { - continue; - } - fictpoint = at[c_point].c_point + num_vertices - 1; /* c-group vertex index */ - vert_ficpoint = pBNS->vert + fictpoint; /* c-group vertex */ - vertex_cpoint = pBNS->vert + c_point; /* c_point vertex */ - /* Debug: check overflow */ - if (fictpoint >= pBNS->max_vertices || - num_edges >= pBNS->max_edges || - vert_ficpoint->num_adj_edges >= vert_ficpoint->max_adj_edges || - vertex_cpoint->num_adj_edges >= vertex_cpoint->max_adj_edges) - { - ret = BNS_VERT_EDGE_OVFL; - break; - } - vertex_cpoint->type |= BNS_VERT_TYPE_C_POINT; -#if ( FIX_CPOINT_BOND_CAP != 1 ) /* { */ - /* set capacity = 1 to the edges from the c_point to the centerpoint(s) */ - /* if their current capacity is zero */ - /* the centerpoint is any adjacent atom that is adjacent to a multiple bond */ - for (k = 0; k < vertex_cpoint->num_adj_edges; k++) - { - int iedge = vertex_cpoint->iedge[k]; - if (!pBNS->edge[iedge].cap) - { - /* single bond, possibly between c_point and centerpoint */ - centerpoint = ( pBNS->edge[iedge].neighbor12 ^ c_point ); - if (centerpoint < pBNS->num_atoms && - pBNS->vert[centerpoint].st_edge.cap >= 1) - { - int bond_type = ( at[c_point].bond_type[k] & BOND_TYPE_MASK ); - if (bond_type == BOND_TAUTOM || - bond_type == BOND_ALTERN || - bond_type == BOND_SINGLE) - { - pBNS->edge[iedge].cap = 1; - } - } - } - } -#endif /* } FIX_CPOINT_BOND_CAP */ - - /* Create a new edge connecting c_point to the new fictitious c-group vertex vert_ficpoint */ - edge = pBNS->edge + num_edges; - edge->cap = 1; - edge->flow = 0; - edge->pass = 0; -#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) - edge->forbidden &= pBNS->edge_forbidden_mask; -#endif - /* Mark edge to c-point having NO moveable charge with flow=1 */ - if (!CHARGED_CPOINT( at, c_point )) - { - /* Increment edge flow */ - edge->flow++; - /* Increment c-group vertex st-flow & cap */ - vert_ficpoint->st_edge.flow++; - vert_ficpoint->st_edge.cap++; - /* Increment c-point vertex st-flow & cap */ - vertex_cpoint->st_edge.flow++; - vertex_cpoint->st_edge.cap++; - } - -#if ( FIX_CPOINT_BOND_CAP == 1 ) /* { */ - - /* Set capacity = 1 to the edges from the c_point to the centerpoint(s) */ - /* if their current capacity is zero */ - /* the centerpoint is any adjacent atom that is adjacent to a multiple bond */ - for (k = 0; k < vertex_cpoint->num_adj_edges; k++) - { - int iedge = vertex_cpoint->iedge[k]; - VertexFlow nNewCap = vertex_cpoint->st_edge.cap; - centerpoint = ( pBNS->edge[iedge].neighbor12 ^ c_point ); - if (!pBNS->edge[iedge].cap) - { - /* Single bond, possibly between c_point and centerpoint */ - if (centerpoint < pBNS->num_atoms && - pBNS->vert[centerpoint].st_edge.cap >= 1) - { - nNewCap = inchi_min( pBNS->vert[centerpoint].st_edge.cap, nNewCap ); - nNewCap = inchi_min( nNewCap, MAX_BOND_EDGE_CAP ); - pBNS->edge[iedge].cap = nNewCap; - } -#if ( FIX_CPOINT_BOND_CAP2 == 1 ) /* multiple bond */ - else - if (centerpoint < pBNS->num_atoms && - edge->flow && pBNS->edge[iedge].cap < MAX_BOND_EDGE_CAP) - { - pBNS->edge[iedge].cap++; - } -#endif - } - } -#endif /* } FIX_CPOINT_BOND_CAP */ - - /* Connect edge to c_point and fictpoint and increment the counters of neighbors and edges */ - edge->neighbor1 = c_point; /* the smallest out of v1=endopoint and v2=num_vertices */ - edge->neighbor12 = c_point ^ fictpoint; /* v1 ^ v2 */ - vertex_cpoint->iedge[vertex_cpoint->num_adj_edges] = num_edges; - vert_ficpoint->iedge[vert_ficpoint->num_adj_edges] = num_edges++; - edge->neigh_ord[0] = vertex_cpoint->num_adj_edges++; - edge->neigh_ord[1] = vert_ficpoint->num_adj_edges++; - edge->cap0 = edge->cap; - edge->flow0 = edge->flow; - } - - pBNS->num_edges = num_edges; - pBNS->num_vertices += nMaxCGroupNumber; - pBNS->num_c_groups = num_cg; - } - - return ret; -} -/*#endif*/ /* } MOVE_CHARGES == 1 */ - - - - /****************************************************************************/ -void ClearAllBnDataVertices( Vertex *v, Vertex value, int size ) -{ - int i; - for (i = 0; i < size; i++) - { - v[i] = value; - } -} - - -/****************************************************************************/ -void ClearAllBnDataEdges( Edge *e, Vertex value, int size ) -{ - int i; - for (i = 0; i < size; i++) - { - e[i][0] = value; - } -} - - -/****************************************************************************/ -BN_DATA *DeAllocateBnData( BN_DATA *pBD ) -{ - if (pBD) - { - if (pBD->BasePtr) - { - inchi_free( pBD->BasePtr ); - } - if (pBD->SwitchEdge) - { - inchi_free( pBD->SwitchEdge ); - } - if (pBD->Tree) - { - inchi_free( pBD->Tree ); - } - if (pBD->ScanQ) - { - inchi_free( pBD->ScanQ ); - } - if (pBD->Pu) - { - inchi_free( pBD->Pu ); - } - if (pBD->Pv) - { - inchi_free( pBD->Pv ); - } -#if ( BNS_RAD_SEARCH == 1 ) - if (pBD->RadEndpoints) - { - inchi_free( pBD->RadEndpoints ); - } - if (pBD->RadEdges) - { - inchi_free( pBD->RadEdges ); - } -#endif - inchi_free( pBD ); - } - - return NULL; -} - - -/****************************************************************************/ -BN_DATA *AllocateAndInitBnData( int max_num_vertices ) -{ - BN_DATA *pBD = NULL; - int max_len_Pu_Pv; - max_num_vertices = 2 * max_num_vertices + 2; - max_len_Pu_Pv = max_num_vertices / 2 + 1; - max_len_Pu_Pv += max_len_Pu_Pv % 2; /* even length */ - if (!( pBD = (BN_DATA *) inchi_calloc( 1, sizeof( BN_DATA ) ) ) || - !( pBD->BasePtr = (Vertex *) inchi_calloc( max_num_vertices, sizeof( Vertex ) ) ) || - !( pBD->SwitchEdge = (Edge *) inchi_calloc( max_num_vertices, sizeof( Edge ) ) ) || - !( pBD->Tree = (S_CHAR *) inchi_calloc( max_num_vertices, sizeof( S_CHAR ) ) ) || - !( pBD->ScanQ = (Vertex *) inchi_calloc( max_num_vertices, sizeof( Vertex ) ) ) || - !( pBD->Pu = (Vertex *) inchi_calloc( max_len_Pu_Pv, sizeof( Vertex ) ) ) || -#if ( BNS_RAD_SEARCH == 1 ) - !( pBD->RadEndpoints = (Vertex *) inchi_calloc( max_len_Pu_Pv, sizeof( Vertex ) ) ) || - !( pBD->RadEdges = (EdgeIndex*) inchi_calloc( max_len_Pu_Pv, sizeof( EdgeIndex ) ) ) || -#endif - !( pBD->Pv = (Vertex *) inchi_calloc( max_len_Pu_Pv, sizeof( Vertex ) ) ) - ) - { - pBD = DeAllocateBnData( pBD ); - } - else - { - /* Initialize data */ - ClearAllBnDataEdges( pBD->SwitchEdge, NO_VERTEX, max_num_vertices ); - ClearAllBnDataVertices( pBD->BasePtr, NO_VERTEX, max_num_vertices ); - memset( pBD->Tree, TREE_NOT_IN_M, max_num_vertices ); /* djb-rwth: memset_s C11/Annex K variant? */ - pBD->QSize = -1; - pBD->max_len_Pu_Pv = max_len_Pu_Pv; - pBD->max_num_vertices = max_num_vertices; -#if ( BNS_RAD_SEARCH == 1 ) - pBD->nNumRadEndpoints = 0; -#endif - } - - return pBD; -} - - -/****************************************************************************/ -int ReInitBnData( BN_DATA *pBD ) -{ - int i, ret = 0; - Vertex u, v; - if (pBD) - { - if (!pBD->ScanQ) - { - ret += 2; - } - if (!pBD->BasePtr) - { - ret += 4; - } - if (!pBD->SwitchEdge) - { - ret += 8; - } - if (!pBD->Tree) - { - ret += 16; - } - if (!ret) - { - for (i = 0; i <= pBD->QSize; i++) - { - u = pBD->ScanQ[i]; - v = prim( u ); - pBD->BasePtr[u] = - pBD->BasePtr[v] = - pBD->SwitchEdge_Vert1( u ) = - pBD->SwitchEdge_Vert1( v ) = NO_VERTEX; - pBD->Tree[u] = - pBD->Tree[v] = TREE_NOT_IN_M; - } - } - pBD->QSize = -1; - if (!pBD->Pu) - { - ret += 32; - } - if (!pBD->Pv) - { - ret += 64; - } - } - else - { - ret += 1; - } - - return ret; -} - - -/****************************************************************************/ -int GetVertexDegree( BN_STRUCT* pBNS, Vertex v ) -{ - int i = v / 2 - 1; - if (i >= 0) - { - if (pBNS->vert[i].st_edge.cap > 0) - { - return pBNS->vert[i].num_adj_edges + 1; /* add 1 neighbor for s or t */ - } - else - { - return 0; /* since the edge s-v has zero capacity, we ignore vertex v */ - } - } - else - { - return pBNS->num_vertices; - } -} - - -/****************************************************************************/ -Vertex Get2ndEdgeVertex( BN_STRUCT* pBNS, Edge uv ) -{ - /* - Vertex ret; - */ - if (uv[1] >= 0) - { - /* -- debug -- - if ( uv[1] > pBNS->num_edges || uv[0] > 2*pBNS->num_vertices+3 ) { - int stop = 1; - } - ret = ((uv[0]-2) ^ (2*pBNS->edge[uv[1]].neighbor12+1)) + 2; - if ( ret > 2*pBNS->num_vertices+3 ) { - int stop = 1; - } - return ret; - -- end debug -- */ - - return ( ( uv[0] - 2 ) ^ ( 2 * pBNS->edge[uv[1]].neighbor12 + 1 ) ) + 2; - - /*short u = uv[0]-FIRST_INDX; */ - /*short t = 2*(((u / 2 - 1) ^ pBNS->edge[uv[1]].neighbor12) + 1) + ((u+1) & 1) + FIRST_INDX; */ - /*return t; */ - } - - if (uv[0] <= 1) - { - return -( 1 + uv[1] ); /* vertex1 is s or t, return x or y */ - } - else - { - return uv[0] % 2; /* vertex1 is x or y, return s or t; never happens? -- NSC 3737, 7634,... */ - } - -} - - -/****************************************************************************/ -Vertex GetVertexNeighbor( BN_STRUCT* pBNS, - Vertex v, - int neigh, - EdgeIndex *iedge ) -{ - /* neigh = 0 => the neighbor is s or t except case when v is s or t. */ - /* v= FIRST_INDX or FIRST_INDX+1: v is s or t respectively */ - int i, neighbor; - if (( i = v - 2 ) >= 0) - { - /* Neighbor of x or y */ - if (neigh) - { - neigh--; - /* x or y */ - *iedge = pBNS->vert[i / 2].iedge[neigh]; - if (!( pBNS->edge[*iedge].cap & EDGE_FLOW_MASK ) || IS_FORBIDDEN( pBNS->edge[*iedge].forbidden, pBNS )) - { - return NO_VERTEX; - } - neighbor = ( i ^ ( 2 * pBNS->edge[*iedge].neighbor12 + 1 ) ) + 2; /* parity opposite to v parity */ - } - else - { - /* neighbor of x or y is s or t */ - neighbor = ( v & 1 ); /* s or t, same parity as v */ - *iedge = -( neighbor + 1 ); - } - } - else - { - /* neighbor of s or t: x or y, same parity as v */ - if (!( pBNS->vert[neigh].st_edge.cap & EDGE_FLOW_ST_MASK )) - { - return NO_VERTEX; - } - neighbor = 2 * neigh + 2 + ( v & 1 ); /* parity same as the parity of v */ - *iedge = -( neighbor + 1 ); - } - - return neighbor; -} - - -/****************************************************************************/ -int GetEdgePointer( BN_STRUCT* pBNS, - Vertex u, - Vertex v, - EdgeIndex iuv, - BNS_EDGE **uv, - S_CHAR *s_or_t ) -{ - int i = u / 2 - 1; - int j = v / 2 - 1; - int bBackward = BNS_WRONG_PARMS; - *uv = NULL; - if (i >= 0) - { - /* u is an atom */ - if (j >= 0) - { - /* v is an atom */ - if (( u + v ) % 2) - { - *uv = pBNS->edge + iuv; - bBackward = ( u & 1 ); - *s_or_t = 0; - } - } - else - { - /* v is s or t */ - if (v >= 0 && !( ( u + v ) % 2 )) - { - *uv = (BNS_EDGE*) &pBNS->vert[i].st_edge; - bBackward = !( v & 1 ); - *s_or_t = v + 3; /* 3=> v=s, 4=> v=t */ - } - } - } - else - { - if (j >= 0) - { - /* u is s or t */ - if (u >= 0 && !( ( u + v ) % 2 )) - { - /* v is an atom */ - *uv = (BNS_EDGE*) &pBNS->vert[j].st_edge; - bBackward = ( u & 1 ); - *s_or_t = u + 1; /* 1=> u=s, 2=> u=t */ - } - } - } - - return bBackward; -} - - -/****************************************************************************/ -int AugmentEdge( BN_STRUCT* pBNS, - Vertex u, - Vertex v, - EdgeIndex iuv, - int delta, - S_CHAR bReverse, - int bChangeFlow ) -{ - int f, flow, ret = 0; - - BNS_ST_EDGE *pst_edge; - BNS_EDGE *pedge; - S_CHAR s_or_t; - int bBackward = GetEdgePointer( pBNS, u, v, iuv, &pedge, &s_or_t ); - if (!IS_BNS_ERROR( bBackward )) - { - if (bBackward) - { - delta = -delta; - } - - if (s_or_t) - { - pst_edge = (BNS_ST_EDGE *) pedge; - flow = pst_edge->flow; - f = ( flow & EDGE_FLOW_ST_MASK ) + delta; /* new flow */ - if (!delta) - { - /*((BNS_ST_EDGE *)pedge)->flow = pst_edge->flow & ~EDGE_FLOW_ST_PATH;*/ - pst_edge->flow = pst_edge->flow & ~EDGE_FLOW_ST_PATH; - } - else - { - int cap = pst_edge->cap; - if (f < 0 || f > cap) - { - ret = BNS_WRONG_PARMS; - } - else - { - if (!( bChangeFlow & BNS_EF_CHNG_FLOW )) - { - f -= delta; /* do not actually change the flow, only find the augmenting path */ - } - else - { - if (delta) - { - /*((BNS_ST_EDGE *)pedge)->pass ++;*/ - pst_edge->pass++; - } - } - flow = ( flow & ~( EDGE_FLOW_ST_PATH | EDGE_FLOW_ST_MASK ) ) + f; - /*((BNS_ST_EDGE *)pedge)->flow = flow;*/ - pst_edge->flow = flow; - /*((BNS_ST_EDGE *)pedge)->delta += delta; */ - if (bReverse) - { - /* u <- v; Note: in case of bReverse s_or_t has actually been determined - for the u' <- v' pair; therefore s and t should be switched - in order to correctly determine the 1st or the last atom - on the augmenting path. - */ - switch (s_or_t) - { - case 1: /* u = t: t<-v, v is the last vertex */ - ALTP_END_ATOM( pBNS->alt_path ) = v / 2 - 1; - break; - case 2: /* u = s: s<-v, error */ - ret = BNS_WRONG_PARMS; - break; - case 3: /* v = t: u<-t, error */ - ret = BNS_WRONG_PARMS; - break; - case 4: /* v = s: u<-s, u is the first vertex */ - ALTP_START_ATOM( pBNS->alt_path ) = u / 2 - 1; - ALTP_DELTA( pBNS->alt_path ) = delta; - break; - default: - ret = BNS_WRONG_PARMS; - break; - } - } - else - { - /* u -> v */ - switch (s_or_t) - { - case 1: /* u = s: s->v, v is the first vertex */ - ALTP_START_ATOM( pBNS->alt_path ) = v / 2 - 1; - ALTP_DELTA( pBNS->alt_path ) = delta; - break; - case 2: /* u = t: t->v, error */ - ret = BNS_WRONG_PARMS; - break; - case 3: /* v = s: u->s, error */ - ret = BNS_WRONG_PARMS; - break; - case 4: /* v = t: u->t, u is the last vertex */ - ALTP_END_ATOM( pBNS->alt_path ) = u / 2 - 1; - break; - default: - ret = BNS_WRONG_PARMS; - break; - } - } - } - } - } - else - { - f = ( pedge->flow & EDGE_FLOW_MASK ) + delta; - if (!delta) - { - pedge->flow &= ~EDGE_FLOW_PATH; - } - else - { - if (f < 0 || f > pedge->cap) - { - ret = BNS_WRONG_PARMS; - } - else - { - AT_NUMB iu = u / 2 - 1; - AT_NUMB iv = v / 2 - 1; - int indx; - if (!( bChangeFlow & BNS_EF_CHNG_FLOW )) - { - f -= delta; /* do not actually change the flow, only find the augmenting path */ - } - else - { - if (delta) - { - pedge->pass++; - } - } - pedge->flow = ( pedge->flow & ~( EDGE_FLOW_PATH | EDGE_FLOW_MASK ) ) | f; - if (ALTP_MAY_ADD( pBNS->alt_path )) - { - /* bReverse? u <- v : u -> v */ - indx = bReverse ? ( pedge->neighbor1 == iv ) : ( pedge->neighbor1 == iu ); - ALTP_CUR_THIS_ATOM_NEIGHBOR( pBNS->alt_path ) = pedge->neigh_ord[1 - indx]; - ALTP_CUR_NEXT_ATOM_NEIGHBOR( pBNS->alt_path ) = pedge->neigh_ord[indx]; - ALTP_NEXT( pBNS->alt_path ); - } - else - { - ALTP_OVERFLOW( pBNS->alt_path ) = 1; - ret = BNS_ALTPATH_OVFL; - } - } - } - } - return ret ? ret : f; - } - - return bBackward; -} - - -/**************************************************************************** -rescap_mark( ... ) - -Find residual capacity and mark the edge -as belonging to the augmenting path -****************************************************************************/ -int rescap_mark( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv ) -{ - BNS_ST_EDGE *pst_edge; - BNS_EDGE *pedge; - - int f, flow; - S_CHAR s_or_t; - int bBackward = GetEdgePointer( pBNS, u, v, iuv, &pedge, &s_or_t ); - - if (!IS_BNS_ERROR( bBackward )) - { - if (s_or_t) - { - pst_edge = (BNS_ST_EDGE *) pedge; - flow = pst_edge->flow; - f = ( flow & EDGE_FLOW_ST_MASK ); - if (!bBackward) - { - f = (int) pst_edge->cap - f; - } - if (flow & EDGE_FLOW_ST_PATH) - { - pBNS->bNotASimplePath++; - f /= 2; /* this is the second time we pass the same edge: reduce flow by a factor of 2 */ - } - else - { - pst_edge->flow |= EDGE_FLOW_ST_PATH; /* mark the edge */ - } - } - else - { - flow = pedge->flow; - f = flow & EDGE_FLOW_MASK; - if (!bBackward) - { - f = (int) pedge->cap - f; - } - if (flow & EDGE_FLOW_PATH) - { - f /= 2; /* this is the second time we pass the same edge: reduce flow by a factor of 2 */ - pBNS->bNotASimplePath++; - } - else - { - pedge->flow |= EDGE_FLOW_PATH; /* mark the edge */ - } - } - return f; - } - - return bBackward; -} - - -/**************************************************************************** -GetPrevVertex( ... ) - -Get previous vertex in the searched path -z is SwitchEdge_Vert2(y) != y. Go backward from z to y -****************************************************************************/ -Vertex GetPrevVertex( BN_STRUCT* pBNS, Vertex y, Edge *SwitchEdge, EdgeIndex *iuv ) -{ - Vertex w, z, x2, y2; /* djb-rwth: removing redundant variables */ - EdgeIndex iwy; - - w = SwitchEdge_Vert1( y ); - z = SwitchEdge_Vert2( y ); - iwy = SwitchEdge_IEdge( y ); - if (z == y) - { - *iuv = iwy; - return w; - } - x2 = prim( y ); - y2 = prim( z ); - /* djb-rwth: removing redundant code */ - while (y2 != NO_VERTEX) - { - w = SwitchEdge_Vert1( y2 ); - z = SwitchEdge_Vert2( y2 ); - iwy = SwitchEdge_IEdge( y2 ); - if (w == x2) - { - *iuv = iwy; - /*return z; */ - return ( y + z ) % 2 ? z : prim( z ); - } - /* djb-rwth: removing redundant code */ - /* - #ifdef _DEBUG - if ( n ) { - int stop = 1; - } - #endif - */ - if (w == y2) - { - return NO_VERTEX; - } - y2 = w; - } - - return y2; -} - - - -#define CHECK_TACN 1 - - -/**************************************************************************** -The purpose is to avoid paths - -(H-group)[u]---atom[v]---((-)-cgroup)[w], - -where atom[v] is not acidic and (-) and H are not interchangeable without -explicit bond tautomerism. - -It is important that acidic atoms are only O,S,Se,Te and should have -only one chemical bond. Only because of this an early rejection of -the vertex v (before it gets on SCANQ) is possible. - -CHECK_TACN == 1 prohibits replacing (-) on N with H unless H can be moved to N -along an alternating path from another heteroatom (t-group will be detected). -****************************************************************************/ - - -#if ( FIX_TACN_POSSIBLE_BUG == 1 ) /* { */ - - -/****************************************************************************/ -int bIgnoreVertexNonTACN_atom( BN_STRUCT* pBNS, Vertex u, Vertex v ) -{ -#define TYPE_T 1 /* t-group [also called H-group] */ -#define TYPE_CN 2 /* (-)c-group */ - int i, degree, ret, u_is_taut = 0, w_is_taut, num_allowed = 0, num_found_groups = 0; - Vertex w; - EdgeIndex ivw; - if (!pBNS->type_TACN || u <= 1 || v <= 1 || - ( pBNS->vert[v / 2 - 1].type & pBNS->type_TACN )) - { - return 0; /* add/remove H(+) is allowed for acidic atoms */ - } - if (!pBNS->type_T || !pBNS->type_CN) - { - return 0; /* should not happen */ - } - u_is_taut = ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) ? TYPE_T : - ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ? TYPE_CN : 0; - if (u_is_taut) - { - /* u is either t-group vertex or (-) c-group */ - degree = GetVertexDegree( pBNS, v ); - for (i = 0; i < degree; i++) - { - /* v = vert[u].neighbor[i]; */ - w = GetVertexNeighbor( pBNS, v, i, &ivw ); - if (w == NO_VERTEX || w <= 1) - { - continue; /* the atom has only single bonds or it is s or t, ignore it */ - } - if (w != u && ( ret = rescap( pBNS, v, w, ivw ) ) > 0) - { - num_allowed++; - w_is_taut = ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ? TYPE_CN : - ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) ? TYPE_T : 0; - if (( u_is_taut | w_is_taut ) == ( TYPE_T | TYPE_CN )) - { - num_found_groups++; - } - } - } - if (num_found_groups && num_allowed == 1) - { - return 1; /* reject */ - } - } - - return 0; -#undef TYPE_T -#undef TYPE_CN -} - - -#else /* } FIX_TACN_POSSIBLE_BUG { */ - - -/****************************************************************************/ -int bIgnoreVertexNonTACN_atom( BN_STRUCT* pBNS, Vertex u, Vertex v ) -{ - int i, degree, ret, u_is_taut = 0, num_allowed = 0, num_found_groups = 0; - Vertex w; - EdgeIndex ivw; - if (!pBNS->type_TACN || u <= 1 || v <= 1 || - ( pBNS->vert[v / 2 - 1].type & pBNS->type_TACN )) - { - return 0; /* add/remove H(+) is allowed for acidic atoms */ - } - if (!pBNS->type_T || !pBNS->type_CN) - { - return 0; /* should not happen */ - } - if (( u_is_taut = ( pBNS->vert[u / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) || - ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN )) - { - /* u is either t-group vertex or (-) c-group */ - degree = GetVertexDegree( pBNS, v ); - for (i = 0; i < degree; i++) - { - /* v = vert[u].neighbor[i]; */ - w = GetVertexNeighbor( pBNS, v, i, &ivw ); - if (w == NO_VERTEX || w <= 1) - { - continue; /* the atom has only single bonds or it is s or t, ignore it */ - } - if (w != u && ( ret = rescap( pBNS, v, w, ivw ) ) > 0) /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - { - num_allowed++; - if (( u_is_taut ? ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) : - ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) )) - { - num_found_groups++; - } - } - } - if (num_found_groups && num_allowed == 1) - { - return 1; /* reject */ - } - } - - return 0; -} - - - -#endif /* } FIX_TACN_POSSIBLE_BUG */ - - - -/**************************************************************************** -The purpose is to avoid paths -(H-group)[u]---atom[v]---((-)-cgroup)[w], - -where atom[v] is not acidic and (-) and H are not interchangeable without -explicit bond tautomerism. - -It is important that acidic atoms are only O,S,Se,Te and should have -only one chemical bond. Only because of this an early rejection of -the vertex v (before it gets on SCANQ) is possible. -****************************************************************************/ - - -#if ( FIX_TACN_POSSIBLE_BUG == 1 ) /* { */ - - -/****************************************************************************/ -int bIgnoreVertexNonTACN_group( BN_STRUCT* pBNS, - Vertex v, - Vertex w, - Edge *SwitchEdge ) -{ -#define TYPE_T 1 /* t-group [also called H-group] */ -#define TYPE_CN 2 /* (-)c-group */ - int u_is_taut = 0, w_is_taut = 0; - Vertex u; - EdgeIndex iuv; - if (v <= 1 || w <= 1) - return 0; -#if ( CHECK_TACN == 1 ) - if (!pBNS->type_TACN || - ( pBNS->vert[v / 2 - 1].type & pBNS->type_TACN )) - { - return 0; - } - if (!pBNS->type_T || !pBNS->type_CN) - { - return 0; /* should not happen */ - } -#endif - u = GetPrevVertex( pBNS, v, SwitchEdge, &iuv ); - /* - u = SwitchEdge_Vert1(v); - iuv = SwitchEdge_IEdge(v); - */ - if (u == NO_VERTEX || iuv < 0) - return 0; /* should not happen */ - /* check edge adjacency */ - if (pBNS->edge[iuv].neighbor1 != ( u / 2 - 1 ) && pBNS->edge[iuv].neighbor1 != v / 2 - 1 || - ( pBNS->edge[iuv].neighbor12 ^ ( u / 2 - 1 ) ) != ( v / 2 - 1 )) - { - return 0; /* !!! should not happen !!! */ - } - -#if ( CHECK_TACN == 1 ) - u_is_taut = ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) ? TYPE_T : - ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ? TYPE_CN : 0; - w_is_taut = ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) ? TYPE_T : - ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ? TYPE_CN : 0; - if (( u_is_taut | w_is_taut ) == ( TYPE_T | TYPE_CN )) - { - /* rescap must have already been checked */ - return 1; - } -#endif - - return 0; -#undef TYPE_T -#undef TYPE_CN -} - - -#else /* } FIX_TACN_POSSIBLE_BUG { */ - - -/****************************************************************************/ -int bIgnoreVertexNonTACN_group( BN_STRUCT* pBNS, - Vertex v, - Vertex w, - Edge *SwitchEdge ) -{ - int u_is_taut = 0, w_is_taut = 0; - Vertex u; - EdgeIndex iuv; - if (v <= 1 || w <= 1) - return 0; -#if ( CHECK_TACN == 1 ) - if (!pBNS->type_TACN || - ( pBNS->vert[v / 2 - 1].type & pBNS->type_TACN )) - { - return 0; - } - if (!pBNS->type_T || !pBNS->type_CN) - { - return 0; /* should not happen */ - } -#endif - u = GetPrevVertex( pBNS, v, SwitchEdge, &iuv ); - /* - u = SwitchEdge_Vert1(v); - iuv = SwitchEdge_IEdge(v); - */ - if (u == NO_VERTEX || iuv < 0) - { - return 0; /* should not happen */ - } - /* check edge adjacency */ - if ((pBNS->edge[iuv].neighbor1 != ( u / 2 - 1 ) && pBNS->edge[iuv].neighbor1 != v / 2 - 1) || - (( pBNS->edge[iuv].neighbor12 ^ ( u / 2 - 1 ) ) != ( v / 2 - 1 ))) /* djb-rwth: addressing LLVM warning */ - { - return 0; /* !!! should not happen !!! */ - } - -#if ( CHECK_TACN == 1 ) - if (( ( u_is_taut = ( pBNS->vert[u / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) || - ( ( pBNS->vert[u / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ) && - ( ( w_is_taut = ( pBNS->vert[w / 2 - 1].type & pBNS->type_T ) == pBNS->type_T ) || - ( ( pBNS->vert[w / 2 - 1].type & pBNS->type_CN ) == pBNS->type_CN ) ) && - u_is_taut + w_is_taut == 1) - { - /* rescap must have already been checked */ - return 1; - } -#endif - - return 0; -} -#endif /* } FIX_TACN_POSSIBLE_BUG { */ - - - -#if ( FIX_KEEP_H_ON_NH_ANION == 1 ) - - -/**************************************************************************** -bIsRemovedHfromNHaion( ... ) - -Detect an attempt to remove H from -NH(-) to make =N(-); -all taut atoma except N are 'acidic' -****************************************************************************/ -int bIsRemovedHfromNHaion( BN_STRUCT* pBNS, Vertex u, Vertex v ) -{ - int i, u2, v2, vat2; - Vertex vtg, vat; - BNS_VERTEX *pvAT, *pvCN; - BNS_EDGE *pEdge; - if (!pBNS->type_TACN || u <= 1 || v <= 1 || - u % 2 || !( v % 2 ) /* the edge flow may only increase */) - { - return 0; - } - if (( pBNS->vert[u2 = u / 2 - 1].type & pBNS->type_TACN ) || - ( pBNS->vert[v2 = v / 2 - 1].type & pBNS->type_TACN )) - { - return 0; /* add/remove H is allowed for acidic atoms */ - } - if (!pBNS->type_T || !pBNS->type_CN) - { - return 0; /* should not happen */ - } - /* find which of u, v vertices is N and which is t-group */ - if (( ( pBNS->vert[u2].type & pBNS->type_T ) == pBNS->type_T ) && v2 < pBNS->num_atoms) - { - vtg = u; - vat = v; - } - else - { - if (( ( pBNS->vert[v2].type & pBNS->type_T ) == pBNS->type_T ) && u2 < pBNS->num_atoms) - { - vtg = v; - vat = u; - } - else - { - return 0; - } - } - - vat2 = vat / 2 - 1; - pvAT = pBNS->vert + vat2; /* atom */ - for (i = pvAT->num_adj_edges - 1; 0 <= i; i--) - { - pEdge = pBNS->edge + pvAT->iedge[i]; - pvCN = pBNS->vert + ( pEdge->neighbor12 ^ vat2 ); - if (( ( pvCN->type & pBNS->type_CN ) == pBNS->type_CN ) && pEdge->flow > 0) - { - return 1; /* detected */ - } - } - - return 0; -} -#endif - - -#if ( FIX_AVOID_ADP == 1 ) - -/**************************************************************************** -bIsAggressiveDeprotonation( ... ) - -Detect (tg)-N=A-A=A-A=N-(tg) -u v w -k = 5 4 3 2 1 0 1 2 -^ -odd number means ADP -****************************************************************************/ -int bIsAggressiveDeprotonation( BN_STRUCT* pBNS, - Vertex v, - Vertex w, - Edge *SwitchEdge ) -{ -#define TYPE_T 1 /* t-group [also called H-group] */ -#define TYPE_CN 2 /* (-)c-group */ -#define TYPE_AT 4 - int k, v2, u2, w2, u2_next, type0, type1, type2, type; - Vertex u, u_next; - EdgeIndex iuv; - - if (v <= 1 || w <= 1) - { - return 0; - } - - if (!pBNS->type_TACN || !pBNS->type_T || !pBNS->type_CN) - { - return 0; /* should not happen */ - } - - v2 = v / 2 - 1; - w2 = w / 2 - 1; - if (v2 >= pBNS->num_atoms || w2 < pBNS->num_atoms) - { - goto cross_edge; - } - - if (!( ( pBNS->vert[w2].type & pBNS->type_T ) == pBNS->type_T ) && - !( ( pBNS->vert[w2].type & pBNS->type_CN ) == pBNS->type_CN )) - { - goto cross_edge; - } - - /* v ia an atom, w is a t-group, v != w' */ - for (k = 0, u = v; 1 < ( u_next = u, u = GetPrevVertex( pBNS, u, SwitchEdge, &iuv ) ); k++) - { - u2 = u / 2 - 1; - if (u2 >= pBNS->num_atoms) - { - /* Moving backward along the alt path we have found a vertex - that is not an atom. Possibly it is a t- or (-)c-group */ - if (!( k % 2 )) - { - return 0; /* even vertex -- always okay */ - } - if (!( ( pBNS->vert[u2].type & pBNS->type_T ) == pBNS->type_T ) && - !( ( pBNS->vert[u2].type & pBNS->type_CN ) == pBNS->type_CN )) - { - /* not a t- or (-)c-group */ - return 0; - } - u2_next = u_next / 2 - 1; - if (!( pBNS->vert[v2].type & pBNS->type_TACN ) && - !( pBNS->vert[u2_next].type & pBNS->type_TACN )) - { - /* none of the atoms at the ends are N */ - return 0; - } - return 1; - } - } - - return 0; - -cross_edge: - - /***************************************************************************** - * v and w (v=w') are same vertex reached with opposite "phases". - * w cannot be (t) because this would have been detected earlier -- ??? - * (t)-A=A-A=A-A=A-(t) - * v - * 3 2 1 0 1 2 3 4 - * kv kw - * (kv + kw)%2 == 1 <==> aggressive deprotonation - *****************************************************************************/ - - if (v == prim( w )) - { - type0 = 0; - if (v2 >= pBNS->num_atoms) - { - type0 = ( ( pBNS->vert[v2].type & pBNS->type_T ) == pBNS->type_T ) ? TYPE_T : - ( ( pBNS->vert[v2].type & pBNS->type_CN ) == pBNS->type_CN ) ? TYPE_CN : 0; - } - } - - return 0; -} -#endif - - -/****************************************************************************/ -int rescap( BN_STRUCT* pBNS, Vertex u, Vertex v, EdgeIndex iuv ) -{ - BNS_ST_EDGE *pst_edge; - BNS_EDGE *pedge; - - int f; - S_CHAR s_or_t; - int bBackward = GetEdgePointer( pBNS, u, v, iuv, &pedge, &s_or_t ); - - if (!IS_BNS_ERROR( bBackward )) - { - - if (s_or_t) - { - pst_edge = (BNS_ST_EDGE *) pedge; - f = ( pst_edge->flow & EDGE_FLOW_ST_MASK ); - if (!bBackward) - { - f = (int) pst_edge->cap - f; - } - } - else - { - f = ( pedge->flow & EDGE_FLOW_MASK ); - if (!bBackward) - { - f = (int) pedge->cap - f; - } - } - return f; - } - - return bBackward; /* error */ -} - - -/**************************************************************************** -W.Kocay, D.Stone, -"An Algorithm for Balanced Flows", -The Journal of Combinatorial Mathematics and Combinatorial Computing, -vol. 19 (1995) pp. 3-31 - -W.Kocay, D.Stone, -"Balanced network flows", -Bulletin of the Institute of Combinatorics and its Applications, -vol. 7 (1993), pp. 17--32 - -N = a balanced network (bipartite directed graph) of: -n=2*V+2 vertices (incl. s (source) and t (target); -each other vertex i is included 2 times: -set X (x[i]) of V vertices (v) and a set Y (y[j]) of -V complementary vertices (v') so that x[i]' = y[i], x[i]''=x[i], and -m=2*E+2*V edges (each original undirected edge i-j is represented as -2 directed edges: x[i]->y[j] and x[j]->y[i]; plus -V edges s->x[i] and V edges y[j]->t) -v' = a complement vertex to v -v'u' = (uv)' = a complement edge to uv -rescap(uv) = cap(uv)-f(uv) if uv is a forward edge -= f(uv) if uv is a backward edge -(i) 0 <= f(uv) <= cap(uv) -(ii) f+(u) = f-(u) for all u in X, Y where f+(u) is a total flow out of u, -and f-(u) is a total flow into u -(iii) f(uv) = f((uv)') (balanced flow condition) - -S = a set of all s-searchable vertices -S- = all other vertices -if t in S, then N contains a valid augmenting path P, so that flow can be -augmented on both P and P' -if t not in S, then let K=[S,S-], the set of all edges directed from S to S-. -K is an edge-cut that has a special structure. -Let -A = {x[i], y[i] |x[i] not in S, y[i] in S} -B = {x[i], y[i] |x[i] in S, y[i] not in S} -C = {x[i], y[i] |x[i] in S, y[i] in S} -D = {x[i], y[i] |x[i] not in S, y[i] not in S} -N[C] = subgraph of N induced by C; -it consists of of a number of connected components C[i] -K[i] = those edges of K with one endpoint in C[i]. - -If t is in S- then - -i) Each C[i] = C[i]' -ii) There are no edges between C and D -iii) Each K[i] has odd capacity, it is called a balanced edge-cut. - -balcap(K) = cap(K) - odd(K), where odd(K) is the number of connected components in N[C]. -Name "odd(K)" is because each cap(K[i]) is odd. - -Max-Balanced-Flow-Min-Balanced-Cut Theorem: - -Let f be a balanced flow in N, and let K be any balanced edge-cut. -The value of a maximum balanced flow equals the capacity of a minimum -edge-cut, that is, val(f) = balcap(K) when f is maximum and K is minimum. - -****************************************************************************/ - - -/*******************************************************/ -/* */ -/* VERTEX NUMBERING */ -/* */ -/* Total number of atoms = n */ -/* Total number of vertices = 2*n+2 */ -/*******************************************************/ -/* */ -/* atom numbering starts from 0: */ -/* */ -/* atoms s t x0 y0 x1 y1 ... xi yi ...xn yn */ -/* vertices 0 1 2 3 4 5 ... 2i-2 2i-1 ...2n-2 2n-1 */ -/* */ -/* atom = vertex/2-1; if negative then s or t */ -/* */ -/* vertex = (atom + 1) * 2 + i; i=0 for x, i=1 for y */ -/* */ -/*******************************************************/ - -/*********************************************************************************/ -/* v' variable is called prim(v) for now */ -/*********************************************************************************/ - -/* -BalancedNetworkSearch( ... ) - -N has source s, target t, the mirror network M is constructed. -The tree T contains a valid sv-path for each v in T. Simultaneously, the complementary -tree T' is built as indicated in comments. The trees T and T' must have no edges or -vertices in common. Initially T will be built as in breadth-first-search, and T' will -be the complementary tree, it will contain the complementary valid v't-path. - -NB: this procedure is _not_ recursive - -*/ - - -/****************************************************************************/ -int BalancedNetworkSearch( BN_STRUCT* pBNS, BN_DATA *pBD, int bChangeFlow ) - -{ - Vertex *BasePtr = pBD->BasePtr; - Edge *SwitchEdge = pBD->SwitchEdge; - S_CHAR *Tree = pBD->Tree; - Vertex *ScanQ = pBD->ScanQ; - int QSize = pBD->QSize; - Vertex *Pu = pBD->Pu; - Vertex *Pv = pBD->Pv; - int max_len_Pu_Pv = pBD->max_len_Pu_Pv; - - /* added to translate into C */ - int i, k, degree, delta, ret = 0; - Vertex u, b_u, v, b_v, w; - EdgeIndex iuv; -#if ( BNS_RAD_SEARCH == 1 ) - int n, bRadSearch = ( BNS_EF_RAD_SRCH & bChangeFlow ) && pBD->RadEndpoints; - BRS_MODE bRadSrchMode = RAD_SRCH_NORM; - int bRadSearchPrelim = 0; - if (bRadSearch) - { - pBD->nNumRadEndpoints = 0; - bRadSrchMode = pBD->bRadSrchMode; - bRadSearchPrelim = pBNS->type_TACN && bRadSrchMode == RAD_SRCH_NORM; - } -#endif - - /* -- Always -- - Vertex_s = FIRST_INDX; - Vertex_t = Vertex_s+1; - */ - QSize = k = 0; /* put s on ScanQ = set S */ - ScanQ[QSize] = Vertex_s; - BasePtr[Vertex_t] = Vertex_s; - BasePtr[Vertex_s] = BLOSSOM_BASE; /* create initial blossom C(Vertex_s) with base s */ - Tree[Vertex_s] = TREE_IN_1; - - do - { - u = ScanQ[k]; /* select u from the head of ScanQ */ - /* since u is on the queue, it has a blossom C(U) with base b_u */ - b_u = FindBase( u, BasePtr ); - degree = GetVertexDegree( pBNS, u ); -#if ( BNS_RAD_SEARCH == 1 ) - n = 0; -#endif - for (i = 0; i < degree; i++) - { - /* v = vert[u].neighbor[i]; */ - v = GetVertexNeighbor( pBNS, u, i, &iuv ); - if (v == NO_VERTEX) - { - continue; /* the atom has only single bonds, ignore it */ - } -#if ( BNS_RAD_SEARCH == 1 ) - if (!k && bRadSrchMode == RAD_SRCH_FROM_FICT && v / 2 <= pBNS->num_atoms) - { - continue; /* start from fict. vertices only */ - } - if (bRadSearchPrelim && v / 2 > pBNS->num_atoms) - { - continue; /* during initial add/remove H allow radical movement only through real atoms */ - } -#endif - if ( /* PrevPt[u] != v ** avoid edges of T */ - ( SwitchEdge_Vert1( u ) != v || SwitchEdge_Vert2( u ) != u ) /* avoid edges of T */ - && ( ret = rescap( pBNS, u, v, iuv ) ) > 0) - { - /* Special treatment to prevent H<->(-) replacement on non-acidic atoms */ - /*----------------------------------------------------------------------*/ - if (pBNS->type_TACN) - { - if (bIgnoreVertexNonTACN_atom( pBNS, u, v )) - { - continue; - } - if (bIgnoreVertexNonTACN_group( pBNS, u, v, SwitchEdge )) - { - continue; - } -#if ( FIX_KEEP_H_ON_NH_ANION == 1 ) - if (bIsRemovedHfromNHaion( pBNS, u, v )) - { - continue; - } -#endif -#if ( FIX_AVOID_ADP == 1 ) - if (bIsAggressiveDeprotonation( pBNS, u, v, SwitchEdge )) - { - continue; - } -#endif - } - /*----------------------------------------------------------------------*/ - b_v = FindBase( v, BasePtr ); /* Notation: b_x is a base of x */ - - if (b_v == NO_VERTEX) - { - /* Originally 0 instead of NO_VERTEX */ - - /* Important note: following "A. Note of Implementing the Algorithm" from the - article by Kocay and Stone, all references to PrevPt[a] have been - replaced with SwitchEdge[a][0]=SwitchEdge_Vert1(a); to be on a safe side - the check whether (SwitchEdge_Vert2(a)==a) has been added. - */ - - /* v is not yet in T or T' -- add it to T and M */ - /*PrevPt[v] = u; ** this effectively adds v to T and v' to T' */ - - QSize++; - ScanQ[QSize] = v; - TREE_MARK( v, TREE_IN_1 ); /* mark v s-reachable (in T) */ - TREE_MARK( prim( v ), TREE_IN_2 ); /* mark v' in T' */ - - /* Switch Edges: If u in T then Pu (a valid su-path) can be constructed - by successfully executing u=PrevPt[u] until u=s. - For vertices in T' the situation is different. - Suppose uv and v'u' are added to a mirror network M creating a blossom: - - s T (Note: in the code v' is prim(v), - T / \ u' is prim(u), etc.) - / ... - w=x1 - / \ u in T, v in T' - u=y2 v'=y3 - \ / <--- two added edges uv and (uv)'=v'u' - -------- X ------------intersection of the edges ------------------------ - / \ <--- (the edges intersection in the picture is shown as X) - u'=x2 v=x3 u' it T', v' in T - \ / - T' w'=y1 - \ ... - \ / - t T' - - Vertices v and u' now become s-reachable; - The valid paths to v and u' must use the edges uv and v'u' respectively. - - For each vertex z in S we define a switch-edge that allows a valid sz-path - to be constructed, SwitchEdge[v]=uv and SwitchEdge[u']=v'u'. (We don't - know the direction of the edge uv, it may be (u,v) or (v,u). In either case, - the complementary edge is indicated by v'u'). - - Vertex w' also becomes s-reachable when uv is added to M, and a valid sw'-path - must use one of uv and v'u'. Therefore we choose one of them, say uv (see below - the rule of choosing the switch-edge), and define SwitchEdge[w'] = uv. - - When the addition of an edge uv to M causes a vertex z to become s-reachable - (where z was previously non-reachable), z is placed on the ScanQ, that is, into S. - The edge uv is said to be a switch-edge for z. - - Rule: We choose the the order of the vertices uv to be such that the valid sz-path - consists of a valid su-path, followed by edge uv, followed by a valid vz-path. - - For vertices z in T we can take SwitchEdge[z]=yz where y=PrevPt[z] since - it is the edge yz that allows z to be s-reachable. - For vertices z not in S we take SwitchEdge[z]=NONE. - - */ - - /* v is not yet in T or T' -- add it to T and M */ - SwitchEdge_Vert1( v ) = u; /* this effectively adds uv and v'u' to M */ - SwitchEdge_IEdge( v ) = iuv; - - BasePtr[prim( v )] = v; - BasePtr[v] = BLOSSOM_BASE; /* create a trivial blossom C(v) with base v */ -#if ( BNS_RAD_SEARCH == 1 ) - n++; -#endif - } - - else if (TREE_IS_S_REACHABLE( prim( v ) ) /*Is_s_Reachable(prim(v)*/ - /* if v' is reachable, an st-path is given by P(u)-uv-P'(v') */ - /*&& PrevPt[prim(u)] != prim(v) ** avoid edges of T' */ - && ( SwitchEdge_Vert1( prim( u ) ) != prim( v ) || SwitchEdge_Vert2( prim( u ) ) != prim( u ) ) /* avoid edges of T' */ - && b_u != b_v - && !( pBNS->type_TACN && bIgnoreVertexNonTACN_group( pBNS, prim( v ), u, SwitchEdge ) ) -#if ( FIX_KEEP_H_ON_NH_ANION == 1 ) - && !( pBNS->type_TACN && bIsRemovedHfromNHaion( pBNS, prim( v ), u ) ) -#endif - ) - { -#if ( BNS_RAD_SEARCH == 1 ) - n++; -#endif - /* There is now a valid sv-path via u avoiding b_v (unless v==b_v) - => u, v, u', and v' now all become part of the same connected component of M[C] */ - - if (b_u < 0) /* djb-rwth: fixing coverity CID #499578 */ - { - return BNS_WRONG_PARMS; - } - - w = MakeBlossom( pBNS, ScanQ, &QSize, Pu, Pv, max_len_Pu_Pv, SwitchEdge, BasePtr, u, v, iuv, b_u, b_v, Tree ); - /* this constructed the new blossom and returned its base */ - - if (IS_BNS_ERROR( w )) - { - pBD->QSize = QSize; - return w; /* error */ - } - - b_u = w; /* the new base of C(u) */ - if (prim( w ) == Vertex_t) - { - /* t is now s-reachable, a valid augmenting path P exists in M */ - delta = FindPathCap( pBNS, SwitchEdge, Vertex_s, Vertex_t, 10000 ); /* compute the residual capacity of P + P' */ - if (IS_BNS_ERROR( delta )) - { - pBD->QSize = QSize; - return delta; /* error */ - } -#if ( ALLOW_ONLY_SIMPLE_ALT_PATH == 1 ) - if (pBNS->bNotASimplePath || abs( delta ) > 1) - { - delta = 0; - } -#endif - if (delta) - { - pBNS->bChangeFlow |= ( bChangeFlow & BNS_EF_CHNG_FLOW ); - } - ret = PullFlow( pBNS, SwitchEdge, Vertex_s, Vertex_t, delta, 0, bChangeFlow ); /* augment on a pair of valid st-paths */ - pBD->QSize = QSize; - return - ( IS_BNS_ERROR( ret ) ? ret : delta ); - } - } - } - - else if (IS_BNS_ERROR( ret )) - { - pBD->QSize = QSize; - return ret; /* error */ - } - } - -#if ( BNS_RAD_SEARCH == 1 ) - if (bRadSearch && !n) - { - /* The BNS stopped at u */ - n = RegisterRadEndpoint( pBNS, pBD, u ); - if (IS_BNS_ERROR( n )) - { - pBD->QSize = QSize; - return n; - } - } -#endif - - k++; /* advance ScanQ */ - } while (k <= QSize); - - - /* if this point is reached, no valid augmenting path exists, ScanQ contains - the set S of all s-reachable vertices and K=[S,S-] is a minimum balanced edge-cut */ - /* ClearFlowMarks( vert, num_vert); */ - - pBD->QSize = QSize; - - return 0; -} - - -/* -Blossoms. - -The vertices of a mirror network M consist T U T'. Intersection T ^ T' is empty. - -The edges of M consist of switch-edges and their complements because edges -are added in complementary pairs, one of which is always a switch-edge. - -The base of every blossom is in T. -Let C(i) be a blossom with base b_i. Since C(i)=C(i)', C(i) contains vertices of T and T'. -Since every valid sv-path to v in C(i) contains b_i, b_i is the first s-reachable vertex of C(i). - -Suppose the mirror network M contains a valid sz-path P(z) to all vertices z in ScanQ. -Every vertex of P(z) is s-reachable therefore its vertices are all in blossoms or -trivial blossoms. - -Let z be an s-reachable vertex and P(z) be a valid path in M. -Then every valid sz-path in M contains exactly the same sequence of blossom bases as P(z). - -*/ - - - -/*********************************************************************** -BasePtr[u] = -2 NO_VERTEX u is not a blossom --1 BLOSSOM_BASE u is the base of its blossom -v a vertex closer to the base -************************************************************************/ -Vertex FindBase( Vertex u, Vertex *BasePtr ) -{ - if (BasePtr[u] == NO_VERTEX) - { - return NO_VERTEX; - } - else if (BasePtr[u] == BLOSSOM_BASE) - { - return u; - } - else - { - Vertex b; - b = FindBase( BasePtr[u], BasePtr ); - BasePtr[u] = b; /* path compression */ - return b; - } - -} - - -/**************************************************************************** -Returns index of the last path element and the path -****************************************************************************/ -int FindPathToVertex_s( Vertex x, - Edge *SwitchEdge, - Vertex *BasePtr, - Vertex *Path, - int MaxPathLen ) -{ - /* x is the base of a blossom, construct a valid Path of blossom bases to s */ - int i = 0; - Path[i] = x; - while (x != Vertex_s) - { - x = FindBase( SwitchEdge_Vert1( x ), BasePtr ); - if (++i < MaxPathLen) - { - Path[i] = x; - } - else - { - return BNS_WRONG_PARMS; - } - } - - return i; -} - - - -/**************************************************************************** -Make a blossom -****************************************************************************/ -Vertex MakeBlossom( BN_STRUCT* pBNS, - Vertex *ScanQ, - int *pQSize, - Vertex *Pu, - Vertex *Pv, - int max_len_Pu_Pv, - Edge *SwitchEdge, - Vertex *BasePtr, - Vertex u, - Vertex v, - EdgeIndex iuv, - Vertex b_u, - Vertex b_v, - S_CHAR *Tree ) -{ - /* In order to find the base of the new blossom, the paths - P(u) and P(v') are constructed and compared in order to - find the last blossom base they have in common which - is reachable on a valid path. - - Edge uv connects two blossoms, their bases are b_u and b_v. - */ - Vertex w, z; - int len_Pu, len_Pv; - int i, j, k; - EdgeIndex izw; - - len_Pu = FindPathToVertex_s( b_u, SwitchEdge, BasePtr, Pu, max_len_Pu_Pv ); - if (IS_BNS_ERROR( len_Pu )) - { - return len_Pu; - } - len_Pv = FindPathToVertex_s( b_v, SwitchEdge, BasePtr, Pv, max_len_Pu_Pv ); - if (IS_BNS_ERROR( len_Pv )) - { - return len_Pv; - } - i = len_Pu; - j = len_Pv; - /* Initially Pu[i] and Pv[j] both equal to s, but their first elements are different */ - /* Find the last blossom base common to Pu and Pv */ - while (i >= 0 && j >= 0 && Pu[i] == Pv[j]) - { - /* Was (Pu[i]==Pv[j] && i>=0 && j>=0) => tested Pu[-1], Pv[-1] <- pointed by W.Ihlenfeldt 08-26-2004*/ - i--; - j--; - } - i++; - w = Pu[i]; /* w is the last common vertex */ - z = SwitchEdge_Vert1( w ); - izw = SwitchEdge_IEdge( w ); - /* now extend the blossom if rescap(zw) >= 2 */ - while (w != Vertex_s && rescap( pBNS, z, w, izw ) >= 2) - { - i++; - w = Pu[i]; - z = SwitchEdge_Vert1( w ); - izw = SwitchEdge_IEdge( w ); - } - /* w is the base of the new blossom */ - /* first follow the path Pu from w to b_u */ - for (k = i - 1; k >= 0; k--) - { - z = Pu[k]; /* z is the base of the blossom */ - BasePtr[z] = w; - BasePtr[prim( z )] = w; /* w is the new base of the blossom */ - /* z and z' may already be part of a blossom that is being - swallowed into a larger blossom. - We don't want to change the switch edge in that case. - */ - - if (!TREE_IS_ON_SCANQ( prim( z ) ) /*!IsInScanQ(prim(z)) */) - { - SwitchEdge_Vert1( prim( z ) ) = prim( v ); /* set the switch edge of z' */ - /* SwitchEdge[prim(z)][1] = prim(u); */ - SwitchEdge_IEdge( prim( z ) ) = iuv; - ( *pQSize )++; - ScanQ[*pQSize] = prim( z ); /* add z' to ScanQ */ - TREE_MARK( prim( z ), TREE_IN_2BLOSS ); /* mark z' s-reachable */ - } - } - /* Now follow the path Pv */ - for (k = j; k >= 0; k--) /* djb-rwth: converting for loop into while loop to avoid LLVM warning */ - { - z = Pv[k]; /* z is the base of the blossom */ - BasePtr[z] = w; - BasePtr[prim( z )] = w; /* w is the new base of the blossom */ - /* z and z' may already be part of a blossom that is being - swallowed into a larger blossom. - We don't want to change the switch edge in that case. - */ - - if (!TREE_IS_ON_SCANQ( prim( z ) ) /*!IsInScanQ(prim(z)) */) - { - SwitchEdge_Vert1( prim( z ) ) = u; /* set the switch edge of z' */ - /* SwitchEdge[prim(z)][1] = v; */ - SwitchEdge_IEdge( prim( z ) ) = iuv; - ( *pQSize )++; - ScanQ[*pQSize] = prim( z ); /* add z' to ScanQ */ - TREE_MARK( prim( z ), TREE_IN_2BLOSS ); /* mark z' s-reachable */ - } - } - - if (!TREE_IS_ON_SCANQ( prim( w ) ) /* !IsInScanQ(prim(w))*/) - { /* add w' to the blossom */ - SwitchEdge_Vert1( prim( w ) ) = u; /* set the switch edge of w' */ - /* SwitchEdge[prim(w)][1] = v; */ - SwitchEdge_IEdge( prim( w ) ) = iuv; - ( *pQSize )++; - ScanQ[*pQSize] = prim( w ); /* add w' to ScanQ */ - TREE_MARK( prim( w ), TREE_IN_2BLOSS ); /* mark w' s-reachable */ - } - - return w; -} - - -/**************************************************************************** -When t is found to be s-reachable, a valid st-path P is known to exist. -Its complementary path P' is also valid. Once the residual capacity -delta(P) is known, the flow is augmented by calling PullFlow(s,t,delta). -It constructs the path P by using the switch-edges. -Let uv=SwitchEdge[t]. -Then P is given by a valid su-path, followed by the edge uv, followed by -a valid vt-path. -PullFlow is a recursive procedure that constructs the path and its complement. - -Let wz=SwitchEdge[y]. PullFlow(x, y, delta) uses the xw- and zy-portions of P -(see below). Since it must also augment on P' simultaneously, the zy-portion -is replaced by the y'z'-portion. - -x y' -| | P: x--w--z--y -P | | P' P': y'-z'-w'-x' -| o -o \ -/ w' z \ -/ o----\ /----o / -\ / \ / \ / -\/ X \/ -/\ / \ /\ -/ \ w / \ z' / \ -\ o---- ----o / Using a switch-edge wz and w'z' -\ / to construct P and P' -o o -| | -| | -x' y - - -****************************************************************************/ - - - -/* PullFlow( ... ) - -Augment the flow by delta on all edges on a path P -between x and y in the order of the path; -AugmentEdge( pBNS, w, z, iwz, delta, 0 ) means the path is in w->z direction -AugmentEdge( pBNS, w, z, iwz, delta, 1 ) means the path is in w<-z direction - -Unlike PullFlow in the paper by Kocay & Stone, here the augmentation -starts at "s", proceeds sequentially through the path end terminates at "t". -Since we do not really need the complement path, PullFlow ignores it. -*/ - - -/****************************************************************************/ -int PullFlow( BN_STRUCT *pBNS, - Edge *SwitchEdge, - Vertex x, - Vertex y, - int delta, - S_CHAR bReverse, - int bChangeFlow ) -{ - Vertex w, z; - EdgeIndex iwz; - int ret = 0; - - w = SwitchEdge_Vert1( y ); - z = SwitchEdge_Vert2( y ); - iwz = SwitchEdge_IEdge( y ); - if (bReverse) - { - /* P consists of a path from x to w, then wz, then a path from z to y. */ - /* z may equal y, in which case z is just PrevPt[y] */ - if (z != y) - { - ret = PullFlow( pBNS, SwitchEdge, prim( y ), prim( z ), delta, (S_CHAR) ( 1 - bReverse ), bChangeFlow ); /* augment between z and y */ - } - if (!IS_BNS_ERROR( ret )) - { - ret = AugmentEdge( pBNS, w, z, iwz, delta, bReverse, bChangeFlow ); - } - /* Do not augment the complementary path: AugmentEdge( prim(z), prim(w), vert, delta); */ - /* w may equal x, in which case there is no need to call PullFlow(x, w) */ - if (w != x && !IS_BNS_ERROR( ret )) - { - ret = PullFlow( pBNS, SwitchEdge, x, w, delta, bReverse, bChangeFlow ); /* augment between x and w */ - } - } - else - { - /* P consists of a path from x to w, then wz, then a path from z to y. */ - /* w may equal x, in which case there is no need to call PullFlow(x, w) */ - if (w != x && !IS_BNS_ERROR( ret )) - { - ret = PullFlow( pBNS, SwitchEdge, x, w, delta, bReverse, bChangeFlow ); /* augment between x and w */ - } - if (!IS_BNS_ERROR( ret )) - { - ret = AugmentEdge( pBNS, w, z, iwz, delta, bReverse, bChangeFlow ); - } - /* z may equal y, in which case z is just PrevPt[y] */ - if (z != y && !IS_BNS_ERROR( ret )) - { - ret = PullFlow( pBNS, SwitchEdge, prim( y ), prim( z ), delta, (S_CHAR) ( 1 - bReverse ), bChangeFlow ); /* augment between z and y */ - } - } - - return ret; -} - - -/**************************************************************************** -Before augmenting on the two paths, it is necessary to find delta(P). -This can be done by following the paths and computing the minimum -residual capacity of all edges on P. An edge on both P and P' counts -for only half of its actual residual capacity, since augmentng on P by -delta will simutaneously reduce its capacity on P' by delta. -The path P can only be followed by using the switch-edges, as in PullFlow(...). -FindPathCap( x, y, delta ) is a recursive procedure that finds the residual -capacity on the portion of P between x and y. delta is the minimum capacity -found so far along the path. -****************************************************************************/ - - -/**************************************************************************** -Find the minimum residual capacity of all edges -between x and y in a valid st-path P. -delta is the minimum found so far -the vertices occur in order s,...,x,...,y,...,t along P -the vertices occur in order s,...,y',...,x',...,t along P' -****************************************************************************/ -int FindPathCap( BN_STRUCT* pBNS, Edge *SwitchEdge, Vertex x, Vertex y, int delta ) -{ - - Vertex w, z, iwz; - int cap, delta2; - - /* static int level; - if ( level ++ > 50 ) - { - #ifdef _DEBUG - int stop = 1; - #else - ; - #endif - } - */ - - w = SwitchEdge_Vert1( y ); - z = SwitchEdge_Vert2( y ); /* wz is on the path P */ - iwz = SwitchEdge_IEdge( y ); /* edge index */ - - /* Rescap_mark() detects edges passed 2 times and reduces rescap */ - cap = rescap_mark( pBNS, w, z, iwz ); - - if (IS_BNS_ERROR( cap )) - { - /* level --; */ - return cap; - } - if (cap < delta) - { - delta = cap; - } - /* P consists of a path from x to w, then wz, then a path from z to y */ - if (w != x) - { - delta2 = FindPathCap( pBNS, SwitchEdge, x, w, delta ); - delta = inchi_min( delta2, delta ); - } - if (z != y) - { - delta2 = FindPathCap( pBNS, SwitchEdge, prim( y ), prim( z ), delta ); - delta = inchi_min( delta2, delta ); - } - /* level --; */ - - return delta; -} - - -/* -BT = bond types -*/ - - -#define BT_ALTERN_BOND 1 /* 1-2, possibly stereo */ -#define BT_OTHER_ALTERN_BOND 2 /* 1-3, 2-3, 1-2-3 alternating non-stereo non-taut bonds */ - -#define BT_ALTERN_NS_BOND 4 - -#define BT_TAUTOM_BOND 8 - -#define BT_ALTERN_UNKN_BOND 16 - -#define BT_IGNORE_BOND 0 - -#define BT_NONSTEREO_MASK (BT_TAUTOM_BOND|BT_ALTERN_NS_BOND) - -#define BT_ALT_BOND_MASK (BT_ALTERN_BOND|BT_OTHER_ALTERN_BOND) - -#define BT_NONTAUT_BOND_MASK (BT_ALTERN_BOND|BT_OTHER_ALTERN_BOND|BT_ALTERN_NS_BOND) - -/* BNS members redefinitions for finding non-stereo bonds */ -/* BNS_EDGE */ -#define nBlockNumberAltBns flow /* internal variable of the DFS traversal: mark traversed bonds */ -#define nNumAtInBlockAltBns cap -#define nBondTypeInpAltBns pass /* 0=>cannot be stereo at all, 1=>alt or taut non-stereo, 2=>can be stereo */ -#define nBondNonStereoAltBns cap /* 1=>found to be non-stereogenic although BondTypeInp=2; 0=>as in BondTypeInp */ - -#if ( BNS_MARK_ONLY_BLOCKS == 1 ) /* { */ -/* BNS_VERTEX */ -#define bCutVertexAltBns st_edge.cap0 /* cut-vertex flag */ -#define nRingSystemAltBns st_edge.cap /* ordering number of a ring system */ -#define nNumAtInRingSystemAltBns st_edge.flow0 /* number of vertices in a ring system */ -#define nBlockSystemAltBns st_edge.flow /* result of the DFS traversal: even cirquit must be within one block */ - -#endif /* } */ - -#define valenceAltBns num_adj_edges - - -/****************************************************************************/ -int MarkRingSystemsAltBns( BN_STRUCT* pBNS, int bUnknAltAsNoStereo ) -{ - AT_NUMB *nStackAtom = NULL; - int nTopStackAtom; - AT_NUMB *nRingStack = NULL; - int nTopRingStack; /* was AT_NUMB */ - AT_NUMB *nBondStack = NULL; - int nTopBondStack; - AT_NUMB *nDfsNumber = NULL; - AT_NUMB *nLowNumber = NULL; - S_CHAR *cNeighNumb = NULL; - AT_NUMB nDfs; - AT_NUMB nNumAtInRingSystem; - int i, j, u, w, start, nNumRingSystems; /* djb-rwth: removing redundant variables */ - BNS_VERTEX *at = pBNS->vert; - BNS_EDGE *bond = pBNS->edge; - int num_atoms = pBNS->num_atoms; - int num_edges = pBNS->num_bonds; - - /* Allocate arrays */ - nStackAtom = (AT_NUMB *) inchi_malloc( num_atoms * sizeof( nStackAtom[0] ) ); - nRingStack = (AT_NUMB *) inchi_malloc( num_atoms * sizeof( nRingStack[0] ) ); - nDfsNumber = (AT_NUMB *) inchi_malloc( num_atoms * sizeof( nDfsNumber[0] ) ); - nLowNumber = (AT_NUMB *) inchi_malloc( num_atoms * sizeof( nLowNumber[0] ) ); - nBondStack = num_edges ? ( (AT_NUMB *) inchi_malloc( num_edges * sizeof( nBondStack[0] ) ) ) : (AT_NUMB *) ( NULL ); /* special case: no bonds 2006-03 */ - cNeighNumb = (S_CHAR *) inchi_malloc( num_atoms * sizeof( cNeighNumb[0] ) ); - - /* Check allocation */ - if (!nStackAtom || !nRingStack || !nDfsNumber || !nLowNumber || (!nBondStack && num_edges) || !cNeighNumb - ) /* djb-rwth: addressing LLVM warning */ - { - nNumRingSystems = CT_OUT_OF_RAM; /* program error */ /* */ - goto exit_function; - } - - /******************************************** - * - * Find Cut-vertices & Blocks - * - * 1\ /5 has 3 blocks (maximal subgraphs that - * Example: | >3--4< | are nonseparable by deleting a single vertex): - * 2/ \6 (1,2,3, has 3 bonds), (3,4, has 1 bond), and (4,5,6, has 3 bonds) - * - * Cut-vertices or articulation points are - * intersections of the blocks: points 3 and 4. - ********************************************/ - - /******************************************************** - - RingSystemAlt are atoms connected by alternating bonds - (as must be indicated in bIsAltBond()): - - BOND_ALTERN - BOND_ALT_123 - BOND_ALT_13 - BOND_ALT_23 - - Since other bonds may be present, we possibly need - to restart to move to another component - *********************************************************/ - - nNumRingSystems = 0; - memset( nDfsNumber, 0, num_atoms * sizeof( nDfsNumber[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - - for (start = 0; start < num_atoms; start++) - { - if (nDfsNumber[start]) - { - continue; - } - for (i = 0; i < at[start].valenceAltBns; i++) - { - if (bond[at[start].iedge[i]].nBondTypeInpAltBns & BT_ALTERN_BOND) - goto found_alt; - } - continue; - - found_alt: - - /* Initiation */ - u = start; /* start atom */ - nDfs = 0; - nTopStackAtom = -1; - nTopRingStack = -1; - nTopBondStack = -1; - memset( cNeighNumb, 0, num_atoms * sizeof( cNeighNumb[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ - /* Push the start atom on the stack */ - nLowNumber[u] = nDfsNumber[u] = ++nDfs; - nStackAtom[++nTopStackAtom] = (AT_NUMB) u; - nRingStack[++nTopRingStack] = (AT_NUMB) u; - - /* djb-rwth: removing redundant code */ - - do - { - /* advance */ - /*while ( (int)at[i=nStackAtom[nTopStackAtom]].valenceAltBns > (j = (int)cNeighNumb[i]) )*/ - /* replaced due to missing sequence point */ - while (i = (int) nStackAtom[nTopStackAtom], j = (int) cNeighNumb[i], (int) at[i].valenceAltBns > j) - { - cNeighNumb[i] ++; - if (!( bond[w = at[i].iedge[j]].nBondTypeInpAltBns & BT_ALT_BOND_MASK )) - { - continue; - } - u = (int) ( bond[at[i].iedge[j]].neighbor12 ^ i ); - if (!nDfsNumber[u] && nBondStack) /* djb-rwth: fixing a NULL pointer dereference */ - { - /* tree edge, 1st visit -- advance */ - nStackAtom[++nTopStackAtom] = (AT_NUMB) u; - nRingStack[++nTopRingStack] = (AT_NUMB) u; - nBondStack[++nTopBondStack] = (AT_NUMB) w; - nLowNumber[u] = nDfsNumber[u] = ++nDfs; - /* djb-rwth: removing redundant code */ - } - else - { - if (!nTopStackAtom || u != (int) nStackAtom[nTopStackAtom - 1]) - { /* may comment out ? */ - /* back edge: u is not a predecessor of i */ - if ((nDfsNumber[u] < nDfsNumber[i]) && nBondStack) /* djb-rwth: fixing a NULL pointer dereference */ - { - /* Back edge, 1st visit: u is ancestor of i. Save and compare */ - nBondStack[++nTopBondStack] = (AT_NUMB) w; - if (nLowNumber[i] > nDfsNumber[u]) - { - nLowNumber[i] = nDfsNumber[u]; - } - } - } - } - } - cNeighNumb[i] = 0; - - /* Back up */ - if (i != start) - { - u = (int) nStackAtom[nTopStackAtom - 1]; /* predecessor of i */ - if (nLowNumber[i] >= nDfsNumber[u]) - { - /* Output the block; the block was entered through its first bond u->i */ - nNumRingSystems++; - /*at[u].nBlockSystemAltBns = nNumRingSystems;*/ /* mark the atom */ - nNumAtInRingSystem = 1; - /* - if ( u != start || nNumStartChildren > 1 ) { - at[u].bCutVertexAltBns += 1; // mark cut-vertex (articulation point) - } - */ - while (nTopRingStack >= 0) - { - j = nRingStack[nTopRingStack--]; - /*at[j].nBlockSystemAltBns = nNumRingSystems;*/ /* mark the atom */ - nNumAtInRingSystem++; - if (i == j) - { - break; - } - } - while (nTopBondStack >= 0) - { - w = nBondStack[nTopBondStack--]; - bond[w].nBlockNumberAltBns = nNumRingSystems; /* mark the bond */ - bond[w].nNumAtInBlockAltBns = nNumAtInRingSystem; - if ((i == bond[w].neighbor1 && u == ( i ^ bond[w].neighbor12 )) || - (u == bond[w].neighbor1 && i == ( u ^ bond[w].neighbor12 ))) /* djb-rwth: addressing LLVM warning */ - { - break; - } - } - } - else - { - if (nLowNumber[u] > nLowNumber[i]) - { - /* inherit */ - nLowNumber[u] = nLowNumber[i]; - } - } - } - } while (--nTopStackAtom >= 0); - } - -#if ( BNS_MARK_ONLY_BLOCKS != 1 ) /* { */ - - /******************************************** - * - * Find Ring Systems - * Including chain atoms X: A-X-B, where the bonds (of any kind) are bridges. - * - ********************************************/ - - /* Initiation */ - nNumRingSystems = 0; - for (start = 0; start < num_atoms; start++) - { - if (at[start].nRingSystemAltBns) - { - continue; - } - for (i = 0; i < at[start].valenceAltBns; i++) - { - if (bond[at[start].iedge[i]].nBondTypeInpAltBns & BT_ALT_BOND_MASK) - { - goto found_alt2; - } - } - continue; - - found_alt2: - u = start; /* start atom */ - nDfs = 0; - nTopStackAtom = -1; - nTopRingStack = -1; - memset( nDfsNumber, 0, num_atoms * sizeof( nDfsNumber[0] ) ); - memset( cNeighNumb, 0, num_atoms * sizeof( cNeighNumb[0] ) ); - /* push the start atom on the stack */ - nLowNumber[u] = nDfsNumber[u] = ++nDfs; - nStackAtom[++nTopStackAtom] = (AT_NUMB) u; - nRingStack[++nTopRingStack] = (AT_NUMB) u; - - do - { - /* advance */ - advance_ring: - /*if ( (int)at[i=nStackAtom[nTopStackAtom]].valenceAltBns > (j = (int)cNeighNumb[i]) )*/ - /* replaced due to missing sequence point */ - if (i = (int) nStackAtom[nTopStackAtom], j = (int) cNeighNumb[i], (int) at[i].valenceAltBns > j) - { - cNeighNumb[i] ++; - if (!( bond[at[i].iedge[j]].nBondTypeInpAltBns & BT_ALTERN_BOND )) - { - goto advance_ring; - } - u = (int) ( bond[at[i].iedge[j]].neighbor12 ^ i ); - if (!nDfsNumber[u]) - { - /* tree edge, 1st visit -- advance */ - nStackAtom[++nTopStackAtom] = (AT_NUMB) u; - nRingStack[++nTopRingStack] = (AT_NUMB) u; - nLowNumber[u] = nDfsNumber[u] = ++nDfs; - } - else - { - if (!nTopStackAtom || u != (int) nStackAtom[nTopStackAtom - 1]) - { - /* back edge: u is not a predecessor of i */ - if (nDfsNumber[u] < nDfsNumber[i]) - { - /* Back edge, 1st visit: u is ancestor of i. Compare */ - if (nLowNumber[i] > nDfsNumber[u]) - { - nLowNumber[i] = nDfsNumber[u]; - } - } - } - } - goto advance_ring; - } - else - { - cNeighNumb[i] = 0; - } - - /* Back up */ - if (nDfsNumber[i] == nLowNumber[i]) - { - /* Found a ring system */ - nNumRingSystems++; - - /* Unwind nRingStack[] down to i */ - - /* Count atoms in a ring system */ - for (nNumAtInRingSystem = 0, j = nTopRingStack; 0 <= j; j--) - { - nNumAtInRingSystem++; - if (i == (int) nRingStack[j]) - { - break; - } - } - while (nTopRingStack >= 0) - { - j = (int) nRingStack[nTopRingStack--]; - at[j].nRingSystemAltBns = (AT_NUMB) nNumRingSystems; /* ring system id */ - at[j].nNumAtInRingSystemAltBns = nNumAtInRingSystem; - if (i == j) - { - /* Reached atom on the top of nStackAtom[] stack */ - break; - } - } - } - else - { - if (nTopStackAtom > 0) - { - j = (int) nStackAtom[nTopStackAtom - 1]; - /* inherit nLowNumber */ - if (nLowNumber[j] > nLowNumber[i]) - { - nLowNumber[j] = nLowNumber[i]; - } - } - } - } while (--nTopStackAtom >= 0); - } - -#endif /* } BNS_MARK_ONLY_BLOCKS != 1 */ - -exit_function: - if (nStackAtom) - { - inchi_free( nStackAtom ); - } - if (nRingStack) - { - inchi_free( nRingStack ); - } - if (nDfsNumber) - { - inchi_free( nDfsNumber ); - } - if (nLowNumber) - { - inchi_free( nLowNumber ); - } - if (nBondStack) - { - inchi_free( nBondStack ); - } - if (cNeighNumb) - { - inchi_free( cNeighNumb ); - } - - return nNumRingSystems; -} - - -/****************************************************************************/ -int ReInitBnStructForAltBns( BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - int bUnknAltAsNoStereo ) -{ - Vertex v, v2; - int ret, bond_type, num_to_test, j; - BNS_EDGE *pBond; - BNS_VERTEX *pAtom; - - /* Strip all t-groups and c-groups */ - num_to_test = 0; - if (bUnknAltAsNoStereo) - { - for (j = 0; j < pBNS->num_edges; j++) - { - pBNS->edge[j].pass = 0; - } - } - - ret = ReInitBnStruct( pBNS, at, num_atoms, 0 ); - - if (ret || pBNS->num_atoms != num_atoms || pBNS->num_vertices != num_atoms || pBNS->num_bonds != pBNS->num_edges) - { - ret = BNS_REINIT_ERR; - goto exit_function; - } - - /* Eliminate bonds and fix st-caps */ - for (v = 0; v < num_atoms; v++) - { - pAtom = pBNS->vert + v; - for (j = 0; j < pAtom->valenceAltBns; j++) - { - pBond = pBNS->edge + pAtom->iedge[j]; - if (pBond->neighbor1 == v) - { - bond_type = ( at[v].bond_type[j] & BOND_TYPE_MASK ); - v2 = pBond->neighbor12 ^ v; - if (at[v].endpoint || at[v2].endpoint) - { - bond_type = 0; /* any bond to an endpoint considered non-stereogenic */ - } -#if ( FIX_EITHER_DB_AS_NONSTEREO == 1 ) - if (bUnknAltAsNoStereo) - { - if (bond_type == BOND_ALTERN && at[v].bond_stereo[j] == STEREO_DBLE_EITHER) - { - bond_type = 0; /* treat unknown (Either) ALT bond as non-stereo */ - } - } -#endif - switch (bond_type) - { - - case BOND_ALTERN: - pBond->nBondTypeInpAltBns = BT_ALTERN_BOND; - num_to_test++; - break; - - case BOND_ALT_123: - case BOND_ALT_13: - case BOND_ALT_23: - pBond->nBondTypeInpAltBns = BT_OTHER_ALTERN_BOND; - break; - - case BOND_TAUTOM: - pBond->nBondTypeInpAltBns = BT_TAUTOM_BOND; - break; - - case BOND_ALT12NS: - pBond->nBondTypeInpAltBns = BT_ALTERN_NS_BOND; - break; - - case 0: - case BOND_SINGLE: - case BOND_DOUBLE: - case BOND_TRIPLE: - pBond->nBondTypeInpAltBns = BT_IGNORE_BOND; - break; - - default: - pBond->nBondTypeInpAltBns = BT_IGNORE_BOND; - break; - } - pBond->nBondNonStereoAltBns = 0; /* djb-rwth: addressing GCC warning -- operations on pBond->cap might be undefined */ - pBond->nBlockNumberAltBns = 0; - pBond->nNumAtInBlockAltBns = 0; - -#if ( RESET_EDGE_FORBIDDEN_MASK == 1 ) - pBond->forbidden &= pBNS->edge_forbidden_mask; -#endif - } - } - pAtom->bCutVertexAltBns = - pAtom->nRingSystemAltBns = - pAtom->nNumAtInRingSystemAltBns = - pAtom->nBlockSystemAltBns = 0; - } - - return num_to_test; - -exit_function: - - return ret; -} - - -/****************************************************************************/ -int MarkNonStereoAltBns( BN_STRUCT *pBNS, - inp_ATOM *at, - int num_atoms, - int bUnknAltAsNoStereo ) -{ - int num_bonds = pBNS->num_bonds; - int ret; - int ibond, ib1, ib2; - BNS_EDGE *pBond; - Vertex iat1, iat2; - - ret = 0; - - if (pBNS->num_atoms != num_atoms || pBNS->num_vertices != num_atoms || pBNS->num_bonds != pBNS->num_edges) - { - ret = BNS_REINIT_ERR; - goto exit_function; - } - if (bUnknAltAsNoStereo) - { - for (ibond = 0; ibond < num_bonds; ibond++) - { - pBond = pBNS->edge + ibond; - if (pBond->nBondTypeInpAltBns != BT_ALTERN_BOND && pBond->nBondTypeInpAltBns != BT_IGNORE_BOND) - { - continue; - } - iat1 = pBond->neighbor1; - iat2 = pBond->neighbor12 ^ iat1; - ib1 = pBond->neigh_ord[0]; - ib2 = pBond->neigh_ord[1]; - if ( /* alt bond non-adjacent to a taut. endpoint: */ - ( pBond->nBondTypeInpAltBns == BT_ALTERN_BOND && - pBond->nNumAtInBlockAltBns <= 3 ) /* non-ring bond */ || - /* alt bond adjacent to a taut. endpoint: */ - ( pBond->nBondTypeInpAltBns == BT_IGNORE_BOND && - ( at[iat1].bond_type[ib1] & BOND_TYPE_MASK ) == BOND_ALTERN ) - ) - { - if (( at[iat1].bond_type[ib1] & BOND_TYPE_MASK ) == BOND_ALTERN) - { - /* bond_type = BOND_ALT12NS; */ - at[iat1].bond_stereo[ib1] = - at[iat2].bond_stereo[ib2] = STEREO_DBLE_EITHER; - ret++; - } - } - } - } - else - { - for (ibond = 0; ibond < num_bonds; ibond++) - { - pBond = pBNS->edge + ibond; - if (pBond->nBondTypeInpAltBns != BT_ALTERN_BOND && pBond->nBondTypeInpAltBns != BT_IGNORE_BOND) - { - continue; - } - iat1 = pBond->neighbor1; - iat2 = pBond->neighbor12 ^ iat1; - ib1 = pBond->neigh_ord[0]; - ib2 = pBond->neigh_ord[1]; - if ( /* alt bond non-adjacent to a taut. endpoint: */ - ( pBond->nBondTypeInpAltBns == BT_ALTERN_BOND && - pBond->nNumAtInBlockAltBns <= 3 ) /* non-ring bond */ || - /* alt bond adjacent to a taut. endpoint: */ - ( pBond->nBondTypeInpAltBns == BT_IGNORE_BOND && - ( at[iat1].bond_type[ib1] & BOND_TYPE_MASK ) == BOND_ALTERN ) - ) - { - at[iat1].bond_type[ib1] = - at[iat2].bond_type[ib2] = BOND_ALT12NS; - ret++; - } - } - } - -exit_function: - - return ret; -} - - -#if ( READ_INCHI_STRING == 1 ) -/*****************************************************************************/ -#ifndef RI_ERR_ALLOC -/* from ichirvrs.h */ -#define RI_ERR_ALLOC (-1) -#define RI_ERR_SYNTAX (-2) -#define RI_ERR_PROGR (-3) -#endif - - -/**************************************************************************** -Check if atom bonded to charged atom -****************************************************************************/ -int bHasChargedNeighbor( inp_ATOM *at, int iat ) -{ - int i; - for (i = 0; i < at[iat].valence; i++) - { - if (at[(int) at[iat].neighbor[i]].charge) - { - return 1; - } - } - - return 0; -} - - -/**************************************************************************** -Add or remove protons - -*num_protons_to_add = nToBeRemovedByNormFromRevrs - -nToBeRemovedByNormFromRevrs > 0: less protons should be allowed to be -added by the Normalization of the Reconstructed Structure -nToBeRemovedByNormFromRevrs < 0: prepare more H(+) to be removed by -the InChI Normalization of the Reconstructed Structure - -OrigStruct -> NormOrig + n(orig)*H(+) -RevrStruct -> NormRevr + n(revr)*H(+) -nToBeRemovedByNormFromRevrs = n(orig) - n(revr) [each may be negative] - -n(orig) > n(revr) or nToBeRemovedByNormFromRevrs > 0 means: ------------------------------------------------------------ -- Too many protons were added by the Normalization to the Reconstructed Structure -(a) n(revr) < 0 => protons were added while they should not have been added; -Solution: "neutralize" (-) charged proton acceptors by moving charges to other atoms -on the condition ADP cannot add in another way; -(b) n(orig) > n(revr) => 0 => too few protons were removed -Solution: (the easiest) attach H(+) to =O or -N< or -N= -Solution: move (+) from N or OH to an atom adjacent to (-) charge or to -an atom that is not N. - -n(orig) < n(revr) or nToBeRemovedByNormFromRevrs < 0 means: ------------------------------------------------------------ -- Too few protons were added by the Normalization to the Reconstructed Stucture -(a) n(orig) < 0 => protons were not added while they should have been added; -Solution: move (-) to O by replacing =O with -O(-) -(b) 0 <= n(orig) < n(revr) => too many protons were removed - -Note: it is critically important to takr into account cumbersome Normalization -Total Charge: if it is >= 0 then no H(+) may be removed from -OH or by ADP -However, if N(+) is present then ADP will always try to remove a proton -****************************************************************************/ -int AddRemoveProtonsRestr( inp_ATOM *at, - int num_atoms, - int *num_protons_to_add, - int nNumProtAddedByRestr, - INCHI_MODE bNormalizationFlags, - int num_tg, - int nChargeRevrs, - int nChargeInChI ) -{ - int i, j, ret = 0; - int nAtTypeTotals[ATTOT_ARRAY_LEN]; - int num_prot = *num_protons_to_add; - int type, mask, bSuccess, nTotCharge, nNumSuccess = 0; - int max_j_Aa = -1, max_j_Ar = -1; - - /* for the reference: - - #define FLAG_NORM_CONSIDER_TAUT ( FLAG_PROTON_NPO_SIMPLE_REMOVED | \ - FLAG_PROTON_NP_HARD_REMOVED | \ - FLAG_PROTON_AC_SIMPLE_ADDED | \ - FLAG_PROTON_AC_SIMPLE_REMOVED | \ - FLAG_PROTON_AC_HARD_REMOVED | \ - FLAG_PROTON_AC_HARD_ADDED | \ - FLAG_PROTON_SINGLE_REMOVED | \ - FLAG_PROTON_CHARGE_CANCEL ) - - #define FLAG_FORCE_SALT_TAUT ( FLAG_PROTON_NP_HARD_REMOVED | \ - FLAG_PROTON_AC_HARD_REMOVED | \ - FLAG_PROTON_AC_HARD_ADDED ) - - */ - - /* if ChargeRevrs > nChargeInChI then we should prevent proton addition or facilitate proton removal - a typical case is (=) on N or O instead of C(-) - - if ChargeRevrs < nChargeInChI then we should prevent proton removal or facilitate proton addition - */ - - mark_at_type( at, num_atoms, nAtTypeTotals ); - for (i = nTotCharge = 0; i < num_atoms; i++) - { - nTotCharge += at[i].charge; - } - /* Size for SimpleAddAcidicProtons() */ - for (max_j_Aa = 0; AaTypMask[2 * max_j_Aa]; max_j_Aa++) - { - ; - } - /* Size for SimpleRemoveAcidicProtons */ - for (max_j_Ar = 0; ArTypMask[2 * max_j_Ar]; max_j_Ar++) - { - ; - } - if (num_prot < 0 && nAtTypeTotals[ATTOT_TOT_CHARGE] - nNumProtAddedByRestr <= 0) - { - /* Remove proton(s) */ - /* use test from SimpleAddAcidicProtons() to test whether removal of H(+) from =C-OH, etc. is correct */ - for (i = 0; i < num_atoms && num_prot; i++) - { - /* Choose an atom */ - if (at[i].sb_parity[0] || at[i].p_parity || at[i].charge || - !at[i].num_H || at[i].radical || bHasChargedNeighbor( at, i )) - { - continue; - } - /* try to remove a proton and check whether InChI would add it back */ - at[i].charge--; - at[i].num_H--; - type = GetAtomChargeType( at, i, NULL, &mask, 0 ); - at[i].charge++; - at[i].num_H++; - - if (type) - { - for (bSuccess = 0, j = 0; j < max_j_Aa; j++) - { - if ((bSuccess = ( type & AaTypMask[2 * j] ) && ( mask && AaTypMask[2 * j + 1] ))) /* djb-rwth: addressing LLVM warning */ - { - break; /* the proton may be added to this atom */ - } - } - if (bSuccess) - { - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 1 ); /* subtract at[i] */ - at[i].charge--; - at[i].num_H--; - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); /* add changed at[i] */ - num_prot++; /* success */ - nNumSuccess++; - } - } - } - } - - if (num_prot < 0 && num_tg && nAtTypeTotals[ATTOT_TOT_CHARGE] - nNumProtAddedByRestr <= 0) - { - /* Alternative proton removal: O=C-NH => (-)O-C=N, O and N are taut. endpoints */ - int endp2, centp, k, i0, k0; - for (i = 0; i < num_atoms; i++) - { - /* Choose an atom */ - if (!at[i].endpoint || at[i].sb_parity[0] || at[i].p_parity || - at[i].radical || at[i].charge || bHasChargedNeighbor( at, i )) - { - continue; - } - /* Looking for tautomeric =O */ - if (1 != at[i].valence || BOND_TYPE_DOUBLE != at[i].bond_type[0] || at[i].num_H || - 2 != get_endpoint_valence( at[i].el_number )) - { - continue; - } - centp = at[i].neighbor[0]; - if (at[centp].sb_parity[0] || at[centp].p_parity || !is_centerpoint_elem( at[centp].el_number )) - { - continue; - } - /* Found a possible centerpoint, looking for -NH endpoint */ - for (k = 0; k < at[centp].valence; k++) - { - if (at[centp].bond_type[k] != BOND_TYPE_SINGLE) - { - continue; - } - endp2 = at[centp].neighbor[k]; - if (at[endp2].endpoint != at[i].endpoint || - !at[endp2].num_H || at[endp2].charge || - at[endp2].sb_parity[0] || at[endp2].p_parity || - at[endp2].valence != at[endp2].chem_bonds_valence || - 3 != at[endp2].chem_bonds_valence + at[endp2].num_H || - 3 != get_endpoint_valence( at[endp2].el_number )) - { - continue; - } - /* Find bonds in reciprocal ajacency lists */ - for (i0 = 0; i0 < at[centp].valence && i != at[centp].neighbor[i0]; i0++) - { - ; - } - for (k0 = 0; k0 < at[endp2].valence && centp != at[endp2].neighbor[k0]; k0++) - { - ; - } - if (i0 == at[centp].valence || k0 == at[endp2].valence) - { - return RI_ERR_PROGR; - } - /* -NH has been found */ - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 1 ); /* subtract at[i] */ - type = GetAtomChargeType( at, endp2, nAtTypeTotals, &mask, 1 ); /* subtract at[endp2] */ - - at[i].bond_type[0] --; - at[centp].bond_type[i0] --; - at[i].chem_bonds_valence--; - at[i].charge--; - - at[endp2].bond_type[k0] ++; - at[centp].bond_type[k] ++; - at[endp2].chem_bonds_valence++; - at[endp2].num_H--; - - num_prot++; - nNumSuccess++; - - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); /* add at[i] */ - type = GetAtomChargeType( at, endp2, nAtTypeTotals, &mask, 0 ); /* add at[endp2] */ - } - } - } - - if (num_prot > 0) - { - /* Add protons */ - /* 1. Use test from SimpleRemoveAcidicProtons() to test whether addition of H(+) to =C-O(-), etc. is correct */ - for (i = 0; i < num_atoms && num_prot && nAtTypeTotals[ATTOT_TOT_CHARGE] - nNumProtAddedByRestr >= 0; i++) - { - /* Choose an atom */ - if (at[i].sb_parity[0] || at[i].p_parity || at[i].num_H || - at[i].charge != -1 || at[i].radical || bHasChargedNeighbor( at, i )) - { - continue; - } - /* Try to add a proton and check whether InChI would remove it back */ - at[i].charge++; - at[i].num_H++; - type = GetAtomChargeType( at, i, NULL, &mask, 0 ); - at[i].charge--; - at[i].num_H--; - if (type) - { - for (bSuccess = 0, j = 0; j < max_j_Ar; j++) - { - if ((bSuccess = ( type & ArTypMask[2 * j] ) && ( mask && ArTypMask[2 * j + 1] ))) /* djb-rwth: addressing LLVM warning */ - { - break; - } - } - if (bSuccess) - { - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 1 ); /* subtract at[i] */ - at[i].charge++; - at[i].num_H++; - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); /* add changed at[i] */ - num_prot--; /* success */ - nNumSuccess++; - } - } - } - /* 2. Use test from SimpleRemoveHplusNPO() */ - for (i = 0; i < num_atoms && num_prot; i++) - { - /* Choose an atom */ - if (at[i].sb_parity[0] || at[i].p_parity || - at[i].charge || at[i].radical || bHasChargedNeighbor( at, i )) - { - continue; - } - /* Try to add a proton and check whether InChI would remove it back */ - at[i].num_H++; - at[i].charge++; - bSuccess = ( PR_SIMPLE_TYP & ( type = GetAtomChargeType( at, i, NULL, &mask, 0 ) ) ) && - ( PR_SIMPLE_MSK & mask ); /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - at[i].num_H--; /* failed */ - at[i].charge--; - if (bSuccess) - { - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 1 ); /* subtract at[i] */ - at[i].num_H++; - at[i].charge++; - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); /* add changed at[i] */ - num_prot--; /* succeeded */ - nNumSuccess++; - } - } - } - - if (num_prot < 0 && ( bNormalizationFlags & FLAG_PROTON_AC_HARD_ADDED ) && 1 == num_tg && - nAtTypeTotals[ATTOT_TOT_CHARGE] - nNumProtAddedByRestr <= 0) - { - /* Try to remove protons from tautomeric N (specific ADP must be present) */ - int nNumAcceptors_DB_O = 0, nNumDonors_SB_NH = 0, num_max, num_success; - for (i = 0; i < num_atoms; i++) - { - /* Choose an atom */ - if (!at[i].endpoint || at[i].radical || - at[i].sb_parity[0] || at[i].p_parity || bHasChargedNeighbor( at, i )) - { - continue; - } - type = GetAtomChargeType( at, i, NULL, &mask, 0 ); - if (( type & AA_HARD_TYP_CO ) && ( mask & AA_HARD_MSK_CO )) - { - nNumAcceptors_DB_O++; - } - else - { - if (( type == ATT_ATOM_N ) && ( mask == ATBIT_NP_H ) && !at[i].charge && - at[i].valence == at[i].chem_bonds_valence) - { - nNumDonors_SB_NH++; - } - } - } - num_max = inchi_min( nNumAcceptors_DB_O, nNumDonors_SB_NH ); - for (i = 0, num_success = 0; i < num_atoms && num_success < num_max && num_prot < 0; i++) - { - /* Choose an atom */ - if (!at[i].endpoint || at[i].radical || at[i].sb_parity[0] || - at[i].p_parity || bHasChargedNeighbor( at, i )) - { - continue; - } - type = GetAtomChargeType( at, i, NULL, &mask, 0 ); - if (( type == ATT_ATOM_N ) && ( mask == ATBIT_NP_H ) && !at[i].charge && - at[i].valence == at[i].chem_bonds_valence) - { - /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 1 ); /* subtract at[i] */ - at[i].num_H--; - at[i].charge--; - type = GetAtomChargeType( at, i, nAtTypeTotals, &mask, 0 ); /* add changed at[i] */ - num_prot++; - num_success++; - nNumSuccess++; - } - } - } - - /*exit_function:*/ - - *num_protons_to_add = num_prot; - - return ret < 0 ? ret : nNumSuccess; -} - - -/**************************************************************************** -Add or remove isotopic protons -****************************************************************************/ -int AddRemoveIsoProtonsRestr( inp_ATOM *at, - int num_atoms, - NUM_H num_protons_to_add[], - int num_tg ) -{ - int i, j, k, n, ret = 0; - int nNumSuccess = 0, min_at, max_at, num_H, num_iso_H, num_expl_H, num_expl_iso_H; /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ - int iCurIso; /* 0=> 1H, 1=> D, 2=> T */ - int iCurMode, iCurMode1, iCurMode2; /* 0=> Not Endpoints, 1=> Endpoints */ - - /* Distribute isotopes from heaviest to lightest; pick up atoms in order 1. Not endpoints; 2. Endpoints */ - iCurMode1 = 0; - iCurMode2 = num_tg ? 1 : 0; - for (iCurMode = iCurMode1; iCurMode <= iCurMode2; iCurMode++) - { - for (iCurIso = 2; 0 <= iCurIso; iCurIso--) - { - /* check for isotopic H to add */ - if (!num_protons_to_add[iCurIso]) - { - continue; - } - if (0 > num_protons_to_add[iCurIso]) - { - ret = RI_ERR_PROGR; - goto exit_function; - } - - /* Limits for atom scanning */ - min_at = 0; - max_at = num_atoms; - - /* Cycle withio the limits */ - for (i = min_at; i < max_at && 0 < num_protons_to_add[iCurIso]; i++) - { - /* Pick an atom */ - if (iCurMode) - { - if (at[i].endpoint) - { - j = i; /* atom number */ - } - else - { - continue; - } - } - else - { - if (!at[i].endpoint && 1 == bHeteroAtomMayHaveXchgIsoH( at, i )) - { /* atom number */ - j = i; - } - else - { - if (at[i].el_number == EL_NUMBER_H && at[i].charge == 1 && - !at[i].valence && !at[i].radical && !at[i].iso_atw_diff) - { - /* proton, not isotopic; make it isotopic */ - at[i].iso_atw_diff = 1 + iCurIso; - num_protons_to_add[iCurIso] --; - nNumSuccess++; - continue; - } - else - { - continue; - } - } - } - - /* j is the atom number */ - /* count implicit H */ - num_H = at[j].num_H; - num_iso_H = NUM_ISO_H(at, j); /* djb-rwth: ignoring LLVM warning: possible presence of global variables */ - - while (num_H > 0 && num_protons_to_add[iCurIso] > 0) - { - /* Substitute one implicit H with an isotopic atom H */ - at[j].num_iso_H[iCurIso] ++; - at[j].num_H--; - num_protons_to_add[iCurIso] --; - num_H--; - num_iso_H++; - nNumSuccess++; - } - /* Count explicit H */ - num_expl_H = num_expl_iso_H = 0; - for (k = 0; k < at[j].valence && num_atoms <= ( n = at[j].neighbor[k] ); k++) - { - num_expl_H += ( 0 == at[n].iso_atw_diff ); - num_expl_iso_H += ( 0 != at[n].iso_atw_diff ); - } - while (num_expl_H > 0 && num_protons_to_add[iCurIso] > 0) - { - /* Substitute one explicit H with an isotopic atom H */ - n = at[j].neighbor[num_expl_H]; - if (at[n].iso_atw_diff) - { - ret = RI_ERR_PROGR; - goto exit_function; - } - at[n].iso_atw_diff = 1 + iCurIso; - num_expl_H--; - num_expl_iso_H++; - num_protons_to_add[iCurIso] --; - nNumSuccess++; - } - } - } - } - -exit_function: - - return ret < 0 ? ret : nNumSuccess; -} - -#endif From 5693b2517ba16ba690d0b3baf64115171e893a33 Mon Sep 17 00:00:00 2001 From: Djordje Baljozovic Date: Sun, 1 Feb 2026 18:13:39 +0100 Subject: [PATCH 4/9] Unresolved issues comment --- INCHI-1-SRC/INCHI_API/libinchi/src/inchi_dll_a2.c | 2 +- INCHI-1-SRC/INCHI_BASE/src/ichinorm.c | 2 +- INCHI-1-SRC/INCHI_BASE/src/ichiprt1.c | 2 +- INCHI-1-SRC/INCHI_BASE/src/ichiread.c | 4 ++-- INCHI-1-SRC/INCHI_BASE/src/ichirvr2.c | 8 ++++---- INCHI-1-SRC/INCHI_BASE/src/ichirvr7.c | 6 +++--- INCHI-1-SRC/INCHI_BASE/src/ichister.c | 2 +- INCHI-1-SRC/INCHI_BASE/src/mol_fmt4.c | 2 +- INCHI-1-SRC/INCHI_BASE/src/strutil.c | 6 +++--- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/INCHI-1-SRC/INCHI_API/libinchi/src/inchi_dll_a2.c b/INCHI-1-SRC/INCHI_API/libinchi/src/inchi_dll_a2.c index 8fb1c972..52355a15 100644 --- a/INCHI-1-SRC/INCHI_API/libinchi/src/inchi_dll_a2.c +++ b/INCHI-1-SRC/INCHI_API/libinchi/src/inchi_dll_a2.c @@ -2557,7 +2557,7 @@ int FillOutINChIReducedWarn( INChI *pINChI, /* Num(H), Num(-) */ for (j = 0; j < INCHI_T_NUM_MOVABLE; j++) /* djb-rwth: removing redundant code */ pINChI->nTautomer[len++] = t_group->num[j]; - for (j = T_NUM_NO_ISOTOPIC; j < INCHI_T_NUM_MOVABLE; j++) /* djb-rwth: redundant code as the loop is never executed -- discussion required */ /* djb-rwth: ui_rr */ + for (j = T_NUM_NO_ISOTOPIC; j < INCHI_T_NUM_MOVABLE; j++) /* djb-rwth: redundant code as the loop is never executed -- discussion required */ /* djb-rwth: unresolved issue -- revision required */ pINChI->nTautomer[len++] = 0; /* should not happen */ /* tautomeric group endpoint canonical numbers, pre-sorted in ascending order */ for (j = (int) t_group->nFirstEndpointAtNoPos, diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichinorm.c b/INCHI-1-SRC/INCHI_BASE/src/ichinorm.c index 4f9229bf..7f514e1a 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichinorm.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichinorm.c @@ -2261,7 +2261,7 @@ int is_DERIV_RING2_PRRLDD_PPRDN( inp_ATOM *at, k = ( ord[1] < ord[0] ); da1->ord[0] = ord[k]; /* smaller */ da1->ord[1] = ord[!k]; /* greater */ - /*da1->num[0] = */da1->num[0] = i - 1; /* djb-rwth: ui_rr? / da1->num[1] = i-1? */ + /*da1->num[0] = */da1->num[0] = i - 1; /* djb-rwth: unresolved issue -- revision required? / da1->num[1] = i-1? */ } return i; } diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichiprt1.c b/INCHI-1-SRC/INCHI_BASE/src/ichiprt1.c index 331541be..0547b3e5 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichiprt1.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichiprt1.c @@ -4008,7 +4008,7 @@ static int OutputINCHI_PolymerLayer( CANON_GLOBALS *pCG, for (i = 0; i < p->n; i++) { units2[i] = OAD_PolymerUnit_CreateCopy(p->units[i]); - if (NULL == units2[i]) /* djb-rwth: ui_rr? -- units2 properly allocated, and loop index well defined */ + if (NULL == units2[i]) /* djb-rwth: unresolved issue -- revision required? -- units2 properly allocated, and loop index well defined */ { err = 4; goto exit_function; diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichiread.c b/INCHI-1-SRC/INCHI_BASE/src/ichiread.c index 96c748cc..156a7746 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichiread.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichiread.c @@ -2965,7 +2965,7 @@ int InChILine2Data(INCHI_IOSTREAM* pInp, /* create two zero/NULL-initialized isotopic stereo if they do not exist */ if ((!pInChI->StereoIsotopic && 0 > (ret2 = CopySegment(pInChI, pAltInChI, CPY_SP3_M, 1, -1))) /* -- the following will be created later, in TAUT_YES part of the code -- */ - || (!pAltInChI->StereoIsotopic && 0 > (ret2 = CopySegment(pAltInChI, pAltInChI, CPY_SP3_M, 1, -1)))) /* djb-rwth: addressing LLVM warnings */ /* djb-rwth: addressing coverity ID #499533 -- ui_rr */ + || (!pAltInChI->StereoIsotopic && 0 > (ret2 = CopySegment(pAltInChI, pAltInChI, CPY_SP3_M, 1, -1)))) /* djb-rwth: addressing LLVM warnings */ /* djb-rwth: addressing coverity ID #499533 -- unresolved issue -- revision required */ { goto exit_function; } @@ -10195,7 +10195,7 @@ int ParseSegmentFormula(const char* str, { U_CHAR* pci1 = NULL; /* copied from below to obey C syntax - 2024-09-01 DT */ /* Copy duplicated formula */ - strcpy(pInChI[iComponent + i].szHillFormula, pInChI[iComponent].szHillFormula); /* djb-rwth: ui_rr? */ + strcpy(pInChI[iComponent + i].szHillFormula, pInChI[iComponent].szHillFormula); /* djb-rwth: unresolved issue -- revision required? */ /* Copy atoms in the duplicated formula */ pInChI[iComponent + i].nNumberOfAtoms = nNumAtoms; /* djb-rwth: fixing oss-fuzz issue #43420, #34772 */ diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichirvr2.c b/INCHI-1-SRC/INCHI_BASE/src/ichirvr2.c index c3fe3eb4..7a6ca894 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichirvr2.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichirvr2.c @@ -416,7 +416,7 @@ int RestoreAtomConnectionsSetStereo( StrFromINChI *pStruct, if (nNumDeletedH) { /* add explicit H */ -#if ( FIX_GAF_2019_2==1 ) +#if ( FIX_GAF_2019_2==1 ) inp_ATOM *at2 = (inp_ATOM *)inchi_calloc(nNumDeletedH>0 ? num_atoms + nNumDeletedH : num_atoms, sizeof(at2[0])); #else @@ -437,7 +437,7 @@ int RestoreAtomConnectionsSetStereo( StrFromINChI *pStruct, inchi_free( at ); pStruct->at = at = at2; /* fill out deleted H atom info */ - for (i = num_atoms; i < num_atoms + nNumDeletedH; i++) /* djb-rwth: ui_rr? -- buffer overrun cannot happen, loop not executed for nNumDeletedH <= 0 */ + for (i = num_atoms; i < num_atoms + nNumDeletedH; i++) /* djb-rwth: unresolved issue -- revision required? -- buffer overrun cannot happen, loop not executed for nNumDeletedH <= 0 */ { strcpy( at[i].elname, "H" ); at[i].el_number = EL_NUMBER_H; @@ -4776,7 +4776,7 @@ int RestoreIsoCyanoGroup( BN_STRUCT *pBNS, at2[j].num_H == 0 && at2[j].radical == 0 && pVA[j].cNumValenceElectrons == 5 && - ( eNPlusEdge1 = pVA[j].nCPlusGroupEdge - 1 ) >= 0 && + ( eNPlusEdge1 = pVA[j].nCPlusGroupEdge - 1 ) >= 0 && pBNS->edge[eNPlusEdge].flow == 0) /* djb-rwth: ignoring LLVM warning: variable used */ { /* -N(+)- */ @@ -5083,7 +5083,7 @@ int FixMetal_Nminus_Ominus( BN_STRUCT *pBNS, if (ret == 1 && ( (vPathEnd == v1 && vPathStart == v2) || (vPathEnd == v2 && vPathStart == v1) ) /*&& nDeltaCharge == nDeltaChargeMax*/) /* djb-rwth: addressing LLVM warnings */ - { + { ret = RunBnsRestoreOnce( pBNS, pBD, pVA, pTCGroups ); ( *pnNumRunBNS )++; *pnTotalDelta += ret; diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichirvr7.c b/INCHI-1-SRC/INCHI_BASE/src/ichirvr7.c index 49954c47..685f4693 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichirvr7.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichirvr7.c @@ -1392,17 +1392,17 @@ void FreeStrFromINChI(StrFromINChI* pStruct[INCHI_NUM][TAUT_NUM], } if (pStruct1[k].pXYZ) { - inchi_free(pStruct1[k].pXYZ); /* djb-rwth: ui_rr? -- false positive as this function just does the clean-up job */ + inchi_free(pStruct1[k].pXYZ); /* djb-rwth: unresolved issue -- revision required? -- false positive as this function just does the clean-up job */ } /*==== begin ====*/ free_t_group_info(&pStruct1[k].ti); if (pStruct1[k].endpoint) { - inchi_free(pStruct1[k].endpoint); /* djb-rwth: ui_rr? -- false positive as this function just does the clean-up job */ + inchi_free(pStruct1[k].endpoint); /* djb-rwth: unresolved issue -- revision required? -- false positive as this function just does the clean-up job */ } if (pStruct1[k].fixed_H) { - inchi_free(pStruct1[k].fixed_H); /* djb-rwth: ui_rr? -- false positive as this function just does the clean-up job */ + inchi_free(pStruct1[k].fixed_H); /* djb-rwth: unresolved issue -- revision required? -- false positive as this function just does the clean-up job */ } for (j = 0; j < TAUT_NUM; j++) { diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichister.c b/INCHI-1-SRC/INCHI_BASE/src/ichister.c index 971eb025..2adfd55f 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichister.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichister.c @@ -1015,7 +1015,7 @@ double triple_prod_and_min_abs_sine2( double at_coord[][3], ? ( max_edge_len_NoExplNeigh < MAX_EDGE_RATIO * min_edge_len_NoExplNeigh ) : ( max_edge_len < MAX_EDGE_RATIO * min_edge_len ); - if (sine_value > vMinSine && ( min_sine || bAmbiguous )) /* djb-rwth: fixing coverity ID #499548 -- ui_rr */ + if (sine_value > vMinSine && ( min_sine || bAmbiguous )) /* djb-rwth: fixing coverity ID #499548 -- unresolved issue -- revision required */ { if (min_sine) { diff --git a/INCHI-1-SRC/INCHI_BASE/src/mol_fmt4.c b/INCHI-1-SRC/INCHI_BASE/src/mol_fmt4.c index ba527667..5844041f 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/mol_fmt4.c +++ b/INCHI-1-SRC/INCHI_BASE/src/mol_fmt4.c @@ -494,7 +494,7 @@ void NumLists_Free(NUM_LISTS *num_lists) { int i; for (i = 0; i < num_lists->used; i++) - inchi_free(num_lists->lists[i]); /* djb-rwth: ui_rr? -- false positive as this function just does the clean-up job */ + inchi_free(num_lists->lists[i]); /* djb-rwth: unresolved issue -- revision required? -- false positive as this function just does the clean-up job */ inchi_free(num_lists->lists); memset(num_lists, 0, sizeof(*num_lists)); /* djb-rwth: memset_s C11/Annex K variant? */ } diff --git a/INCHI-1-SRC/INCHI_BASE/src/strutil.c b/INCHI-1-SRC/INCHI_BASE/src/strutil.c index 8e0d20e0..981ff18a 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/strutil.c +++ b/INCHI-1-SRC/INCHI_BASE/src/strutil.c @@ -2747,7 +2747,7 @@ int bIsMetalToDisconnect( inp_ATOM *at, int i, int bCheckMetalValence ) for (i = 0; i < 2 && ( i & type ); i++) { - if (at_valence == get_el_valence( at[i].el_number, at[i].charge, i )) /* djb-rwth: fixing coverity ID #499532 -- ui_rr */ + if (at_valence == get_el_valence( at[i].el_number, at[i].charge, i )) /* djb-rwth: fixing coverity ID #499532 -- unresolved issue -- revision required */ { return 2; /* atom has normal valence */ } @@ -5040,7 +5040,7 @@ void imat_free( int m, int **a ) { for (i = 0; i < m; i++) { - if (NULL != a[i]) /* djb-rwth: ui_rr? -- false positive as this function just does the clean-up job */ + if (NULL != a[i]) /* djb-rwth: unresolved issue -- revision required? -- false positive as this function just does the clean-up job */ { inchi_free( a[i] ); } @@ -5175,7 +5175,7 @@ void subgraf_free( subgraf *sg ) { for (i = 0; i < sg->nnodes; i++) { - if (sg->adj[i]) /* djb-rwth: ui_rr? -- false positive as this function just does the clean-up job */ + if (sg->adj[i]) /* djb-rwth: unresolved issue -- revision required? -- false positive as this function just does the clean-up job */ { inchi_free( sg->adj[i] ); } From 81bd8351f6476552fc0fe6ae9a1c1b04621001ab Mon Sep 17 00:00:00 2001 From: Djordje Baljozovic Date: Wed, 4 Feb 2026 21:24:56 +0100 Subject: [PATCH 5/9] v.1.07.5 Changelog entries --- INCHI-1-DOC/CHANGELOG.md | 15 +++++++++++++-- INCHI-1-DOC/CHANGELOG.pdf | Bin 130496 -> 132717 bytes 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/INCHI-1-DOC/CHANGELOG.md b/INCHI-1-DOC/CHANGELOG.md index ba06dc99..563c96bd 100644 --- a/INCHI-1-DOC/CHANGELOG.md +++ b/INCHI-1-DOC/CHANGELOG.md @@ -1,5 +1,16 @@ # Change log +## v1.07.5 2026-02-04 + +### Fixed + +- 127 `Coverity Scan` high and medium impact bugs fixed or addressed +- GHI #189: Exception in libinchi.dll when converting some specific polymer structure +- GHI #165, #164, #161, #160, PR #163, #162 -- initial `Coverity Scan` detections +- `.rc` files to `CMake` build system for metadata +- PR #138: stack buffer overflow in `CleanOrigCoord` +- Several _Google oss-fuzz_ issues + ## v1.07.4 2025-07-03 ### Features @@ -33,7 +44,7 @@ - GHI #71: 32-bit InChI version requiring ibgcc_s_dw2-1.dll on Windows 32-bit platforms (thanks to Norwid Behrnd) a few bugs in the code have been detected and fixed libgcc_s_dw2-1.dll added to INCHI-1-BIN folders - GHI #70: Update license -- Copyright (c) 2024 IUPAC and InChI Trust instead of Copyright (c) 2024 InChI Project -- GHI #67: GetStructFromInchi() now working in v1.07.2 (thanks to Greg Landrum) all variable initializations checked and fixed which caused this issue essential part of InChI tests from now on as all bugs reported by Paul Thiessen/Evan Bolton had the same origin +- GHI #67: GetStructFromInchi() now working in v1.07.2 (thanks to Greg Landrum) all variable initializations checked and fixed which caused this issue essential part of InChI tests from now on as all bugs reported by Paul Thiessen/Evan Bolton had the same origin - GHI #65:changing descriptions in default output for tautomerisms (thanks to Norwid Behrnd) - GHI #58 and #59: 7 bug fixes detected by AFL++ fuzzer (thanks to @skorpion89) - GHI #43: add changes to new version (thanks to Burt Leland) several very important bug fixes related to /InChI2InChI /FixedH /RecMet options @@ -78,7 +89,7 @@ - 33 buffer overflow issues due to use of large array dimensions - 157 security bugs related to improper `NULL` pointer dereferencing which might cause crashes or exits - 71 memory leaks -- 530 potential applications of optional [bounds checking functions](/README.md#BCF) +- 530 potential applications of optional [bounds checking functions](/README.md#BCF) Additionally, 29 potential security issues have been marked for further revision. diff --git a/INCHI-1-DOC/CHANGELOG.pdf b/INCHI-1-DOC/CHANGELOG.pdf index bbd28df732cc475066cdb14bfd2ee27796dc5823..00376b748529df298fb34eadf3c6639c58a53d9e 100644 GIT binary patch delta 119293 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%0D%tlrcs%dfRk1W(A> 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 Date: Fri, 6 Feb 2026 09:27:59 +0100 Subject: [PATCH 6/9] Update license in FAQ; renamed v1.05 specific file; --- INCHI-1-DOC/FAQ/html/inchi-faq.html | 1 + INCHI-1-DOC/misc/{announce.txt => announce-v105-prerelease.txt} | 0 2 files changed, 1 insertion(+) rename INCHI-1-DOC/misc/{announce.txt => announce-v105-prerelease.txt} (100%) diff --git a/INCHI-1-DOC/FAQ/html/inchi-faq.html b/INCHI-1-DOC/FAQ/html/inchi-faq.html index fe692c32..edd55cff 100644 --- a/INCHI-1-DOC/FAQ/html/inchi-faq.html +++ b/INCHI-1-DOC/FAQ/html/inchi-faq.html @@ -558,6 +558,7 @@

Up to Fall 2011, InChI software was published under the GNU Lesser General Public Licence, LGPL version 2.1.

Since the release 1.04 of the InChI software of Fall 2011, it has been replaced with the more permissive IUPAC/InChI-Trust Licence for the International Chemical Identifier (InChI) Software version 1.04, September 2011 ("IUPAC/InChITrust InChI Licence No. 1.0").

The text of the IUPAC/InChI-Trust Licence may be found here
PDF format / DOC format
(it is also included in the distribution package as the file LICENCE).

+

Since release 1.07 thee InChI software is released under the MIT License.

diff --git a/INCHI-1-DOC/misc/announce.txt b/INCHI-1-DOC/misc/announce-v105-prerelease.txt similarity index 100% rename from INCHI-1-DOC/misc/announce.txt rename to INCHI-1-DOC/misc/announce-v105-prerelease.txt From d12eaf961e9a400a19376455e08552f57c5d4968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20B=C3=A4nsch?= <168176402+fbaensch-beilstein@users.noreply.github.com> Date: Mon, 9 Feb 2026 13:20:06 +0100 Subject: [PATCH 7/9] Update license in faq .doc, .docx, and .html; --- INCHI-1-DOC/FAQ/doc/inchi-faq.doc | Bin 949248 -> 859136 bytes INCHI-1-DOC/FAQ/doc/inchi-faq.docx | Bin 605461 -> 527520 bytes INCHI-1-DOC/FAQ/html/inchi-faq.html | 44 ++++++++++++++-------------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/INCHI-1-DOC/FAQ/doc/inchi-faq.doc b/INCHI-1-DOC/FAQ/doc/inchi-faq.doc index f7bc5f7e0e1f2fb26531b81a8e82bef1d04ef436..3d58e65dd519942dc0476955df2d6316a1ecc860 100644 GIT binary patch delta 340638 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

v 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 BG8F&- delta 421264 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 diff --git a/INCHI-1-DOC/FAQ/doc/inchi-faq.docx b/INCHI-1-DOC/FAQ/doc/inchi-faq.docx index ca1eb8e36808d21e0d5554d326bb1d7c4a4bb6f5..08e48947334c42d9bd9416323c4698556f559a10 100644 GIT binary patch literal 527520 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

6?wceY6Z(4ohRu<*Mt^rj<;X{>+%_8$h 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≺F-LyoOLnW~eHMfe9 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 CFyp= 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 literal 605461 zcmeFXg;Sef6ef%nDaDEucP$iJio3hJOK}PA?oiwvic4{Kr)aSTPp}f4;I5ngc4ue5 zneRW?&CGpgGIQU|y(dSW=bT4H9uWx-4jB#=4i1hA?rxJ7xd|Q)t_TGV4i^p;L0{a_ z!Ogo;)eB%xS%ieZSOA9r+yDPQ{})@JIc-wu=reZ2t@K|qYDd+-g9wGi zWi0J1@ZYKPYPJ>hLLD2+oBe%96u-x-$OX0L$ejQ7dlkmzCpWH%onEJu*s&jehn zm(ynEXI{CyV(l~6l`yp{%nMJhp=zueAOCUg2Bosp0GN&MM!m4@sZI|>>F{8sQ^%o8 zQT9X--HP=_6P;bo?T5%);jrvx656x(21~JUShg|iIpk?fG#+$TJ}P$dnrqdH9BweSH!I==Ya7<*DWZ@1XA7V^Ke4@sSx}|E`Iv)%9bA zOA7AZ#HhO5a$!AqMLPOwiFVaNUB3op6;E^_Q7}5_c2I@DxKriQVc6I#LRhuvev@`s zrfX`yD2A}`SbD}^2tr--^)+_)?SKIC-uBA62cPv{QIR)mV9)76R)sggV2S`jGM`zA z;g$$5FO*N7I^@`un}o=%5K(mbiv0N9zruF~NfB=4MSq;UNMIYoQ1%kG3U)9jXx89o zg>HpYNq%c5r*`nZx|N3+Up<|7DK2!pE)JaHq4jtMCcaE?&I_*kxeh6|NPd|2_X-jQ?L8*#F1XtCI(8hd#d(ISqXdo$FCu z9Uv@LVl$fs5w4)1>dPwNf|hNUUY-S(mk|sPOr=LK_kmF5gMb5A3Z~ioOBnJIn|H5^HJhvrySje znrUX_zVq33HuN z={6g0Ig;cWieCQz#z(j}F-}b+JX{$D4jc~5D4vck=4|GUX6^u3LHt(wov zC0)s|!seBjiUOjhlVmLF9Z^_OlEqVhNabtuY_KT-+8Tu0&0~wW8s(X#9r^TjH z-W3*lI4WOK9!-!*2hx@#$t))%EVB4sMee;m_dP!z>N18%6@Yqu_jxj~P5Q#2y z>e>9cl-a96pdb*3#X7rb24u!lgT>ySX%Kr#F$Q&_yu&cudnxQ*j3hQ1YwGl*>;ndG zR-cgB%tB?bo?M0;q+L!aZ04ad>(4ZCU1SGFxqlzwKgg%|hki{O;fM?@yNt;!Tl#gu zMCv8$Dzt+$v*h&qrJncQ&bWKz*AQ($Jhrdt5lt-XH=M>X^qk@-3JQFii|T-9;MCDh zrEryz@#|bS_1fNTozcb5Uf$Hcd&vpvI~IxLPj@b^;iHBL$XKk|pz1dD%l z=VsMd_H7%FR$k{CGZp`_c`bn(T3Z;8mj|!1gj_jJE{=JW$UB*PjIr0jHZh3g?LKen zTXme;ogeazKFFm~cju$h&o48@b9Po2758(@T*Z>98-b9a>4b?;KbcA4+6#9i$Lr$= zDPbX>p^9qVTM#a_nvS zFCwNh`j(VWjTbj;l*)CVtu9R__F@dkIYS(O4Dg2+J?*K93^U{lSIl&J+dNO6(^d)V zOAF-?+>7rHI5JZ8wb-J(A*L2jf4A~*ZZx#1V^^lCx(mLC~!w` zn^&Lf3yVhhZeh%3*q$pK->uT`!n57q8E&~d)S0J@Aje7V;2Tym%vrp$5q|#%Y4I_#5wMm#HLD~=JXHcb#%G; zEVN^fBzHVK`fEMz!gq$Jx%S!I!I0S5TV+LRqzUL)z&cE%HI^du``{{^j_=L*tw%ryBGd`> z$dUYpx&EaUf??|KrX!y7Aa}JHh~AJqT#MY4Q7I#lgv27@BK{eJ-gC6@Kikg1Z0o{I z)i(8w18d5fcs$OM0|UaE5x^OMFO@F&whciF7P<^vT{-r|?;JU8Il|iD&staFb_+=r zX}VS8%iz~v0A5zXI@Fz~MIaN+?DCPch<%|zw?`<7@_!Z=>iok|L}F+|JS(`Lq#eR3 zxTD)(5Y53h(4&XSvx<`Lf^!jMP}7wA3)N+;vV-z=p&dAaQi>#6iv;270{Xd?A0T#w zo^W7LvMq&)k~}qsFA?1<25^D2sE zM{okSDD-nD1FKt8z+S7rRi(SdeK1D4i1)IA!i@A|o^*a~x}97i2ia1+#cqm-8+ic< z-8jtF6^@qe;eK3ZOj)JW^xCJa8!vw0PZ4g!za2RbIU#LmPpvCGTq3vGQUS%jiYR^Z z_p5mrqAOO!Y&3A4nVJe2#k-&gJ_mhjpe^f6B-tn~$bWK%Y_A}baz^va&$=le5aq)a zCm=1DgPGr@=_~Nz&o}{r=mONJ=uyn0ab}acfEETkP&lZAqcVzQR6z8IcAx(&Sc9++ z=qcAM9YNSV0OF+hbuKa)wqF3T_~;K=;4>0`HbqhlyFUF)eA67UD9;S_o@S8R+g6QB| z>n#|ke%~z=V|H8(rsoF-edGvuQ-UL`f;Ta5X_3>(gjy_EQ&aA>auqytUh$8xoC zPC zR!$5girX>tP0v9s#d0610=N7h#Kll_Y*uV_S-Y5P&L&ne*s50plI8d)yZK2UB@b<$rNCJkcT zJ0NTTJlc6N<-i;lWONS1cS6;RnG3jUYFg%Q#D$BJBXj1K%oojZm=kF1`WQ_Bf)-xP z>{SkS5=8)Urr=>xRW3c1B1y5l7FN=BCwo-M0N8^c6SMU(`v?Das7nY~YY?zxNtLr* zl%z=0HaAul4BCbcU-?iGp{dc2_K&mRfARPch<1SdxI(I(RDhA>fba*v)y&KKag~Fb z3?D$8C{&q9{&w-0fSjE;34i7T-LzSD^>q5)3Tvc9 zm4(|AwsNT_!+if8u6EzJfFmfO0rdhw$dKg?P#H{*A#W3M8Mfb4{Y)bnGBW^ZP%%WzireSq+Q za%rPKH7jun79RvigSR_5vSdRCpiIf#RPBmzZ41fVSagmL{m^2FB1-#OW6P(<5Zeqx^ z^4H#|qTL~Z1qWRA%)qbjl1j*}c z*Yd*7g||Gf26#?5xp&fIiKJssB74W>sdGmcD}D0o#iUATrxcyhC*aaTWG|-2)vrc} zCOZ=?8Pu{miI*h#by%I@pkSYrDd%2d*W4r0R9uOkY~=2RT^@=lXX4=aU7j6`yI}C@ zQ<}j~R?x|x&*~DXvlRxZy*Aa_7``3C=#y1_92IqYvlhQNCT-qt{^24r3)L0g=XqH^ zv6EUP8F&a@XzhSs-Q{Q`2e=aJ^kq^0XpA`5P>N^MKNPt%h+aQZG$1!d+Mt=Ds-OoN z#93q7I3P{c5KLjHaFi$QGG+rsTu*s}2_Ewf1R0FnX6DyS1;^NZK;a4tQ>4T=w*0-*XLx=JwZ6j5iZD$Oy(u5-Gn|Yo+ zgWG~!6Q+U^Ji=CrQYPh*ST&QVY2LU}IKDlORD{qvp6#Z%;~qVz63`MgKm7gE7jViQ zdvgDbuHNnLkaz;3vpVr^vAa#G)zY)Y#Bt52XGV^D}WRzFsWkXie; z0!9;EDfNmsI=$amn6OeWY^bDPnrz!T0Nx^Z)k6C>vKRF%M!W6Q#zqA6OPJ9t-a7o5 zD*QTtagriBWix0{x&TJYP{p664V=G8nSmo@+t~)$?;IuB1x^ccDZ9DPgmwlW3m4eC zRY!j@{#3Kz?pBQ`M_Tt~siU|VW9VS&w!iGdRmYU}2gcq|xMj44?$S@5OGQJxWLy!m z|I$?Lc+sS8+m!H5oTqaCigW=y=b1hOe7mzUGc=2zoTuEyTyd-*&X^yfqjV>l?!Fsj zC@))mT-w;q4Ir{i`CccJ8#&A!e5Vz2DYZvE{b=}};@XQi>Qs*8q?0@-G^>ShSOyBxM!0KO znCSlU@sb09Jk6UJ?(}wSC-yAYJoeZ1+isum{NshXn`X3OfvvvJ)~nq9H}9{{iQfiA zy^$QwPfYVO6=V|*KdN1Xh*weQJ=)!U5#UO@gaVt5dPl7!YHwnwk1sN|xI4sDO16gH zZpq*eGL;|4)hwRHsScGlh>2kQNPcUYz~oy@-ch8=8s|sl{bSk&AzT#m^B%m?N@zj0 zf~%xj?-r~kWmnmp>VMiHDNa?UnNpo7@9q(PI85zPcuz*Mov4sLWLyQdo!BWR_ zyu6r3>4ZaXak~=Y2FijMk6zMaWiIZ9y#(-BI%ne9YLj^C!UdGAf8k@j?20#;alrZE z+{sKm^lltxgkeYQz`^e)XS-T7{e)) z58Rpy`!xMm<2ZfHEJvhEfX8G9X6FtEJH?s{apuPFY_`JJeQIBcZ#Wk#*#c=$&-|3! z9VWwi>^tM_S2Tf+%t3xd$@h!GDg8g9{etTwNps%$avt)|2r@FD`f}E{=?d=gRpbLv zeKlrmf}RVcStsAPsC}Gq@M6^Nk{9)Bp)>GN{M$?GeVm$it2?rXhMuEn;o)=tl{Y^y zDWy77=o7=n>&;PMvO?!JpEfZjOXwAbdDgkT&C2&Dw0XK(*Bq9mYTcmiA-9 zM4A^DIgzG)p#-PWyx4|;YR`rJ)5L43`gP0ayrZHQC5j{IiaucfgKA66)3iz;+LHvw z^S$PyKXS(437p8#{Xz&zOk<03Xg3W1(O-jKrjReMd)**k3^afF!AB}(9%Ch94Z0%c zkN50*(7!itoGE1Ca+(P0W>Kgmn~%Ermpo0N1!W%fy3Ko?jH^H${sL=dap>n-Ta=DU z7QjUKM89~3JhD}KgG(pnxcBdgPX}8z0$I{6pC}G62RO4%Y&m>oJZbhFS}bRd+Sesv z;IfS0_J(8DU(G?9P5gaaPx( zIMPOpMe!Ge>ZcFgx||&<$JyB50tTI~4lyikWpwYtj}!Q%r-AO5br|)<>PAux3BxB?=rSi+v!W_Qw)-5uw)$&#%nwv z_xoc&85cK*4Q0m$Om^M7LF&5OT+i{>mTiTgjl1xWNOUMvjx%c0dXm5(uf#p_PI>MESF_#;mqbU7RBAC;5pCi& zYhm|l?9p%FPpHGVM*+yZ2~@FNVbWDcGzXAi_A_r;0fbp{!x||~IS*RxH05>BTKv}& z$@47f+%h}s%oz#djK{1%Y4V|&9jsnQt$6Jz4^_w{_2?pR$&&dnvsy3JUqzAbg^9Mg z4#o{?p7Vr6s`SP)#Jr{-YEpHRR;2KG%%!* zQW90pG9^Q)c9)ngrnf0E_4@FI1&(rn{sUaJo0AS)rV5-+O(;nrrV`DrDoQ!xrBOn6 zN)%fXS-+-SAr4l>jP8Adc_8H}L~0MHG5c9>l5E-nAG^Qu4`s%F#+wk-kZ*S03}*x9 z=JAk>LawZ*=v3!_yJ<4yn}n5Oi8gTFhoOAr3P9mNP!$i354# zM`+$jpM<^ieupE2=2D<0D_+rctZH0E8xkj8kpt&m)#Ge-HDVLS=dqMbFTI?fucTj(yUgr z#tSLC?9?`Fd$U#?mdY}W5aC5yi?8VumF`pG78aDzv=Y7IZWz0d5^)ij|2Qgxmfb#m zMIms^bAI+$9->pzL9;LngQ+${t*sIFW9oKEaMna(T(2X)c ziL>q_B&_JbiS~=2Fiem@iW}2Pwu$Q^EP2TdWWeZem};~8eNTA zS6_!0QP$F+1#JUGe03Yn)(vY*Phd|Nn)stHi3>ggvHZMzVEhS`al~7wbPVzJlypD- zis7P0bQqNhpo|ANp;nCJX>S*aN0W#;=NP&fy&4#}^~pyUJ1e35%6ZnZi)K?#iYamX z{XTyT0CH(a`%O7rRgxX+%4x~F!OzGL<;uy^w!*S^J;zdxvuB+S48F`;cm00FG^HaG zw1b}gY147Xtnc~Zhq)faT+{VOdII$_RTF)vVI0r&E$oybhG@%qH{xtC=YaP>`Q=PJ z5dW8l%%rb{_b3(T4!gi&dN3yO&4EuAB6!kbpOn?uzUs7O!K8%Wmc=E?jV95dNpjkC zmbx7MAfPXSfR{{$LPI9wXucJF_8U$^L6i=1+(i!brhM?IOw1q1GcMUk?-)kc$~p#$cxF^-qe);?ucU)G8^jVF zIzwPno3P6m4HUgpP3W$ecRJfRlBjOI+-$WD%=J$oj0_`=b=FS8!u;X@H)5FM@01@S z#1ls-O_7Tkn_yAwrzkeiYPMZ6RzR08VfPnPRwP599Ot_ZYn!%YuDF`wNC)*TXdmW` z(+itm%iEm2qDMuV>AB}J#Jv=d|FO#jUlzWs3acJ7B+N4(ZUmPYe$A?AJ@t(*sA??x zx4R@C52O>#piLKLucIOqIOaY-aIo14bnF+R$)GibbCIJ?`mG!1WKg~c0h&bll8xfP zkQeHCvFKBnlJ-o~>f60Sd?lLUxwqv=e;;`acOqEm`pfMuF8_5$)5+X?TM@VE?Y0CY z_1e#2U@ex}CdO9__I-ZPW|+rzYrgH*vtb9bB5F*=eWw@?S07a}y{mrGD@F$Zp{?eo z&wD=*I0m@tJJ|Fnb_F1hR#~=@B9*s*@Zm96IEXf*1sqYG5aCYRC=_5U^Ig#6zBdrn z>8kqxuD$KZTVD5`inhZ(3~1c}7X{?l6CK9hPE-l~a>DG=r3mZyd^5lpsqyH#-}eAU zI-{&P@O=)DU+VnD6Qh$@j!=uyj{06JHBdTLTuxD{gSwQY2#l1fU*mSEdQgV5Q{e^- zz8HY+Sc1r}^%mYTwCO}vW_~@^&!FPWf<(JH$hhFjIJ8W|`rAYiKQ&eqUFJIuD7|T{ zdJ--ydZ0|`NrzZ!Yvx@bk)$<@|B9s+Xbsug6DZ@}+;vd!urCk2jM_st8ist54iV>3 zq;ID#BzX@;3eo@MMp7`VNHd_iUlzJq`s3OTDdUqfIXmS&i3D%Sym@Msb34WZ$_|oh zE%J^QKNxx62^i(#)_x%3ePCImd6c{(fJX3CDZXq)fagRLL=(M&xl=dHVmz0c#4DdE zFj_bJLz@jU-Z(bib?Z1DEA0}~LR)_E^HEqbUEb8-`D1nrVa%I$%y+B=5o9P#FjvrF zAyj2~SL5*uV-CN(K}SS8H~w4U``%i*1zbiV83kNMGPTaXPNJXGzbM<}`q!|xYvORQ zL3G~w72B*@lo5$RO>7_^IIaJ3 z6-OH|IFa`k`z+Bg1-@=1G%|=A{;c>0QSx8rxWn-|gE3P#?0OLyBY=K(_fO z7_hm+U#{ESfY6|?H{?c@LY}b97v|9f7<8wLD?XytlecSQWwOkZRN@?(3Ytg=nzX1m zhKULKUkAmA3DRBnL+vcGgr5(#Pr~7~Uxz57tI3{>?&or^XvTj`zM$kMZ3H~;N#20! zUa6h9ljDW+HN-Kp#(pKEsI=6lq9x-4%W(`R8=?-;s#j4H6m)5|bo~3nEnKb(N8ov! zV1BDbk#o46+O-;A?Ex1*3t!RjAc9g5ak#x@2tb*tZJpu>3q6_g_zX6G+>nWT#v*c% zzzSKo>2n?p=ls`@7@B*5p{g!!!=UTw^i~11B5HF}AYNabvwe)X1jg>2PTVOLuLHv9 zsMh1l$o?a6%=zm1VAHGV7XW~s-556I#rgpmFU#Py%~lITARX)Vye=b*H3L@dNq1iJ zqg;6VPt*}`Mmf;Xy4#M^9Mg&Y65Qb=zz{x>I8LWc@>JYv#QAx6Eq%mMYm9jvlmbo_ zX|hdDW;lnqGBy%`h~_(c{aeQ^>e7P;5w z1wt8M{5UQ2rAcGhi6;rLL>*zSS8L^Gf={DG;53(Mpv#y{_|3vp%)+!~*eUkCcwE{W zxp(dw1OW*KobnhBjqBoeShi#0Nlvq$Rxwj^stI%5NYMbdoHP@0BKO0#zc!KZLy1-6 zqeaOWDXzvy8j|ynG9+FmIHH|~Uqz#GSWt2qlM$(h6@%IrT>8-_;5o%ecY^pRg}}jH ziR@nL2bWAZ@sJ3WYy}6&Y@vUxp^k+_kgehd5~n|Gw3jVJ1|h#5lmBkZ+jjCmomg|a zx<)fPx$XYd;9o(=j&+t~7aG31Hv^xxQK-Rk8*1#Mf9g3bXHML?nRJ5-GEmSf!7)q* z#idH8)4zF%k?gZ*#;HnnlS!w^W#efb2Thu!W=@Nxlqtpq=l2gN?@OeO1p7~_byy{{ zQ!-B1wR|CzBUFX-W(G+Ku)>2d0=SvGe|9~elXUt^K_$*&v4z5CC0rV7lri&Sh(NCB z&IiYKJ73cYj;YSt9kDu_QK8+~`Nt+*5Wre~%1*L+DLN^^buvbg{oL?(T$4wB<=e>^ zFi=Et#8?LmaksL<1Y5R&EC~!G@80wTQzYp~urN}0;N{Cw`M1pHY4NXXk=;p%pe2ft z!J#DPYz^YOT_19$!zDU|%EL(~-D1kaAe7ThYCp#`n;f1(Ql(VVt{%WkvJ zl*fMF{H2SP9a3aH$$0y}=nHMjB@8Tx8DT&G>8tmca!?qBDfQ5!G}eO#{YCFIU~eZV zurTI@q=$ohxITq+%Mb~?OZ_mr_+vt=2mGuBcZfD6nVZBU;Lcn@#q=mWumwzw@1~5@ zD-5z~NJW8Q1p8uSC{L8U<;MTzCu(##!{VoYnjiDtz?&)4fQ?aY!L-LjtjDD3=d`Da zW_g2=h-O~8&%kMt^6jVAMu8}sM*5ZLy@3!5VGVyo6}jr~euD}nG9IWk1LmImn4z#f zTGFvp;#$j!!CsejEl|dTW66f-lmyBls(j?HVD*wV@ray$r>biY z@quWN&@SJkK-al_%2 zwfFVuazn_VC-9jVCxH3ChEm0U4W$}_g?ln>>wjzxRa!NVAdH_R?38~LqtIw)!KC6b zdfpY)9kJjRxy0;i4WR7K|~B)86iKuYJR2Y0gZ=I)a;GeY-7 z*#I1c8!3}LEQ9pN!QJ)SW`N)f9f;xMS-C&KIT|>CUR-^K*4Y}+0%A7lyFkd%V1UdS z4NkY^stu|`OBW#MgbOyN^vro5BJ5TJ?)V`812n02iJ;6`-*MDn`HDb*{iZ-i3q_#(^h+3`(r>htzA z3^MeqE=;IywbE*C1wOHN)OE@bwt}dp=xL0T<}s2S;VvSfk)|-dj(9Jg+G!&pB)8^9 zxdDag1Ps#oizc6E>u?*W(eGZp6#v7>n@?W<=5NsS&LUkpM+>S(vTt^uL6Onsj$w;liEH%3h}g$XH<7grj2oY1aGv6nIzbeyeZf@9&hg<3mW)=X zMTr8vxo+Zx1?!)8BFgJMfxgbyhwi`p*tc@%W5T5M_zZ-l)&Ji;GIqp%p8d8vZM*3vEi z@kR~m&)NXqRAckyQRCgU%_5VMF@Z?QV0g)aG22Tp>Xa*S38|3OqE%mv})8(G=6>Ey<1HapZ~sAIAn`#OH*0rn~V=9(?%8tQ@@@p-&0 zADLHQm;VDhJ}^qQc4mwY&H5tGzK?+lXEw21{eHu5pn<^{`QMD{d;#MThVv?GBM!A5 z52g02VA%0$0frshVS~G$I05A}fg{3`6juBtk@DhWmACL5hfAm)W7PvD6rQAQ|NL}0 z4(@T;HeroW&;!Px$oa`kerT9vke$1xf4;A!+u6!s3+YY_QkFCjrBKCW;w0L!4fBY) zFe`jY73*qP5bOH#7RpgX8tx&d(wi{rFkeM->@o#blQ_yOCG!3)H1x&$cXF=O28CN! zE8-D7^T~)Uo~QU8EXWrZnrCaYz;UY1CN=w(lNgP z5Xu;!(whGq5{Nth$7Yzr_Q1_#6`BN-%=H9HSraDf)B@0TmAq4NlI)4sQP#4dBJJZh z9p8x`NvXkMm{;EyZaUCb_pYe?qHcKUP&djE{lPR8L>O{O_6sR5cV_nt9y#JliV+>e zN2G(`sGIhM#SS#RJ&r-r8rMV6w%H26s8)QNsM0I0X^AqL9wuC2#`Fdt)d65o_knE5 z;9t_|meS6}Gzx5a?WVpH<+kL9bEsbe%xZ7DKlUK_-KB6}8FN+#{Gz@WUm}YC`Dyk9 zp*z6GJCh9#%*)j;P5>CJA60q#^y78hIUj>wKWO819}?;Odgkjky}|p0XnX`!KE09d zd^8M{*+Q4!y=bah_fMF=3>-#l1v>o_sb)`7Z-KqL^=2R&oO@n%zCnHaba68oO_*m7K9NVni zpVRd>p(l%n5}uj%h|U>&;XODQ;ROx~;|K=+60A+AWziR*f-Y!CoP?vzoPkHuZE&zX#@QCKuLo-cS{vwW8pIMJBs(-wTB# zE1rSzA0G5Z(Vtz3+1$9hkhI;UwOBH!({d07d|8mXf&YhqYl2#+Rp2kQYE}zpi7#OP z2k@>?{~9vj|JW$|zcpJEh0gD;lf?X2MJ0@nD2oD>LZePB%iHo!5`-IU`##{yvfkb{ zbB~AKq*>+AVl~H;VouvYX4ASz(qu7zd2l>!Sa&~}axc@q|C=rGq_-A}1)>R9Z5S3E zb!erLe99epZ`d(2S_9y%bIA_lz&L6i5^fdEc+~;qWC;KslvCeqFtsJt^W2w{d68Pf zRt2FKSomJ4PkKEH9}MOO{Qfups_|&;@bSFA*<)6?X-M{8Js&;vTueLO%8C7JPSkk-VlSPK*RcQ|+SZlBzZAMum^q!zaUuSg zr*=nG2oROyXX(}PP=f@}Gh zJ3=bRTY62hvc5j_uMwacPL4C$B(Psj76P_98UeoX|51aFkKB{H+({Ok+hqIK1NRPu z#=sQHrn$rMeln$ZCcrI{*6;`$BE+A_q~OB~x}MhY#Xr@iX8b0@pXMuJ+M19C1;+E7 zG;PhGHNg%PpP&2saf%mBpOa4Re@dUis{&`JX3I$nSFB!>#Sv;;!Orb7@%Shx5B)gA zOoGgg%ffT9D2EYd$Gxgpw{s7kGuQQ@j4zoTLgl5&0T!gX87b{Foe}yiq;gnj%Jb+l z)d}v87fqVg?(yuHU8@jfydxiv9|kg7JH&d?J5r3YMy2|#OuV%0Fj3R|r}So_Z3eP1 zQV*w5im%&y9Htb^S!ZxKYNOnsjs*4D^`vh#-43 zPkU6|yM?hsnu2d=ZvxYo}Mgn686@Z za-O0i@r&^vjy^$r(!=)^#;H5&Eg(tG<9Y_sDzF{d`tji}Va=1CGJA%MKSQ_%;f-7sXWsAfDpRTSUywkH${ zX;momLsmqC1AnXhSV}AhvgoCtllIoz0!EGcI`Up?2LlGt{tjXK5;VWS$#a_fIx9I{Q}t8gndeaqg_D76~AkuMl}L8)Pduc0Y7 z?0ID9MB*Z2XR<3&wy;w0HjYf(bBUH0tU5ZEJQIv~(xDQD7TBOfzI+jf{k>&~yj@R5 zW4ITVxJPeB9;_RLpfXk{!7n&whCRFX-=L?dY#n1Z^KND07LETpm`x?5YZ=Pz%hOY9 zHTJz1(YAxJ54AE~isG;v&^C97@kQMxc!%c#?+!$iG+zJOXF)kKezF;{a{Zj}C73vZ z*F)ru{7F$8np^5Fi-aYJIjqRrMz5FQYNK=Kf88l@v%YQNQaxGXp9elLGkid=cJVvPAKc~djQ|0)8Lp?_qEdf>WHCQewwqBWDx{zDo-(ypbGK8MGO zlU_$CKY>{4r#Gf0sWmkLHsTDMISh69L5nr{*P_;`yZ=W1u$iWptQC`Im(E>@rWcWS zz(@()@wHw4+lwyrx7?D0F$3p_`Mn=J2MUZ*Z2J8B{KYiM(@% z*r>jxU$6wI)kM{JF=&FmuX?X_WEDV2Q4u7aPg@%sWdp^ z%#(5);uOwtBjftH{ZtU>l_@_UFA0WHgjN38Ldhe)gQia32Byl(*D8;8fe z8ES}7EnI7U6QW+0ksAu8PT92QSjo-Mr%KtZKA1UbV=^a0vXIsd#R}WZtrh=^tYz@@VNmb()Rc>po;kvU zlxv;$3ceh|1F7e_$h%1JZrOC`H>95+6hWn3oPuGbl-3p5sGhaBXzo$=y?DZ&97uzDt6)4qF6Txb&boG=&RAGgf0h= z&5^ONr`);0kVIq2X^*Ky`49RAA?s~dUw**-g&xK;o_LJrDq#l1D$K5%6SSseq!;3q zu3sa5GMV5}{TwMP5}+#ArD2|ttpkM=7&2n7c-g())w7=8EC?X+nk~BKWN`5`uUx$D4%pf4>YT#@|@Cki=c+m|n<&eFC zpY3g_r3ycb7h%8A*GRwvdD?wBB?WVtcOm&uO~!XnyZ%j zkJ57@-IXX2ByL9~@os~%Zt>#{?bTgmObZemU(7NFwTDqSvcR+aj2+gr=`5 z^h7ZtMgd$eIAC=@G7pGeX4}_J%d@9gUnYs$TBN`AH63W_blN99{VnV46iH1~JxjI% z4gH))T1}fJVViOQQ8MC-NtXD@Ecv!7jng>VTud=Xsl)PXWJ=_;!Ivcak4{;ir6Yb) z`XKv@7C2gR&ou=Jp)^Pa7tBohs=nX%)p${k3(d_s#l8}Vjrg|XxlE)ji$snPMVoOD zjks)-KN}eN+@Fp5;VY1EhpwYiNv?I%Nhj<39w{DuRtc@uax*25j`H#8)&@|FvDtX`R$h#fcdU15>GFDz{vAgPk#wbCcYUx*P4y zqoIEL*{Rj>hwx{Yul>C3Y;T7HjBI0*>rZhpE7e)jG2|l@7vUfoNGIH)#g@jm+8}`W z(m;M_H7)wGYrO#;+6`a=d{dMKT4|5~0x{UXnSZf%pIr|DMp=xYx+W%?hulbgZS<~W zV;A+EBBV-A9csIYqWIii8l$T=f3RVL7+azJfd>pVYs({*pv?;EofEJzVvkjG@^J3V{Nb+((hwW9P34I+0f=J4v$H5NwTne=AJB!$|7Cd zJjet`oMIoFTu)UA5p0Sb6ll%M9?oZ$h5X_vy3c6V)yDPn`L90;R5l-tv2izKg?1In zKpfS-;U?A{s(yA44E@x)FpiF%u9}%G>i-Upmm#@+#biq1+`7t+>8$EB|5H}ctg(ab zR}>5J;Qg7&eU(Z&L~3VK#WG?GUOFOEi_P`(UM^l9&c+~q6gKgs&Gj-3`hxaaQq{vE zxiFrud{ZyDUs;YYacXhko9glBtJEP~@z=*(4)oQI9Bo+{HiazJ#nVcW?p71-U#?;_ z@DPui;8LmJc6J3^XIb!=;Plfj?M)cTX2t~>n+(_s#%~63;|*=ju2auv@4FK#)4N08$y0%g$*H{EO>4&Y z_xfr4025tSWQVhQ*Rew!TvO{CHaw6;goTTfwfW!;Ola(_OTupIyH@{BkEdcgaEjTk zVD0B=`yeZ)-RhKRrwVCBmp3obgzECtJt=PByxWII3PlcT(X$4_ypeT)lc#I_H*6&Aej7d3L}Tufs{ zaIrF{c9;~OgYI-(N6y$DFhSWjg4~-Vi~FF%vtCe7TPLse7xpdxl!G}3Bcq7MGjb-2 zV;aX+M4w!&coc)SA7#tjF@t-9nkb(>E*$g6Uy*VU=_clfsu#+XIBM25AGoHQQaTe* zUFpa26%3wQ&0S%L__vW@ySu8Gn1?*jtCy~Ir@plieWtbjd6aI7ih|)jdot+E2`L9h z33nb*vT>5ZED)_iJJ$A*Y<2hsxW^9v_O&#B=If-O$WyPnAWmf&MyoM=(^^&U5{{Un_o4;y?vzvpU zph%Q&Rfe;Pt)Ih&3WibG&@+h`8_|v|Gk|WB*a478pn8*K*Wq4j(zBa`JfKLpZ`HZc z<`K4Hk$4B=o0%N&tue!bA1Gv397x=Pu39A~^t(C89kO7%ncW^L5Ziev1TtZJ-Gn~Y zZpp~v6T5oUCR3xjM&;Xp?lLuZ4i<+@=-z1ZGjHqvax`}vrei zTyB;#M_d0Q;k;E@&Q_4i_YH5Uq|w0ERARq6T<>;cmTnHpg-p2KXf`u%-~Y03y`U7;J*^@rPabmyR6$b#-19sY|%_f};vTg%!Gaf9owjcq+)fF}3o-_Hmy z3gOu;(M$;6XyP(213*~_pKC-uGfPySUbETwX<%C;{%oKW2Jmu|mO1+P7YXpKN?Nvp z%={w4rP-}v!PPU^O9Oij;)N_=&(X)fK(Oa+^IsO&i6A;on;XI%BX7!AqB>yjc1Nvl z4w8jTz|I+uD+t(Im9}ij+}qkVso2;ZtqWlJXJRrv|= z{+Rk$9M&0s1j_{0$e;qk8TfClq5FWxlfhWwHVisJD1`i>FsGi&zW(MbHWUUHDVnY( zz={2x=eU>_RlmaSbk8zWlnj-d5tZ+}DH+O3CQz0P$!z}auQPLjYx1jYZMc$SbdB_szYL?#K@XjU~ZH9=_-LTS}NLJHVxP!^DxR2cW%PPx;l zi=V})NHHomo125}phz*=vTQE4GmThl%WW@1)9)}H_LVq%g@RymstLhmws=UBG2Q zE9-N^diX`DhBAw`%cX|sZj>6LTM0G9x<%VMaOcoPHcsA+^f_J&h58aJ2KXkW?`Jp}Ejjaz(&`?m9LC?W3@q-^l+sChe z_5BUgrc(pEw1FS{(E3tysJlL^v-!?@72@k4Lb9iMOScI)JBxnvRDjgm!lw~H*I zjfLPcA{MdKgQSa;k=b7GmFU|@1(&>2uz_$~Tl76Tp6pl??urR_@U{a__pioF%#jmn zGNkw?EN2$79^i?%_+a<5z!fEMl$@fwUE~yPtWCf5LvQ!aQCuueVIO4Y8R5ks zyj&iN?nZeiy4%G=(e}IX!1+?nap=y4%Gx(Z;g$0Nc9F zVHB7otoDHO&I7vK`o)dXOLQxtm&gFU&cV% z@upMDcG<<(U&*4rXLJ{Z?ozX^y^V5A^tOv*qD_V2(mKJ0o)Y8K5pH0apSje_R`qT6 z3y)aEk-=R@d#Q=o-bNWFdfUY?(WWBrz_|=cwu3$v1bk|~uLa%snQCnz1M!+H+xB_1 zu;DX^2iyQFy5a3^FR!bUjNRrM>Xpk#(c35^MQ^(pDcV%G{ml%{+JeGA2q=cIS13q> zYb{F9Gxm$Zes&``6ZSWmpzUoJMMaxxx2b?(tWBrfbfRZ<9M|@A*R!c5G&3#O8Tz;f z`28^Gu#Q6{T(hhav-yvnfSp4TFS_uy)`Z(aXRjE*K;T6VRy)|1HyX2R@yG|SR0(*6 zbq>2OMx~}*dmAOe=xrAXMw{xj-z*j?pw!TDQ|Cdr`j|U-!U2TMMWS@P0F0?;z!wDg za(OX&8|B65Z5J;F0N!sAhA74jPnRZ5K5L0NrmD76Ce)L?KQLaFJayd!CVA0@6#()%G^ZiqYFHRt!M8-zO}DbZO5} zDZ(?v%Yk^g3EO6Nqo_cLS3-`F1>%0ku;7UPrS;l!&j*433EwbaMdK)Fk=xrB4M*FDYGj#>1etq@Bx3}M1Uq2(e zcx0EGj@>9lMsK?)G632B!B}-RDurA5jP>HMUM^uqZ=-}6z3n2*0Id6`WM{U?_up?q zf$uhnXs=w3j9zP_nbYm!$N*6LnbQE&kzQ8MxGoUa<)$(>N{!LmE@}+Gb!#5ikp%rS zu8YHUxhxpHjj~|$wu=P=aP4O-XGVy2&%c@eQWbWI&BJ=-vS9Q!%7W3Wgau>W=3ysC z?1Hj3a1%=6RL1w*-fe>1Ub*}iy^Zo;^tOxt;sm>g-3&u5TpYi$YO3jX+9=fYWp<5( zJJ#&t(LB|d$+bNP>)0)`!s8peE(ztPF6BFKN)on<#o`1Tja}l&4Xi-N`g1y+G=~41 zJcWqrgei|_pgr@TIjV`kpgPF!Hg8?8Tw03WMrkQ}+eJ%pg3ZIuWhn|Cqc)$I%k{A- zbj@IfmS`$S=3#}dbx?tjdDlywu?LB1p9W;N$Z$ycQ)6pktu$n9Fb3~ zLa8Fm4Gp-X+hXckHa1wrvv|k1m)Gk21|Ha}uvBZ;1)|*i=tfB;dfP=Rae{5WmI;Iy znHF{-AQ{lde1h#DpYY@o9^JF-fk6J=Lx8@+_CLP;L+$e8+dsYti9}dX)NxjU%_yG@ zrNU&TTxN;hMwumgl`u22n+|pSj$yMUc|K3JQ^in_e{hfXir}1Ib*SHM+M!+! zT8&Jo-)I6hFJ(hnsGl!apW0U6;0SkYWuR-=!(%AS0kc5uYkmB$I~En1L%R<4aZ8S17qluxO+bpf0Tkk?+P=~pmrbmJ7z#c(CCauC1jEvu!DVQ*mPvPX`V_KXw(IA$ zi_CB2!x)~O)EEHn2Ht}I78&f@xVH!mx0qGI(a%kK+{3cpm)!I4WWX#Gh^Di{1gK=N z@~eePTpRzn3GcjYD*E~29-CAw6NP6652YG-(v0mCI5Qai%ci*AY1A%)U9K36WYA$5 z{E8JI$$j#|799(Qjx2?bVvsb!qd&8qBZ26c*-4Rf4HOrrlQ4{^a4bk8|ge z*)Y{cd}cSmSC(}*(d@fhSF_zbPFlM3qjJx#&;O2na}SRc{9*2S{>)vO zgV4M!PEbKZiJyk(Bou+-=z0>0o8XK$yUS5bKENSN)uF=kA$fr_sK$a!a<(jjtUEV{ z3lp{!5o=-sd2oFqIrtB}5BW98OAc?LUUgyOn=fn4D>5ZgO?>onIq~wN6cewR&I7ld z=(HzH;n^GYiuk(Na?y49Wa?sFi@X)l;8`a7(c_NH@>{CS;-SqAENQ_ejo4!de?ORW z4e^r+*G!CfTSHY4hS5SSBmjrs5q*3M4!5^lEFH7C?ix=%K^TW04TUZ=gWY`p?fJ#A zjJUkP5;Eopm(QLVW+FR!|8BK7Z1bwb0~_0#S+*Dn6XxUN+kgJvoXrl+3p@%F(V=o9 zBvpGY^gDK`Ju%ttjD2qkgCpDF1vg!rAFxY41#z5U#U8BDg`dVdm=_`kAn(4>P&;|H z_+rnq%~J=newuSQ5xQ+*P2eHm<&?(7HRuni zMian(p-uX>7>tO(Hw+JdB)Qh5qrP{zP2s~<># zvviLzgRS-YoMX4id*J})P$a!6T5*E|_8{D`ObT!taOGe<9H7hx<$+K87nW>LK66t# z#rV*bJu_dBs)Tltm7BzwtKDIC4Kv5xK=(1> zI@}lrT1ycmhG?Zj0}GkT>50c0r?r@nB&n(NVVxY$ZZfp$9DRkiHb{wQ?MEo5XFlA>{R@j7OpUws!?E=z}! z_U&}bhJQ~jbAWAUA5b=NiE-!0J$P0cWpK^m^N$NdICWebAlzLI;rQX+AF=vTt-W9l zuZD2^{T3H9{7R`qiRoSmV`$4F3L(!wJyTo!V-vzsq0uN0K7LxRv7`a_0-BvP&VG7= zw{@1kuyrQ|9f5kF$NY_tie8gFje=zT>}!h#K*Legy}0KZAdj9izinjSu>zh_sXqP+ z9`O0f9oU(2!$`RW(|v!)opjKQ!Q*UCW6|Q!CS@BfZu_SyUI%F zoiysb#CxJHNV>yCyVYt3DgAhJWE6qqs`PV0&ONNe$F4g) zJwASTcsLRsjP%H|N5{l=emsx)U}X8;`qLI6GN=hXtZxmT)agO=;vA-?bWt`8mJ-Onlq{{1K z*ipDH=X-2leswAC1%(g(^Ucjo%!MzG-oHx|`1|y>j|&B>37_=gZmaf=oGX@b!IrHT zR)L=8T!mV#bJCsVkdjwHeH2;+)0@bD2;&~TC0Y!M%hPu^Xt2;{b+sVD4{$OtMh)f- z2g?WMr7j6p<)7!CYpF}{$MCr}guOGkivF6rD4faDEyKdOlmnvw$?v0<|C0P(>>P#e z9^HSgCeyLz2*O;hC*#Upj5T3LS24vv@;z*sQ<7}d#)7=uA$_-eM8!V->=n2{+ulXH#E;VU^m+XtZxnOn*4q%Pz3;b zb;Q2oPY0mUw+u(17dD9_cI$Fsk~*h<^|^j`z<#}T;`U~<;`T;+f}0(%MSFH*0`>;> zyt}b=@7!5pt9AF))`2O(tgGVjKM3Ovlr?y3@GnDX6Zyxs0P8p07UmWsYHp^EW4*af z=c=`&MBV=|?9D|km)@NGi0&+hQ)Je|#_YauT&5Y06&G54u5?9QH7_s3m}^ghS8O_ONmRbIbhE z`y^IjA1r6Tr7?cN_S)-{M@*~(9tEI+BIrB!v#`e>p z%}20u(HBlN+_Ud*&zHaavYANx+Ao-g=d89Ml?Yzy6sA#XeoQN-I>7Pi<#BI?2}0ed z)p`q%D{9u^4_U&6o9Pqnw8bc^S;x-!&tpz(1R_qlHtgB|T z)d?;y0$4G=18p){e1|ksl*XM%?KNQ0;UP8RS4D^e{&+MUPygn}FHCE|kE5MDj#s-7 z8J8h?c_H$hfGrS(PZLPA-F(_WBI1QCNLt^j%e4*XMnY#&^9Mjy*X1hY zQ?>A@42R~`qhfFudiAwd?HV4hvA!+%klPesB4UqlWH{)8ali~rW5t}hTsgRPy1>eV z6Ijr7!2B|AETdS6w`Z=S$T`enD&7j6BP<9!@GHDH`{W2P= z0^E_a(Nxla2p0ozrLe`YeZ>A2>=OLa@0sNj{^<_uuze8D_KO47XnuVA-y6-WGLUa& zkJ#lmH`xVl#lx2Lo$m9I2ugE`cn&B&*IwRoguVLBw^!eNb@TeyY)^TKgU6$RCCEjr z*N*D-?#Z!JZ#EnCLzw)-TJ5BJ2)g?3T^5AS{@!AHAO7XTpMQS);m;rb_s{?E;V`}x28{15QipWu(b{QOTp|08_BKK$jwzyJJSKl}%L{(nFG>F0lfzu`CR!+)?3 z|L^C2{O~_M{2P4of7Ca@ec&E=-#_Ee|JR5A317n>AO7v<|F%c#61-&T>*HWoH`pg; zOXTmcDIU3Aba3fn%po(f)urwjoN}v6*)IJPu{lyV`(5AW$l^&BXmgNxG4a61K)+s^ z8BvQugF$knQgT>d)9;}8c2)W#_<*`Y_ zjBGIFIUkbM@nG4;-~r5wnXNJFqB^rWu(cl5dnKA5Z8ATaV19JK`iOQED?n18jgKY9 zN4?YT9yWTdlf(95=h^VsoZ%5!h&eRextb-3gnOJ>8SFvVgo*`(1>DY3TL zA9!&FRdrSLUMuSb^3Gsf8jftuq)LF;Mb20Wu=I$A=YMEgW+3Xm94=2IFO~=_@Gz{b z5J-5f(y_ZbMI__oRIrDtCJEWsm+k9|c@Jat6J)JaGOAbK1?+~th1G-<>EJGwj#8#Y zmXbTVkVc2j!1NM2p4%wlUHl&ME5$Tr%|)7G#4XL*)@!n~V=-;(w`s^aBXuM*Pg=Cq zY1^BmpRdl^Qa@;FC#bC5i6#up-yw!q=Wc0AqVJySxw(_KFE47X^Ovci5xtzCaowpm zFXb?bu4DTRcaE4mCMK4)z#uK1zh&FHLb$Fww`zL|H|D`-_&W}5GpU}PqP=XUCm#-k zqkGPZo+K$|E-V^&@~60&bkA-{v#*7jv+MM4cm_ND{L}I``(2ulMoHMi(~;O?{~$zB zf*Y7M9I9S>m+R4V?YHRLX^1EXTUZM+;CLO$)q;g+n z%FUaxsUBLfDOZ`WpF3=**)pd=o0Ep6Y?Ok=Kd`Dz9?LPFm}xCcc&G}?k|*OHc%L0I z{)kjuf&LHZqW0p*qV{GaK4G4ypwbI=Q%tu6Pg*oe;&c$ztdw_5K6?;iGC9)6N4hpS z()1(mPM%sAYCooIyG`i0s`Xw5WUA?5s*wSbBz3FpE+TzMy2Z-Dosl_2d>x;(Mx^k< zqDG`2=McgA(aEN(nk}^YRir3A*&t0tmAdq@cGB&nZ=4dnoFH*^(W>_@%TTWo219=~ ziTQ3Vv8&ESj?=UUV+lpQ-I=Dl^C6j7MLNHE zVX=KTGNP@Xs1>rjCrP%UyWe2wQV6L~|M=aX?D#wa42cT!* z3Bk#fszo0tqG7<~IM}#o;OP|7Vh-$Sk?Q`{iaDxjS1RV{`))`vGs}c`g}3B@lT#H5 zf_b=yS6`9ePk7rTeGPZ#x^Vabv#q{|DF~?vwJAO}LC8`|ln=YZG-A8*HO^d3o-Pe( z(m=9~R-+=L?H1EVL=7>7iZt3d1dGs5>}w0@ryou=M;GFYysNX)~eShnA+It|EmOXI9Pq3nm`bn*JK>yui7OXSO z4_;!OPN|ZMDn(#@zu0s4*i>`JU+hi3Y<<}_;6L^Hmp%EP_9Ne8LlANfPa5u_QnK#k zziA}&C;Od+<&Yq0a1Q|+E56YEDHhOr@HX^s#(y-w*b_qr?l8YZWyYrBksDvZpFfC! zJ7zRB!Ih3TVPDo*J?7&Y{J$?L_#J$Vs)v2qfXm5Go%_7WXd2`L>0zrbdd0 z0l|=Betfdz$(`gU(>=TDn&^wh{C?S>>b3A4j-wNgD+_DRAF*T%wm0jJ)^TKmn}TUx zgc5${A~JN#G`a4|d@|@6dYE-;Sm49n<2?Ya0|A$6&J@12al^!)%Etz<3@{qTr>KML zvB%`S|5F&W3ONrrJ*Tac?$rH!Os{%cKWQGdr!GNFOh6U}nyZDvIvpIeD_jDeXJUg( zlRJkpn&*#5$})*gae5}kN4)Ny)Y|PdyH7SBk>dZ0KH@w_YOnQB_@m@JHrbV^vo;}6>p~~A!ALFW)(Ytj8bCNzQ5XC%! zL*1cxm8Iy2eYH>A-I|y<=u+!o>AIXcp}J!*f6#3hag(E+L9v*j&C%NrGUx{kHhknz(K!44_Tmv?bpwFAQF8s@+`QCKT6qyOU9%Y2AV<%T)b@5 zYw2q;qOd4=oma#%vHK91a(pD2(48m8&Var$Pr<(95e~4KT0E`U0sUVOaDLKU0_CH@S$ zBT4=2l>**?6cU$FvsNl`(#%^t?n?3!MC?HJF!BrEh68j5tnazA-^i6fAyl%3y3{gZ zmeFaHsugbNVG#X@-CCj9^p(29`JL42_&a+(rn#>gkfX1PBg8Q&_Y+kj3N3$uKi2~B zjtk%e9){o>4`z!97zphd!MKjtn+M!sgiEu7Et`c+og5QO|MME9%kCLxU8Lgo-VpFI z(5p7)_*K`~B`yUPn9{KBeJFL%u_Xw8G;+khpL^MQ=n4?x=k zDm;HXnBhH5fch7;1m~~~VsJaq8^|0$IvYO?D-L1mhDXdp^tIe(!G3Yb9t*7lEP(o* z%5wPkF5!?_h5imbf6?FR=Jt2iK4ey$zvJlEG>5lSZHLe#9UTLW7;i^?lua(z5H8xN zWjQiKpCL#)`kUzf{Sm9b00F^osY}b@fDf?_?*Kp43@T(k>{}*kHp#Z3vxx<+3o(L$ z6{HlRV@;4xVIpL96Z9lq4WGK8E8$0hhD{@d(csp~sg8+-sgJU%Ks#H?X6b^YxsNoZ z&`u)F2Gbex9%)i1R$su7$4>*>0%HTraSJ@y{W;NC|E%81VY-?JkLC*u-s>LK%iDwo z4MR)?;at7=T>0?`VB2S*K#LC9_|)98d(9T)i@}gxOO|q^L1M--o|tU0`ltkK_rXNSz0E>r8vmJ#jla|6$? zsdsX`DLkB7K+QubN^_U^eoHhpx?V1a7aQ{d)>V`};uT#0SC9CG95O7{#B#_SnZQD! z!9vFjUL8)vh;m#e+xI0+IFlDg?3MMv@6q_d9~;^e=4zuJSJ=HYtOth;J^IQfHBNqq z)Fp;+U93Q|(a+aqgIZTQRCHr3pTYOWyL$VE@iF~$C~SE`k2n(Of82b3^eoCV4-+m^v?|b7YE@$A80IBHEIA64NTTld*T*rq9hW9 zmwq{uYST$r4N9Sut*`k7KU8giuD5d0?}ht>9kj!dQ$^s}tzd+q<%MziYY8j%!x;BwI{l&IjQD;s zdZ83a7eE3u(_N-A*{+o|)|0pFE zR0g8_{kxg0Mt?(2ii#Igq^%0f=Tezlf_bT+X0*_{fsY3u9&I{X2B%Lm4(1Q^YJBbBwLOVxP# zIZ%gFNpt{TSujnB7qoh1@LwS)Qv#-W*{EY3S=>v+sE(L8pt?f})sZa@NU^QOIAAY# z9B@T{fuxy`OMi*>lbm8jT`99+V+-E)ThK7p0Bqk|O1-9v>&?GQs$t}g>t$Z*@Z}ko zx|q10-%%$&0-pOUB`SOA;PxSHX^+vLH7w!@&lOp-Y8yZ*w`0G*9&G_HTOS>tqTpQo<9a|$q z&Ky9D%xY>*os6>@nJR0fncQ(KbII$i2s}n$o0@&60N9>kBEtq(UwD&5peC))!K{^s z4A0D+_@0~1q+odxa+D%icI(vlnVIQXag{U)SX(nP1?=Rh?z%=pGQR-j#iwi*G~$o= zF7#ncZx*a*va#AMAP?}yw+v*Zl`3fhBQA|0(1<&-yK{y>hQxbIo;V2oA|LCiva$R0 zg#LvyXUj`2x}d(rGSjn=u3e}Sp)rjteDAz{)xKQ5@M`#x!%z+S-@LCv%a8=_l#hyb z?$D-FgCD9gBtAH#Nsx<}VodMf6)>RH&xv0i*l8lQR#@=rvavVO7Gl#m7M}>n41)c zcze}Sz4SgZQY8zkOc{A4!VFc1N0@msUF|W*c!leNT!6w8qT@3gV@M7^TyKZ*)R!|r^a6d4c`KhkTEkXO!lbE^uh9s z0WEzd>`e^ zg9l_`^_^)kZE&xFyp1?O7y&19*O(un+%=|05byJav?N3th893*C|&B$Fm;re&9|5c z17y*CnoYe7Xh>U8C8Ti=2uw!RfdS#pK~6|n;IL*@niScN$&<+@0ZWPi=VrM$8{-X? zmt!sX15Bk7)5x3zuP*yY4(`#}!3&8EODP6lWzDi8K7DcluTh}=l2IIroofto8G>rW zWkHn#D)I?a!vtI*J1K{&C7vfQm^@WTe^kZhu_IR0Z6Lz~;Y>kWZH*;$fsGl!kf16P zb+kgG;)zAmX;#7jza|?>X4ufEMiT?O7}ALc3llZIz73sxgS|rY9)%(1DzFdaULn(X zhE)E@k+yQ%ptDzj#pR!ZOxD;ho3)dALflj>TE1*kyb_;Z{S^8;l-7R#&e!1ZuRw9V ze^>Nd+TP)J-!JY;E7W6cvnJBNuTig+w++Zkv zgeUtfRP_%L)}9v+cXU}*RpY`Kzk@m+Ub_B96s{u zqJ6F!46XG@T%_WJCgo5H7p=9XfGKRF9Lk!^MkjRO+%Ew@&jNe|ZtGayb7hXG#e~6K zI+aev>wtc+O7=g#{li39Z64XwmZWDN zy)X<|PqF<8C1=2RgWcC3cu;Dj&dbA3u{_@onHLMAGcC13S#MQrj4kSxfo1;6Dblqg zRMcLYCayC<{3LA1*?A@K z+BKUF&BzuixU_wZDUJ3sae>6Ag-koOSgg6yF|#dL7B*di$~}?u8%DlSknPTzbPcTyXs2 zh}{g?1g23;4ap)eQ;2Xa)_{-$Gvg$ZZC{m>hNd<6T$X|9PIY!RRJ-aw6t{@E^Rshr zy~?r3>N2FcXWDK0wS`6iyahd8244;9fn$moZj7ZWezRDWJ}7)Ui(XFPRv%>pcPiMP zUCmYy*`@sabAU6Iy$4K8xsIKpnQmwf;lxJ?c;TV6x~i~~e@oJ>*_j@{m>L~9d4#}* z{a2Gm`DH<~YKTo13oL%LkRPq@S$G+)3>6!}qin2Jz-nvT!c@8Jv7+j1RA=Q`-d(nR zolyX>*K`GbBUf5Yi|5e8XVD5-!L6Ctum|ohZyc&bm-i=w6aO3v+i}&s_JgVzD9O?}ZFNsC*Vp54+yF_4#573IShV<;ALE>exe@+# z9>kC0C%Ktfg_S_Du#lqKa?IG>AeO4EtgKwWS2da9gwwt}fK~rrWH#yj057>g~niR?SkDNZ~ zPH02N)GZtf?}HZpec}dxStEO?-DHmmUi|*`^g(~;m@`B@9uNY;^pRgs`{d@zX+qWC z+=NPPAGZd*s1Mb#Ms27R`?ZZX(Yv$yQ60znQPI4@7F71@cW*D=v7vvWuV29NHGQSL zckJ2qIgn^{-opN+AHNvhWZptdhmZIu{+1j(HcuN;|E)K#My#OemBL<4H>-VZFz6m1 zw@+ThhDOjGM*;bSYz_0pF^+Kmf`BS}?UAm3H z%bU+XetQ4;{rNx6Za)9`-T!HR_wgTRA1_D$`)1g@d71-yyJ?U=+CC+fqjQ;6f4G!7 zM1~lT*NL~f;4lz;SM3%FH3kL)3MQW0Js3FG=k1J@CX}(RY+X6?unw3M#`D$96299dncME)cpCe}Z{&&?ktmvJgEN zrR&u2bkk}n!wKe4BGmI^91c1}t3%b3hbcMuOuWE5?zA8mBy;g${5NPx(csT!{9)r1AC8P zRNuw!^oA}@KHel)Dh-sO)Z`ad)cZB$q_IBv!dtMwb+pzQ>$3C3{53*3Czm^-({X=% z*iS8W7-5QmrDKRY*CQsDn4G>K^3>iK1 zrDK_2ZiD;XFdFs|jahTCFs3Ff9tf6On<;O&gh7KK7SQ}Qz3j=KSspHzI}FH~{~)2P z?9wAtUlnJH9$B$5Q0#ce*t`QCKi9j|&PD_}TWAa-Q!``v1EI|&G6{B4H7Or3*tB;9 z9)$kbnWL}fhg%8M)w+rA1ChJUK%Hz*?qijxoP>NiZ(p9vH=E3oFYFCZvr$sq`fTc+ zE0pg);mA2S=ai+M9H2%=02=t$Lr^7?@~eI^y``gi&mH%luP!eyhwpy;DCM{piT(_d zCT}N_@=L`w^!N`>3hb8k@~j4 zL^9S6lX*y3OC;`|w(plz8NqDmqQsTN1&otBANx6DGO4mk=2tvmXh##>ve0PrU981$ z*^h?^F7_#_UDLizjk}uRfR3*X2#!B~pNRHXEKdOFQ{aQxrE2ep5L7Yk+rUD|6~fK3 zY|L|I+&4yGKNI_ip@4_`%*me4fkyz?jz~I{m9W*=o^A{3e6_YUlvf1*%;gq}Y%~g~ zAPn=GUp2`0*Tgj%zWw-)Efg~ulcz~DC=!EJv=z%-5{4l@9OP>==P}NdI(~=X?Y!mk zIELoSgFCD&P2%|A5pmh$V}~*I>~>pfx1<`cwbZsa=}ANi#t&EaJ%heu3&#Rv%q;l$ z{q@_6k5Zx0tR`CA2LFUb9{UsJyMZQ-;Y=t+j;5c7#3{EDiFieZ5JJ+Lq zR+<@wN27Kfu|^7P`+IXA{uJHHhr@k-6qbxd2RP&cX+&egz*g0W;P}iJ`5NY-PrL?2 zvcp^@PzF&s^c2^8h!KbbS#Ua0X^RfOp%)Oy`-3rt`#nR(m$nU>NCTgS>A2w&xOY)L zgHSMFS_X;&%4%kR9r~WlZ-HO%x(O%Cny)KdT2nE&ulO!B3;B&d-PN_XGI9hX11LD!;z``KQU%&v->+ zR}O!A*Zi6O^+Yo9g*CRz8lxL^bnxcg;myJ5kp3__pg+F3(GK5?czeQ^W&i4yeW^~C z6Kx4gJ;7BE|1f!3@~?ZzCu(xRm)huM!N1A{e+Tk=q`d)w{$_NejZnmsq*p<_zbv`b zlBcWnzB6oRX6pDtUauEip{JhX;s53ac_gI-+(-!p^+G%DrYnr|!|KV~i9`6M7>Dd+ znYDmyTU_ScaQ@CVTTPbcdg16vhk^Wrg`=JR2||?T6pjuy7mjxOgO(O69956IQkA1v z?z!d4(SdyBsM?NIj%vhsM^cre)q5QDd+p9KO9`pdTiBsZweBrUqv#j#7OE9n8Jzww zH?VOVVt+7~M^O0`LO6@wFG_)9@6U}s;+^Lmb=WP1^Hi}SX5)wRat8`hH$D3z1vT}w zXy^p8xzMXiJ97WpdE7Vly*|a9NE#%|t1iu_Wrr5BZdvB5mnMOucw#RwG&D8b6~g`y zZFr+0-X@jBi7;$6H^_-9+Itsg{Z3DSo>ghgEDDzQ`O*u+@M*HZ7+afnmT1BmJ1coR z?JR!jS?;W%8&-5#*k}pZXK8zsgC61WM`zX%vcICcu06qAXKXMRi%IGhabF0>6z>Z~ zpmsWgd1Cp|zzT%Jj_0YdJAnOLN|u*>^|5 z20F^lhB}H3|Eu9Pw09hRfzo24+`}P7xevFng;7R;Evzg|%c7|7TGMVNY!ZSk+^BvW z^lq@V6@o7h%TyIK%P^lts66*agMMC49UCiEnSx0C4}{Qj9u=*vO5i_r&)OFw`R)cu zRl4Ri3E5Ec^x1)S_1+&N-=|jQiFB*lS2IJb4Tjy}iB@qnshYm%YGw&P%7+#SKhcC^ zLl6i*2`1n&am9E6gyI;aqO}MmV^KNCX)L=+$=jcJm8x&4<6bB<0|}Yv(oRk0JCS4! z&Yh^GNRX9+2`wb@hW^ZVy#|Urbr&M<>BzqWkw<>L6_{@6zLyMy#Dx!nWC_)k5AzK`@tBW+4h$rqPmW?-Fq2I{%(;B6-_ucgkokhn26|>2hGs+ zN~wl>ubWJb=J`bpTWsw;O!W|nMA0!){gmJ{@Pko*bXr&DHenhWeM zp)b9Z(=MsIWv*YRKNu9K|IQHQ{0+s{ug*olB5nj!i^y<gzekfylH!?+B>1#IH^sWkxj(kAhBtSWfRe$*0YJy z*txPRp|w;^oJ}Mmh2X_lkhr0b_2pS_I1)sxyi>4Wrv5|-3VYn^4bMYWNP2j<6)TNR z<~%P-$<1Bi`rV#35_ShnYBq&O@Sg^zWaQS%Z;Lb~rBgntrrd1TdP++rR|Q##mBmJq zcMFP*;>C`i-w#J2>LZiCpB&%Cj$AXWQk9m(R^FYm>-MOu{4q6%AQ)VOusFyUg*C2C z*Y=&s8W3;-dRSjRj_oOy%Rb&yG9$V|OXz zWNdqL<$H7D*e-ls`2kd6_R*>G)?E4z5q4%UILjP67;QaZqa-j9X(|b@)=%%?y6q5c zqB#U#Wm#6fX;Ht|pyofs?qpGG?5OcQs?qU`7mfl*Ag%=`DD-q%pTs#1c(ur#m4zknIx7VK*eojWqg4%BJUF z9Rm1v{N8#F=;rU8e$0Dg`8k{>(0kIBK=mk;#0coi^+Rz>!YN4&u>j7J{Ji0u9~+=b zqxQ(;93J{`@`FB_l6zB|09^>;g%XZ^%i=9=w+lA)bkyPfIa-@ViO8JK5G5HF6u(4o z-i6#fLtBBFD)m-=><&gYXrICxG5d(=hOMD7)wRhW-hS~72VviJk1&Vk<_w!lpmUsN z4KJIRh#Mq>eqZposDF*0#iH;s8P+(>Hwonz_8H*}g#rea!bIC|V);`8fugXvB3G6b z_i-_{Eo!rPK++~}XXA)!Dy=zn!I+&R$}6Hv8Q!GT;D-Acjam|TjF-q@4O_@_841$_ zd$plp6Ifu!mFdAeSTjk{;ENYwoC-tCTdgw+n_}X|nLn=P#?n;|vYTScG^ws$`O4pr zyPdf8L1JBQ^3h()F;Qp$>n2JXfUaK3Z?Nb$6-ZY4_V7+OE#77)>!3)CWOUi?ssi7F zER&C(Y`VVVAZFSwCYh^9*EmVgtUW(1f-=oi0)fojrx%04rCK0uZg&;xM4z?I7&KTY zd~|hM8w%8iy|&g97h(&gvw)E7@c;(%)-enz=R&#|U+OcZ?d6M0?d0-YniG<@v#L&Z zDVGy&&~s*iu8fXB7TWHi(PXt@2N~DdNqG4jpa*E)rXf?5D5yiD8_LSOMqI9wz!HjD9 zE@3F6TA(YIIWe%M9@<$1wK~OyZm7_I8Q{;7LEW?K&`*6 zCNtwBc~+u8W}LLFcj=M^5AF=b!B$lVX3J=ypaI1ii^Q4hg-SJbXKZ4(ERJ|Pu|ap4 zcnFq%$Rrc_Yxrs{?5TNc;&L?<-NKBt8JaD47vb{~J~oR@!XNKU zEn}tBn~Oo>Y$nQEltybQI7J|BHh)9vd`U-gt59z9zH4{UsUW@YlD9KR8+J)z-__%X z{JcVebBP`~EaPc}f-y*+0GYSqVOWG1pJMwR5O?3*d{*9qtb@OPM`+=e@*Z!S)auHt z#zq-0Y$$KPd;d0UQK*5g;)s^Y!7E0dI!QtUAWCnWDiu$Pr(4b&yM^oVO2!XbaBC-T zf0C{J2^iHg9=vcfe+@g3$1NDH7iQSizH%AWPZd`#tAvR@?ajPPhv~Ruut~n)HDOuP z28D#%FOt=S@6Rt$pn(~areS`$QdyPgD9vkGG$HkSck@4gH`+Y^XD16z516^ATdp01 z?kL`hB4CP{apu^ktT$MsFFL}W1=cEj{_XYX;%0QQo50YvY)9gwb=xtW;w5i8ZpcrQ zK}03%k2wH%@FGwM0(?0sGbNp5C-wQ#W=hc|9u2yKRB;)*v<*JT<1LSt8!YYfQRjS^ zhQ%&QG4bfs`ghPtTRrb4flarygR)zYX%u}D&0COap0~Gp757&5dpB%2(HBLwx!{YN zitjcH3C6jB!5}3LvO2155r}t>y%u@mAj66Uwn**H``1$gn;kH!b{S5+@6B!a%=HXx zzV~=#s(S`DhF1s8HvF&qNmXBWPhPj%|D+*g4~}0vHz;b=KOc0?7!Wah@e?ZNnTye8 zb&>p@*rLD{eArwf7Cs*?X%^*&8ylB^yloM0$EM|-_9X7C%$z`gO$>1$T4Ji_kfT|z zU2%y|lg7UM!qVO;KghL}xirR30NOYxPSNb8Ih4uCdw%}To3L{;IkWVC0rgX2B`#2O z>mD(>Hyr|fRnyk`ajY9K<&t8SKJgeIU23pq*@KI?0P zb`rs9%jd*Ov_>VBL&vx?ZQrGcD>+i9@d6}T3pY*r#BL|sNOHHUWyLr-cMp;R=}=m< zH*$nVLbQ_VQEeW*D;qgvqnSM+*=UftWRw1mfDrAD za_}Gi(mhHh2S=v+MNCov9#}xlU$wB7KJSaxWoxH@JSpOJ5#;brZ2TETta&cl+pi>P)&mpxD zLeR1;KuT<;9O{kwqrN=+VTMY<-yk7}3aJ#mY$PsiGZI&2l_KdH5`L?UN+BXS8^Bus zK&CRB+Y^5Q8U&@?$Q;kTbbh?l=UVayEb=9Jfp3KJrr= z57j$Ce< z()P~=gZ35_f}Eo3jUXbqD^nS_KwN^jx$63njt)zIL^0zBI83~1RO+nXaT#_o-sqpT zFOO3ebw}&;qyj#P<`kUIlPd9^IcbY%v5!ZJKngVL6;O(kqk(DJYqhCzWd3l&Kh z^`|ME%%(-?%COHL4oEj68Py}Lc zn45+}5McPgpTGSV2@GTU=WqW_^%7xPWvI3y2p78S41F?Z;zgO;))edHvEl%x>ycK& zY;43Lm{__?Q;GFYk0J6lqB=q@t!SQXoPlEG`jZLH@Xm<8#W8NprGeUZ3wTY@r&E)v z9pJ$+9#=Ra&}o*~)Zz{ZfwRJ~p)!UcctppV8BBRwIWTl{1#i969nm2wWrsi@oC3G9FB1CsbDh#AaU4f_YecBPm~&_Wd%pf8yBB_yG_Tjvg%Q#P%(? z1iWI=egqC;e0S^fhT9RId@{3cCyMNrQW$#l{WWc;Qx>JETODHNN@&M!)^_eGF_X)q zxK!oEP|?CksXkc<0ozl3PI~PT1Hq7Dl;rK)^rcH%*xT8Y3N}27Gk@HS2}$aA5Nz-% zcI83xzdCvar;lYW5FJIv8<14*%4mc9(#}XSMCjd2vcM5BF;)!Fmy%_UYm z$1CsKxna)c-fOLW($ab>?-jn$T)>C0`2sm#5`@L7!4SbIH618S460d9;1yp41rz2Oc0saZqs3mMEbU{!H4g4aziXQ(Q*H zd;=WAnIlo%+YWiDmo5+qF9#jsuCLRua5>6GDqm9T_tZhRyLQB8Y^*7&#^_2Im@KH5?DckgKZI*xg zt2JjA%Ca6_LgvcTnk&PU3Gr$-E6oV*eT%Du0gQV*kWqtUE63!5l(L*vn7Tb>Sv%?V zhdIb;8T^sFo%n-alHiXr1xFaKga7yAbfiNOLCn!-5?UvOx*qfSZ19sv=nhXr8`u^8 zg57OecbMBk_i}R*e!E6)p=%n6{iE;+DY9ns%J-p~y1!iWG?YO%=!_rjFSJP&4n*EJ zJeFQ)ltH8Gz;*dToeb(+qW`yf^+KF1;(Rc;zugeGB}k$nW*w!KJA-a#d3tB<-Y{9f z+&c$#bB9=OSg!t>GLMq1NVvfqrtm-?lQ$fW$d8FuUd+qR+w-^v0zfl29qTQb;eD!v z6h|Yxl6qqWpg1<|Bm_uMA;xmF;(QrWi(s?%j$|;@?~SeFII?NCHt&z~6RmS1zdthk zQC0T`{;Q-v>O{sLH6RyM;F9We`mKS$CDmzHa!K_OGNFLDVYGWnar496wBq4>*f>)Y zgR)b_U$NdxvA8vJC*d{2ojB$gap-~{$qEt$g2_H&yBNL7+%?5Fs=KnNK^69Tik#~R zl8*g{nVXA!G?WJPz7-nr0gOk`vROG;k`(pGU?W_1dTaP**x6EOC&>kR4(o~TYIBJp z)(H=Niw^2b7+(bCmnE+vJ52PR&bg+RL8_{ph8hZPVxNFxy}4sxRzbi=62^7)l~ym> zBef_%UI9Ih1#pk*F(Feisu%hs=ri=}1$xCPwPX$L<%K?1k5k8<8B2v_$!w;McA{z* zIdUe0I?3C)l|+|{QpaKU?kZH1O|BnppX8Kl#DJ*41`p0HeQe($YHKY02~JY#P7*|I zC`QY|J4w+d6I9+LI_ivqop#&V@W4*_ISok(!Dsk2JQ84mu57{D>%s&bHa z$CQ}>HUuA9SoX$e;rc7s#AJN2oxJg^_}i1MpcoTucNEZeK!MYj)!viU?!2t_4p#dx zXc9iPsn_0IzhllT(TH}Z{?@tHEj$aO%)`I@(vv+z$KV_FBqA;^R{7mJ}#OMDxiT}YUeI< zGGhS_anfRHZw%X=^W&U&PW5rs@a04=ZH@ks`ZfoVLXQ*~q@tk=h6DAIB`8RLRh+!Y z-?**Gah}}?c~3j7W90UH;1%F=#(}WEK<==L0fwOZ$L~6;T{PD+oy&|iSvCvSwPhga z10MUvv`J)Q(oSMpsUDeIBOk1j@qqoWd9eMD-zWM?ADb2t1qk=Y@3e3KqU1r#er0=@ zPl}1WR0Ioz3Tk149JehXZ*NoDJdAHe!5aq>Z3AeOdWiY>Fb_Gf;g>Bxl>c6U$yeWsLl5vC{2?0fwmvwPpg1P1~KAIGFACb$vCnd{1AP z6Gfkx(^up$7}UJy>61AjXTdQD7N>_Q7}oXkq?6Ep4RYDBF|&i*#gzSl2q%f86FN&-$v7Sq zj}p?4^QbJBXT*uBaydOAiW8|t%jx8juI)J;B-KoqmtdPvSZ!5w!(; z3g;ZzNupP89v{X>fQQDwfSARHI2gdf3(z#cm~xFUU5K5WTbKsRyRnzV`PJr<%vG#3 zRv4DinzdvKO|o8fa@ieqqp`-L^@-aH?iKbYR+N})im$xp*#{|8oR3oWJ#^LwKBbX% z)g4(k@3f;yr>P!v54D5dVgG2ZUNyQ`TI1lV(QEV%$@S!^&7*~SgY^f z@FZD+1*q8@iV2>~`Pb>vVAbOB47*Ux!PHYB--~D>JM`RvUEk92W5byd;e_1!zy4}2 z4VSzqq!$EOJ&B}32P|U3%RwER5JGX=9-WbjLpl-pIuB$ws%A3i(vL7X=tJcN+qu^bmhW3H4Tp2q_I zJTYAYT_l2nu0eU&w}wuSe49qtfyJQJg4G*S->yJqlTZrw*CfiujPKCHB{pk!Q*+ks zn?wnm2-MqS5L3Z63-Mf*pm4??kTRRHFygmoHubvNAdg}hypt@6Vf&O_%H^H+Chd~u z=MQh|mFWCE6;agOUxPse-Gtp=NBFwLwQ@52#%4OyH^d*t^c#@1h^x-cfe;`HWO0NI z6-pXZ^C$t@MXU~;9Rqj@FtjzU|CtChW!orSTFONd#3jXUF7TT7Nymx!4$#AQmakp> zobEQ^la7tZzD*EtukG7gb7HUuJbmUO5eNx|r5@RPr?3i{+vqXnJ!5&%T8#-d`ttEGK+D4&HQ`O-!qhd4xQC(|Um!XXp8wj1 zHsbSSf>V}W=Q6hnsOtz&8HXcZJ7p=vJ~j+8pQ#2&LWk-dcTO&IK=Ff%8xnBY8|ckt z^i@WTG8JU#Bq`={QQHESOQ%v+?*1yH)U{<@8RdMKzZ-Iu(Y{z2-Ke)TDECbRlu-SSVZy-h%_$zVwm$<42%Qp` zap5^S1Lvnjm5{v8kG+z`iKuc!u!^@f>h?H)5u>!*YWIW{NeNEv0*e|{z@aCCAS{;{ zrekVQP!;(!j=_R5fV^{aAU-!mG-BMI3@0cq#|V>w z+3SbYSYMk?|Lj~|b4lLL)`nf$nIPI&DYOy5BsafFb_mIpz_NR4G!)?K?ovnNUi3@Yv0eex*t~Z{%KOaLEtzb@ZSaCL z6haCS?Ve_YqrZQx-vY0LzN7Ky{xu06LhO64(@9vPGE67)9^#?3eHz3mR=%^cc?S!U zA@<5}SoZAW5e8gg)3U!|>$!V$?OB8#iMsh1dtV&g8{>G;dzrNT!Q`F8@MMCiFDqJl zMUm=Dd)Z{2QKHMyxyYLD%zP6}ChVN@vK%!oN48K~-*q}ROu($hsNcx9$~^G@z|J%6 zsX0;n6}EQ{T|i3%dmHJ_i+L?9 z$Wi{3OnS)+TU2C=;qnpFiyaTdD-4|yibTh9OgWR54teh@EpL*n%o$UkP95xRHRVu; z>k{aR#LV_}I<95M^2Q~=GPbGgO>8=JDWd_$5h+wW;EEXpd#_hfCx&OUzta-lc4qq0 zre3)gi19G7glR&s=dpMbgBe@~^T;`@7(EjzWuCdfIs_ERFYC3%^@{042F9(Kew&j8 zM8W(Z4`{t{U<0qEG7IT4s%G$0R=+>`ozh@sJZHOFXPyNoUT08aT>jtSo{0rU0Dcgr zhyLDUzVNYI;PLQ=lXd_n7rZN9yy4Lic-fxg>oVJgPx5v?a?n?QB;YP5k3bM7RAYQG!HNY=`23{_GJrw zJzFT9qRn;@>Nw`ici4HlUK+E5?ZE~HTxU-9V}nG=c%)2xOC3^~&kry9OV;p|jXQ1< zf>5F+zf;~Mm3G+6Ci;ptQD%$b6xW8I#t)wjwC?4$nv0n(HeCjG6AYsCwp?IqBo_1` zPi8Q4-h`QQ7kRAOm>xb2lW*53y=LAV3sWhQu&{CakA;FF+mONhvjAGyx&X}(jt!YD zXA?|wu65eSBING!My=?x>Umc?39}coUbRm;b(ZZ!ebM5wY`<-%z-EoLF;@=EmeB&9 z@|`7bf394i8GtW*XID+cJ7R55dJOlOGUW?~fxVQ6rR2&-J37x_}Fd8f_4kKssp=eVNPU{z0QZd3st`3 zck*^x34STI5_ReIl-y2;0A7eN$m&gT^0x0Of&2RCW?v99No_xYwSN~~_{Se!X7 zq6FjaD>&aU1tI_-CC))>)3Fy7YWCALWKx4EU655>e#kF)J$`{|1@SSbpi*%`|?h`R^;L5%=9oKscy6&4-gLdFtFDq)A z%JpoC`U^P{9m+skx){-c@3fE~hm2=bO^if>hLKcPZ z$2=Vi;aAhOLL zfAY*z0|*_iz(QX>Dj21|!<;~v2Nvw0gmxS-U~n(9XjgRVkpeh1ESp3@JP+NK@|vWv z1*9fX+G}#w?w(!dGzgO0AN&o)_Q$=H87Q}leqiWVh+|GRA)cKq-$aQ2Tvm5FVB-I< zfG(H)CVp;gVT{F`Jvo`OspAYWa8S2!rc~7(vO9J&qVy%EshDJDg2{c6WoWLE5p+Mpu1Bqh_e$lTR0yq@CCsrxEK283d_X8D z1Uo^NVe#!C+i<)=^=AFTIsgkFrznNJJrDwd5Kk4|`T zGdoElCz_{VQVWwAB_p^ySoNHMe3$^bG!Vj+9S`z5^OSV|$;9>vKp8kVXsSR_b{~s_ zfp>?VfDOQ9^% zMfwy(SW|0)5f?=N2-Ny#=1StpT9pQQ+9cj9FeKnCk2jh2K%BC?U@RwZ~qZv`xwqZ@H=;9BUi}5m9mzK`)zS?oMqVy<8+}1MU)We=MZpomOY) zDjQ8!Yr(#CDSfW~{j)$3g#IW4>|gR z1RatB1ki(7XFL}ok`M9r7URdD^JCDqPr3BT^%}N~gz?ZI6Q{no$$6*Sy+mnWkS2%% zATM{q1oD+_Jz{}jLs^&)^oq~T3k$_OTIPJ{d> zTpdOvD`@U9Gw%$d@vZMr8Xw;tjPPMx8zGXOzgVL0uZty01S}_()T&}>q{mthqdC32 zLkwFf(UkVu?UiWSt(I|(82fS9G)hAyTY1_5y_P}EqM%XyrTL2=>x~np{oR9-f_O6& zta1JE!t|&J5OJHBqVf%2oo`yo50nkzVy`0d8slCfQyr}eeB@qtFiCI#_ogCw&|#dYI>+!#muwJi=9o7X2se=cbGfM!AMy-moy@G_=gwG8h|zB~WgR zoEPP^Q}l})-?vL;NNFZ>4aN+_z*s770GSMBdHUc1m zsCR?$Ffk0d-VIM=+s5_}BUP#14ZY$R)h8W+dE4KmdAmb>f_hY~=@VUEG*CvL&}uMq zkb{#rumpmSY9Q0GaVy|F0whw}BrG;ArFW#wxWBO8LDo+O!C5}H32M7(ELoCHoZ_LL zA|pw#eVly8K^FV7H`LDlRQ|Wl{^@3M1=zo{f&B%fVC%u6$;vek<)?BXLY>c57LQ?G zpcK!iZ3L;|l;-)9{$OyNgEx?|=E>V>&H1G*@O<{9KA~74RBS8~bEpP~H0rps&!iUB zE*h#cbanf)nc zLCkb)w1M4}9R)1ym?n>E!bJC717|ul-Ib+3$|UPQ(Q+54mD4CM;wXHg0;i;`A2)Iy zMVv#2*n;;drLbl^#Uq8J{z6iZy3O(YLVg6H?fF8eytIlKks48g5w^|=Q5+`9%(4B| z3lY~+k6HaAC^Y1mkfBdO9p-t{hvC){wzsPsunbFJJl?Cz9@A~Cl`JoS{^wb#Rq3+0(9Ph1SJ0R9uS8UTQ?g}Wj-HM8B_KUv zDQFv^4_Wk?lYZ|+6Cx5VSVOl;V?BM8(WnP$E4cz4wjqJylpy zTrgl<8zl!hsX))9jCD{qnIJiADU=q5Q6>!EpsK3#ppIkcuFVWiJ_;sQNbx4mauc@y z5`UdCuxj)ODGW3KgJf~+bBR5y4ppFRl|9VgQ2QRvZu8!yhs*8Z4Sn7_{oeWUSz+G& zVG~}AdfY!dXF@JttEo0JN?8rUr-3H}c#ew{1}ni$XW>u<+`v90B^k21&2M~lX~|HK zg_E}zWZ~j*En0vmXdC9txc&-LYiYBtg|Z|}PKjBc8>lO_hsXVkUK9i00x1fpX=;9^Vc?$!2FA!jE5Xve$Uebh^P6Tu{DM(`^DiEmQ`wVWK(HGCFu{TBH&cs zZyjXH2#oF}nLtZ)zWDB35!Pdrl&_H&XKw}V)3D+9JcH+jF6r$_30#2~d!bB7nTv;s ziN0{k-y;3oU153$=9s)tD@`o~`l2GgbS~V{WNtb-^<{e@St>-cvMqZ??#~yl%9c)+ zkL(oY3B3>~O9!=`)%=ArDaw3a25HL?$hxs~%*h<_#lLcDB`hVf6(udD!B#A#4?(ta zVN>aH)W6i^lTDJgF)adrL$O7OC~3l=LrRhZvN$F2Ujk^Q(|3+J!_*Y(G0m0m^|j@s zT8{F|DM{7b6+RtWF2(nAma)L61iQD9?LAMd2934cYUF$s6ODNRl*`kzWLAXI&Yo^X za>Dv-D)K8;62!^%P1Y$iwN!O*0cH!|8O|f`$z7y4&$A$Gtvrw2P9CxQHp)=NG8bg@cy=D=*RievW9BRriwo`BLIqWkHOjtI z2BJLImx|ifIt($dC6IZ?MLel;>#tk|U42~>ldJDqirQ-T(2?5D>Bdi8e&GyaEd4iX*!%nhK|3&P1w-}{XrIA z1Rp=j(wc@tO&g4a%%9Mj61S7q#4pjCOK45uHpt-l_m-i%1V<9pAtSJZWBl>^_2>7) z5&S13OCtZ34*zCifS4|5G(*I(Cap2kp%ZW#8vVn5*jUK$$M4dE^59?`!+}NhD=@Qr z+rgTo=RPTxf)xvZ@y^Nwuz|%__U#|PQ;N-VpXox!>{+*^oO5J*mMadNYuth;0HMeM zcWzN7fh{T# zRLwHFYQ?aVddc@jak61zpR>MlE(;yAmWzng}b&s&yq_&po)EjSsr^KFbG$}|QP zt!CvxU<_af6gVC2V1}nLQ0vs^vT{I<33efK19kenK}SB^%l#aWFLw z*%QZOPW%PNCg!d}$j~ zNg8pg`*dS~fTAdi9g0+wk`>p%0C|V`(+B7S)USDjd4QTX$&<{w?9H2a*_0?*s_6Xa zQ;~Vu+-vQ1U*FOY(^T|3E7%7ww1MdWOlqP;W%J$sKM)@te4sBn#ybCS&}w#Q-GgWG zL!;9>KgjHV?H2dHHo8rMbdvqAy)#C5(%jcBwYg^X!k%UJ!n&{D|9JDB*Zz@Se=`P- zIMDv=xsUhPe>k|jx~^Z1%<;o#b83w0P57h-ycPczU;VYG&o7b1fNobV?63nX<44oQ zu=-xFeRhWNw{U54AQtamm7H^W)wu0!MhIv0%Q;;v{@=Y(_A! zkz<(zS)(1E7)MHCHmw2o`xLWT#Q`c%-n;i*ABl}9(jMg@=AJwzjX|P;Es%AsGS~cL z=2OpsY18;*&`O6GG_s5%4fNZh(Y#U@%Vl!CRd=vpEYe2gm&-?io3teNoZq&u+JOgM zz&&T@-P3EOOdz%4O&E{@L+QyvXf`lQ(H$7Oj_b?}+tfW8R}Ftd*c@YoUA*rr z2Fr==ay-tG`yCk~Yd*4InIruPW5Ek57<+0=P0o=NDLxFr&vh&avf{%?Reh#9_^9F&GgzA@BeTbN46fu1 zI2Qj4xEB~?ii1z9IGGcmO&JiV-*4vYvk@HE_-*RqNR?Oi6sq>ys)teg4O8ey&afi& zXd)yihN=YkrwAU#qD!(021L*P_-!|F(TZdz6}`Bap3Dnc*?NgQ zGGe_0w#!W$aOvu4{B%W?`vR-EM!w_T6I%iVFN{SlHkmoqh_O zJ99oe?i{R{&|^y=$j;T;jx9P7>$8)FepoE&(GAR>o1i4%!k=Y+qm0(-i>d4UYD!euAlb?OCJ zg-hfG9PKX11dP-&0co&=-)+K`fW8rVvrnmQp;%{ZFo*2zqqZaqUc1vKK)1npy#xeqBdos0V*B$RjSA~f#&weB01^@oE$nXdO}>3H+#((xm|5aDC>l<2yg z3XX`osZl8y+0BilH zeoCiaP~ursdzdplID#)rMgM5jMkf=2$2YYo$%XYt!ncG!9UATvO@zP+IW8!=!4co* zAZ)afTug(nD*TeANaKO^WDRD)5GtMvqQl(*ZBY@@ zFRVBTf5Y`?_^p8O47fm>QU3u>OD9P8q4fnm!=pADf%l0Yn)pU)E^x#wr&j}aS{qn? zz<954F3mJh$1)~Ci=j*ob2Ua}LHx1a=4>s0kqY4EX|vaUQ=%Q{fv6ps{h-CuM$_db$zCmWKx=7)q3F%A#6%Auy@=1srS1oQCVcH^4o_u5wI3 z$cmhqrWv!cC^xcx!7qZX8C@L|OvGu|;u9Ffuv(mwZViVfw$;eHF_y+ZYKI*B5h#<4 zX^xYs;8^J%9yZ!ICpw-C51FA)fmPu|*7y{C`}*$__uJS1{y|tcSm;XKEyuvhrgq7v z^o!QQD{pvDaTk6RrxbUPb`72pA6M~FHsoq=39?j$|2ysW<#kwsvV>y2zHGjs!qJKq zE4^hwv37)AlW`MCalYx^`9!bwKe@wC;R*R9JY87GCv5%vw6vn`<}2#Foy~dfy$CsR z5Gp*_;j*=`V--C+4DlTtchmQEFMIeNF6*qad& z!DVZa+JFwhrla)!Y)-hC9t4-E`#3i_OdA9xwE~ZT$Pvy#j7SiaNPl-K zpYVl`Ne}qsfBZVvp`Ht`d|24B+fltZPw|8o#d&UH!guQ*pDFZ1oJHnccUm+X>>$fO zZmi@Vw;G*JGh--g3f<$EuUCfUg-6kfOO{j!XXBvknM-oSrDy4Ogdc)`8@~KU@+@98 z?>hCrJ0*_f0b-QTg-K3f$hpf|Rxv3<*wz7-&Cv3Ew#;pWHR${1KWCx2$#yMPjW5=+ zgYbTVJu#ZUYt))Ql-ZIWD4fSR=)UKE25mK)U`&B084q3CcIVQr$5A6_*7w1N#^2E2 zbLZe{m^#`zDh*p{tS`7(k@fkf2~%G((W7!BzCH#6?kgt0>4+i$Wu(ex(;=nzM#hBU%PW#3GN3bLf%rZ>c=5)N`;W z{}z+K`MV_j1W7A~6MR3@n&l|377F3~?Smnx7oD2N5DmSda z`Q7AKcQ*Fb895&ez5d0!86)Gs+MEn1YSxo`A|k_BEcd)1J9YB1ECU>CkrvYq@pl~8N;!*6;~SmS zZ3)2D{_fPaB`CS>wUi1>BKfke&yA6azv=^-;>hu^mCM#CjT&W|Vyf>ETW37KS8uIj+26kYJ5in$R_?^7a|M+b zKIZvL=!CurMwLqHzjfJblsE@zWybsjg>z6Y^-ok=O#LT|$WlJOQ}4yUJb8i&2S;jG zdZs=q+O@pLCaFCZ!?2VR+XO0E1rg(ymn32}fIVQ`KAMi{>2`Jxw95HaG&9l{VJ(24 zt9K<bS`PqRV6XTu=r{gjmOxgC%`m40FO_ny2R~h=zEXTd{GpSQRIJ+89?g z>e>hR30%nFWNF{N{%`gnEzn1e*NyNmSWM<%uNO~zs>yU!v^>!oYB*2}-J}To3D}s- zy?6-)BbVl*6zV;|H&n(8S-=>?3`(Jtos%sOCOfob9V9xu6DRn((>uK^UwwR5ZD{ZkPOsMyK8^^BK5en#nxiNIaaZfAP|}R2-hnb9TRd{V&aj zQvqM(!^QLsl;DGJ1u9o>l%&<;u8rp|nsx0h*4);@;ESl$JH*mWz3)DmM^ctVlKy%G zT^7S#=09iF*u{uUR3Zfi9}6wnavCqjSJ=Xm)$gr0t;_S^FSLc5N7Fv1;OwHwCts0C zl$ET2f(p*HqG^Ams&2S5u>v19XZlgcC(b-@&S#$U+D8eY`!&#Rp6k2ADKg+|cQ~{R zlW&;nk3KF`U=PBJYiC|S#c;J}1}teP?`9``%;N8SWJ5?wWjpk zNQ8p)oSZBI_74~KBe%M7{P|9P8lknxmgG%xeNM@BMobP^-{eL^6Q?RH#ywCvVNVHp zbBRNO8E4RmLE#=p7%B~n++sUv(gs^0Om>9d`)H~RjCvtDSD8)3uZw$O*?Y6f^XIRJ z_TXxy*EfH@zxw#oha2rcOtG5J$K$#& zsvG*at{e5)=M&2T#X8jgc|wB2KM|UOey%@S!vpPq{!V*)^Wjf7x9>l^z5ICp?&c$L ze6WJ`e{9BPiy}K3)wZw%TtN4_*LuT%dK;#8rEf1u>rE4T6FXf<>g)4v=ltxYNL|_6 zcYxIE-f4wX-MnqS7^y3J`%awd_3m^bsavO=+bc#ZdI3^b_Vyhh^}2Vukksd`_G#nA zbaiEK-vLsud#8&@-EQ|p*5xHgUDexnfz)f>>0-0&y3x7f>WG&x%c^?&E|_I&-swV8 ziwN2ak-D*7-_rJBOHnVwDJ5rAD5zy z(=bP#IplwG+A%9ox?zf#0m}d84}RXe*R5Z2-@RrtChy(rwwCkWy>6#0m)F+p`{#f6 zdP7WE@7_!-Gxl~AHhAssBp(rG@U?c0$yH9g%G@dyeBIGc#t75BgwKWj?wn{GfpE4_ zKr2;zHM)&R2}j``#4o2k5I>dMgMfI;HJdI`Aj5g8ss0(WREF*Pi1it1GzqfgA>5+C z7ol6XKV6`3>*2#91cHe( z_W~JojLeX?w7dgFJLqMJN&7~;$(_+W)BxvCJA>r9pzE}c$aY2S}Y z;==Kq*#q3~^zs8PO{l!%LUqfkEk9Ukzk>b^?Ov3{`2mpd_s&b8+Ocsp!Yl6VB~IA( zu?qoxv+{FjE{F9qV?<0$56gGL0zy7-qQ{A@0E^1g$J(4u=ooD;?)4SS7l3$GUrV#z z>NB;SjVK;7{+v}xnk(a4#WJqlicJq{oOSX8(Y;Mp z>u%8PCJ+gByQ#TwVw<0s-#9ZU=6tB+{6Pez7!7RsEt3?53LM1+H zhL4<_J*V_OIa$T!p@+dBm7vW>L=LRn&uW}E-<&T21yKZvQoQ^?5R$xAiY3rMsw$4g zMkA={J4izjDwoll4GrIhO=I8!f6;Ay3}(l!X`X~m$<+yM6}y*F@&l#NC_sWb`>nQc zFgAYD?g;~$3XGB`o>IOpemUFq{L{wH_2FIfxOLn)LZsM{M21{IjgGg%h0XF}vm~-C z|1}j|*whzA@ATu+D_gfT*}8=fb|R`NU~a6whN zvXMKoETr9&r1uU@(lBNoB^i96By1t`QNTXDmps(Z9gi6?mb~FRZEQV?_#eT=;)TPR zZELpWPkB(?M@m_DkF^JZ8oM+zrrGCz=`YE0%KTL@I!_A%Lq7gLoS}*X>G7^GdJyhX z46?_Q&hq`KVnHW^epydZUFb1F{ZPC4 z1jvCc{KqsA(!e2nVn!x~%c3;H`H$iV!Pijg0 zZ;s>n+W)xu$Pem#Jcid`P;6>Fnf9}a2~<*}SH&@N8H7sK6n%uP_1~HE5AIlZ@I9ik zXyJDpYZU*H9_#-s-`ga^0e`u|=f{3qIWC>SB;oAQJf=PCw%Uyh2)@YHEEnEop@OF2 zXA4V?R^@xlcn_WsPdtmW;jF?@Fs3t%2-BgUqu`V5bj7JwUdHzF1%AL&U26~yqvhcz zTTiSaNC6Coupt^K6dcP8T6hRb2c(*`vID3ShR6qXaB2Il)B;0O53wjv(L9@A>YF}_ z30NkRMM0Wzh?l5IdIYn(Q40gH}9vOZ_YLs}ZHp|=s- zvWo}Zo-zl#k3kbF;8Wq2Wm(hf=YVDX!;F!`$q=)uRO}VuQxy>^2cODE+9l5YrSAODPmKevFPRLjIiP3TDXp9wqvkqbgqjnYUPCb<_7M%&dBT0d?69b(To~cGP=1?t3T{t3*PT2du8R;0Y}F6v z<;G_x$7rO(ahswOhR1D&8ql{;v1;DTMu*uAE*CmEKK&YgLj*4qIY~l)25D#JuIhDU zN{C-wLRK2$?-v~pRW|+-(F=yQg2b&P@ZlH&h8bJTNf)Eg7~#E zonR8q*Qc!}rJ740yOq|K@mLWUHHVgC$$Al%+)Ao3Ak?aC6W^9qPGC86wNQf;+IXnO z`nqo!(Oo3Fo}+~ET?Ot?NIaF?y!hq2w0Uo9|DnNF{jCQ7vEP z7QsvY$FX+zH&T%Yx?v6c0|kBfLPq80ckZ6dD@OX(4#>toIOZ)3CW(u`_A!7!W(9YR zkt>foJa8#AFw&n)?XJc-z3?`kr8=%_Z;38s0AtOZD8Lthq&66W{#5(yVAD(xo^d_K zx}|_MFNy;U;wc>AuzgoPrb%&XdX%`NuKn5dEsi{5=bMLN1o3@h3AFIcMdWFbwT8@s zk0hw~ODcP`zGw~Y+t+`Kn6zwJ_>0(7fqtL2FBWJR>OAk!D7PDpvKl(?p(wW%=>Q+r8}caOX6J zPsuaF_xP0g@8086ZvNeSe9Fzfdow}JVtmRM3cKT4#0O{Y$n@gi(y#^xn5YeAd*L8L z+m<5SGj}1iuoO*Ic4#%8$*$`yZAtA)G6GZjVIj#rBLI0ohQE=&fSu1sR7CDg?Dak^ zu|>q*=O(s2H&N-y-X|!wJ3&z)vG-YuZO>9vNbG&8V%t*{RT6ujuh{Z@MU@8HK54P# zNs9`J{heekdSx;fshvfLz(IeHFuivd(PEc14+6fHelqp$Lo=Iog?tGhbfCZQZo0YG-pTWbX)0i;bC-Iggd8Kb(pC?%z#W%6t z`#j!u(R-iD+xApm)#rPk&D-v5UbXbzC-k;Gp;s-v_c^_7&*@c6?|oWt%hP%l+iUyG z-j-+fs-^dLlH5B}P3{Hpt`KS)f$d@&o}5&8)*^_?5VG<-C&AZ_C-`Up-#)>&Pw=I^ zd!OKYiSOPg__j7H5zfZ292Y_7ErT+5c>A*1x9mI)i2AGtr>xDF(27HgM-{W;2y1Y( z*i1*?9ayum27e>8=m?THVL}_O>kTZ2!NUnedgcu9E<#c4<7AsKCkB_yVA=57KWC;t zt;bef1(i35drU~*3%JK!n!c4wfOInUiU!pdVhd-3>=OqDV-ErFSVkS55{V-uc&HdwIRXq+WB9Fw>rb!~p(=~%a>=edUIm<&aV)-PUg zEKd!mxCyVGGWqae%yL?utO|%Fnh645r1^0g4$WLSPX2{4R7F-a{SwAtjb4Jq2PiDU z_wg*c>d)?GX^DW*12NJ}pG-U#cVVi3Hl3iIpJbgIIY%TcgK6(N&z-ZJf%Rk!X1a}Y z1g54J?ozYj^9Ao_-u7@KXfKFMb88K{md_2tn zgL`L=1#*@@X2LKCSguZOG&{HD1y#;dRUd&=CM;uP|T1+&=L8lgoRDCcI zqXa>LX|Fzn*5E51g(9H5HL&=l7K+bEJmd$#-*8};UjPuj&STVv#g9p{BKQkx?C^LT zsSF_e4kheL8y@u?N(e6ID>8+7))6`$Xi?!23+Mi*3>hs+v5k(f$;M^K4Kbb<54UM| z&mv*MUN5&3pu5swo7UNB_p+h9!STy^$~OO0c7v;Q-?V$aL*Yfs+N;V#SK(H6KkArVjIMUxC$KfU(M1(0Gce$koO{;)EO>sJz zPUEp_L)#qSNDJ1$@JAoqRx(hA1m4fT3${I^xn_c17{UXBh=1Mt?$iYtApd=9eSxRm z$$w%AGW~QCTzKV<`!bwFR{?k2$Xtg^egMCjQwmo3WKfy9Z{hSi8Z5$}CdQx*FrpK6 z#13hCnPvJ%yfrkY!*PY@3+IbWJDQ6ZpNclO;JYcFH4zLr1hK50czc#B(BikAJ7&pZ z%6S`4mN}oe7S5H%KhQ{a<|zl|nQi^d9DodBfW1w31wY!4=nRj>C~FLyn!PxkWCfF1 z^?0!lfUKbOZUy6drCkmJ0kmnG-;QeijMcV6xKW@jfNgAyk%3N|;-KW$+M#|#sxlGG zp~D>SzKO-eq-0>Bb=VId0=)PL63Y&sR=r)h!MJt@-?A9jZY=2;_Ui2w)Eag3 zi%EQ0dH87;l}FS)(`4inXUTi+qo;<~TJG^GX=Dkm+L+jBUq7x0P}r98L|S^?TyJcRDC%pF8!AFqgs{pG63f z@1O_G<Ie*J(#J4Lg?zdRNrM5E|yUT#xCU+L5uC_{O@8cwu)?3l8h>Fp_MHu>M51 zIer}f++8E&^di#L@3<%6tb_jxSY%@9o+f-70YEPjLhakY9CQKcg5O!$)cw`BHAWR$Yd0v1bIs18Pf zAh|EkEMqv!FKWr#$P(|qc$k`=>E^wus6s{cO;q;)hTe1HWvQhyJ#lvm2laZljq_DF zsL^S+dgs|3v~0!GSvs2}p&nK1SkCH=0v5>G3EpzVuC#ox@Q}vA{)bJH=0K@#iRu{3 zzI@*xyVSA&D6nGCUiV`VnAkxWC*-j7r2J$+;jJZh=;OwIg)cl(U& z5`f(Jvwn?XM(Wz-R1+_VKQ75M7Q$@8)2XOwh~N{{Lc3~P>v^klecg=io0Xz{QpCxZ zY;n4vO>QL)pjor|k zW5c&O?gLXE5zL*9&?W&pr}5*!^sFbzjjt@H=FXBY`MXSBPq4^*tTPhR`7h-0Hgsc?9|iL=qKHQp+>wTZSZz++VCQt~56wY<+V?O^U@15ek;#Td0Y18at z&;xznwP#fCI?zCXWBI9goaMV?iIFy7Fshm5!yD^6zUyq(B3LNR`E@;pv?9LilUlSb z!+_@t`Hc`URo)}XWF<3{lA0$xIp3m8hbCOE8yB>{akq7VwC5~^Sy!*=-Y%rgjLMIZMq zIMA>kc=Qn*9g!u%3iR*|ahzSS3LQ-!Jn8W7aMU?T78B>BN3Z1)dxkF;R|1QVb7$Tc^!>Gcp~iadt-k zKFG)_bQ>$-o|X&_#4lfcJF6gZb^dIKB4V3EY1mdIw^uR`(Z@}iGcN)*h%k1bTa;eB zeuN}H=Icj{I`eUiz}*DfI0H3+Yu0Lb1)7WEuRQ8hZAi&3>CXq$Rety$D9n7tFsHF6@%Do+u-;KjB`pMZL=5tOzE zEKsAx^LNIg^iBG|Bs2f|OWuNR+NZZS40W2ZGwi1+JfrNEM;wdQc0T>_(uZNYya-RQ z(e7TKmw!n_T;Z`=T2v`5;erO!m`jSK6~2XqVSowrRn52lXj0iL{Qm`=DQ z=uQiFW&xzF+-WIXT?KK@6?Oq_e~>xP+SoKfRf8x(?`;e_fykAXXQFaO;l${aLmT}L z>8kzuOCV7&@<8z5@u-iXdwn^aO7t?1U2H?|KUwY!k$8PmB}7*8D8w(XM@lF_{F)50KdC?#`Ly<2KwwC8(t_|@WeC-`NMS0|kq*F59tgn1* zS~bpNVWWBNxxF7ke{HWoqndD&H-oqx`BU}y)ijMsg30!gjCJN)qB z)rW%*uMR#O92}Ju+$at&ZR^pI+~m(Dz(N!oO-kV3uSy+l9VaF(1=f3F#8wpQs+$n) z8fR`$?gDXc1_PS$k+e|!kwp6)n>0;_gPj49tm5Z>ttF_Ww~l^4lHX9sB&270dTs0U>Ydq z9?2$7@d*y!VJ@D6?nlvt$MeEIevj1=R)|o)eXO3Pr9bLu`<-cr4`RGW<%Hb8F~0vx z)x&09iXcZa4E$ZorH`hZi1b!>KyB4yZ#YTQ_jzW#{4rnOi=XJp%KBdIn{dTdSq1l) zAI2eapnf?)yZ5uVje*nOWxJ1-At&8hW3Z4hhn=6ySgal^K0KpYW@e*ejYqSdB6dRP zPlWEb_};$l8lP$U+^@f&|10M+lBMWRJ&Uvt_=N8fl9BP~D4HF(Ua|&Y&sfQK9boy9 zM}v3$gSr+t-kC(OoL_(8(us%^(a`co%kLfjO5^SqTDVFvh><#)xm4F4 zW>_T(+HHnXSJVW0ZePbh%goWATx&r776=m&o7WC!j&1s-HTIs$>!z~r4ySXV;IF@+ z8G=+pBw&APjj;nK)UAEp^DJz7;2DNka_I2XUGodgnHyj=tgeB*S2Jwg_cc861DuBE zxw5bK9 z>JMcj#4$)-*&G2UMzlm6sZ^UZ80O-84k4uP?we%L74tS9&2ch^d}2wZnz#S zeIh4#KESnNPUjC?=}qnpCLF^n@xrAK%F=q|0eE%E!&0&7`Z5!+AK-Xy$M-XT_(zy{ zrZLGps#dT)j@C3ixIEDo5wr@-xHUBBelQ)~fh)(rXVf)1MKeKgZ2S~pe@A3$ZDb_2 zIBNdX_2?`m@5CxB*A1|Cs0$ z3j`81=*SK^?_`_47RCbmJ{UBc;?d-SV?j)`RHzyVy^E*)0CbBL-ioG{-~Y! z4XGnA9r^9+zk`#-^!WDmzX=$@1ggxYF2)ksY36D^ZESI`6gH@EA0W>{7ma|aM-ktC zGUf%$EjVDhJ=dR6=V-Jp2;p;%Pb=H{|v<7Db~jsU@l_rQJZ+pC+oMv_oqD zTE*mDTH;AbydC0>Ce@e*I2N!hS@DJ@6>NXx2!xyZ18EKsq&yDwN_xied(0{{fL-rw>ML{)UiL`kMB2dRQq~dvQa@5qxFv%m zDP5ZCL6Yo7g4|xrR&g(8yW5NRVz$rfd99dD)mF?1+3;I$ue!I*CH(U&Rw$xC&NJ_E zuvbi()2OeQrx%0iwt@4_T48?Mrfgk5!DIS_fq*mEZK`V5C zaYk~~aRXF#?fjkv^jSgG#NBFTBqII zqt#le%emy9HBZ}DovTXstSswY+E|lJAvgQ^m>nQ}p)sfmCLg;4tWu3S=0VU$S=VGm zO9cW&5ZIcIJa_gu;#m9y5f3O~gC|$>!6!6ErvC$Y8QhkbQ6d-n>fU9qaeI@uh(@Qx zcU*k?`mgv2{r2_0*kS|82lVBvL(tVhhkxYSK{!tLK?wXyhD+&YkAC5pDg00`KI7ka zWE6HwV)4L#E(Sh}f^bj<^~_ZH6DhY{qdj^0%!=hhT3|bL1ZWE%t;jPW)!jbuVH?@Ipjqfg6bv!OaA{ zDUxz@iN&pY!Yd7L2jXF|jf@b~9+=?J?T=1ybXrA6r}zN8kjWT)Mk#>hl!LMAqYBK`j)EuHJdK;Hy+)3) z+Fr?6ja#3E)JiEZ5KmB`R=ENLVxh$X1A-pTyon0K_@=*tc=%-bpMZ-$$pEooe(Iak zxoJ9|{`d(@t535}R#DKYbe#LF-p(&&$lLRr=i&#gR?EO;3kN6ufhG*`8oAih6e!O$ zxLLF=`|fn4l!|XiDzD0ODgCbMJeMXRf~rq(H32BAsz}x6;094p9C3q&XxUNWkO*QV ztvS+V9P;wD*#u$YCSX7UHNsLPtWMRVVRVXMPC%+-zX0&I5ZK}0DbF500DTD^J)jBb zJkRA!=n-f|&P|3F8oCpP;MiGP;DuxSGU6hPGLzvn1($1qkB$WJ8oqp_lQldd1?r-a zOPRU!7a)3)Dn8PiZuc4`t13rbb#8AHP$K+<%B2|b?V=P*Vs@*_fU|lhU$*4!M9y>X z+1Lf5n@<#R%YDi9W$VqG@*%`gK`mAuWNFT0^GqQ%v50ijIGHtW(6RB+pbKHXlE;;? zTp0)U+t>f2AzUt_8~Nzod7mloqC1$k!CU>QlE@5LYE=eLi7BZwcr`I4lzk-e*1)a8 z+6FO|&8OSX##i1hw!`s*)Y?)?NY=P9f2df0FRqTR$Wc90~lUXI5uUo)E% z4o;9?#r+__i}(iif#@J7Y}a##_AHNfQK*ZHO#IuFWxyLupr6B_8&OO`o%Qh0MdWVe zYFX8%{B-H}e2?YlTxni{5dP~W8T$OTebo+J-Xe@MWrpVe!frd~F*77InbzKXP_lQ| zO@oD%6w;t*LsdT+pZ0LkzOSyg@h>)O>^*fm(Rsio>!R0Bb~|JNlu7Ts*4rup6`(7)YtI zWjvHx23ze6KpJVBMYDuT3mg~xX6otW3>vokaCE5bI`{orp(jcCOm#Y?KP4z%`~3-X z(&N}V`~F#U=C)687brE z(OWp$0_)Fp$7Q4wXGWuw$j8DmM5X4xtyV$5{(}C{z|xs9(E-{+m28kJS>0oAgKbAj zv;XsCTCbms>-GOd5h`(2UAq+MZmy4`grYEKjsm@i@N7Fbn_Ph2bjPJQl&;{v6*#99l$Cl{Z%0k=d+M8wy*eeTn0zEbn9N#4@^ ziO~Xgse9BsY#(*NWvVsFX*zEHekH$YfA&hAy@%rh8*+d4HoDH2K6`2bsr}ijM(^#< z-u~=~v!@&k-k-f{^xod)+@HPh?CpN6KHc3v)E{-rVOKbRdlf>PWuoHDAn4dreb@}K zs{VoH&lscUzgbu(sZ#0QY_x7yD!LL+P}ucyMOQSzYO&~wMp0#y-iQNHnviGpZhk@5 z?RDqsP5DNtD?PsxDR1*5M;Af<=h!GH&@Zq{5aX8givYpE-$dDmY(fbFIQFwr;Zi%X zdrB)*X(>o$yu2+Ay4QAKbC-;Cn<_{KD^spZt*?>;Ej@+oY3?zg*$-W54A_R9B!%9P~;8 zf^hjBmN}P}%v-oUnIB(TCX`Szhkeg7hxYU9g=daUU@M;SEK4kTI7NIpd|6}+JQ5`_ z1)fKlU;%NioLp`I)XE7=_@24`^o$>aHO+nk$6#lf=_07uruhH2umAcZ_GBR~>&5b` zq{*;J$^C-6UU*jTxe9qvXC#@bf_WY<`~4R~TYqwANoebp2YzfLRW-visY)j}Qlg*m z;m4nTx-KPe86BQ%csP-wf5O)LrY(Og684y93#>jk(WR$^ZRHjpm)S)u=M6KLDAC|` zSSmzL($pm-q_CB|{iyr?HKTr2x`yN=LYo5X67;wItROIZ=e^#I`rz-BX3De6?#)^G zR;h40J?sC37{&j|Zj8%qfb1&Zb)2_i4Unx~K3)ghzZ4XX*qcnAKq!g3=gG))1hZvO zsd3)v-Owa-B`T$O!r}=ER4V5QldfIxgnI;&n|m6vyxm^Dx0|;Ue9Hbhdd_>mlI}8( zK#jP(Slh>9knQ>8Fq1gk0!lw!)KqGs*g*FF1g#K<(-FamIM_Tcz((L&!@~J}@p>)G z=T34p(Bh6Hqm%MDi2^@`&)?+GmmM0iyOL>9m4j`T!M7SKco zCMpjuC}sTrI8sOaa)ChrER$fo6f{|^Gn-n#jkw|%2d7f#TPuSaM zg_ERY<21v;4XuR}p2r;ubT6sGw}9?JJ-dYKLc@}}B2kI4Z;|FQ3NU0W%op%OI45?5 z1j!O40wl`?Q)(r~%J`B-r`~LqvDCrhCNKojC=WmV1po0zw7et8SqdaSZFa6p0F|Uz zZQ=a(6dxH85gO5rV^{*A znrH`$L*~x{EaF(S{#g8@N9aM!5so>JF^`H+Zgtw%>UrJxE*92IXckl=y$ z`$ybwR1^q60zbzh`)HeDPlDFM8$o-Zc}YmqrlDi9>W*l7&94?AD|iu30EaI^ShVO+ zLbfewxu7k?oAI}d#{>}PM6#?P`f1sGYMCwfNRn%Ufe0Ds8(WDi$ z6bi^oiiec2%TnTDone=rLfGZB8Al*KJEMOeWW`;&s&SXpP0kZiDVv<4e{UO&-qoqf zCYRH{^!`QtD{2HXZaNEZy3!qjojUP91x)+N9nxzh3Be{ny| zRUbqGuAz35ej2eypX5b8Igr5Sxp*c%e;7HhKAB04B7_!cElSe-7Us9n*i+SZRO&J$!o)zYVP~=Ad?m zO*X8i#Sf9|Ztn$Lldm0OtpYxNj-D8LU!ZkBjoYw|s4|eQ2bb__a3j8G&AN8k?|a~f ziU=4!pM<~mXU{au0oD{9NPb{Pgy(?g@nNIeJ8O2umnWwPH`O@FVBxP6bCBE;G)UEN*iODCQ3;; zSO=T7(vB|Q&6gux$!39rIVTV^^z+5|FKI!*D+eZWijTt*IY?l^lkwg|Mq%}jF|JxO z$CD`zNA!;*uZTCo8s8$0%&mgixYZQJ3D_j;Xw(VVP&fgt|75u{_+}BmLED8WhQ!d( z$eVgr|Npc1WxI`JOJcv05HPo;TO!5eB9hf8jkR`_r)zPSy4!QFFD{bg5t&oTOm;4% zQa>04`_Tsca34Ga+=1WxJboB>;AQ5)KT!P(^(Bsob8_F#;UZDhY@kaLnR%8tu}7SU zfa^7Q!PFpNMRZFAP;JBusyZdKMeJWJG$(;IM?RI}8EN~L!%yht3j!*TeOwg?wZL$| zLv&zb1IzqeaALpZ?zZ1jVYlq0pwNynbtA$uAHBbcRYyu&G4`QfE5CCOo3NH{KXej> z-*8ETg^4_Euerw+WR6#HwY$hKE$ZFjLb1RXEl&pB)byAKVIZNbz-!dr8}~Se2_$FslHmF!u>J@v3GzKRfQX$RD=aOu4>Jh3X(>2p6MH zzkkJ#Vp-JDd)-cd{UP3VaUEX^98<+ zr8Y0+>!|c-3?w`n$2umCL=FwTx}{QoC4WW+kV%AT^)BOjshdTZigMMwf}sHlRHz_P z?1$N|2@3v%djX@0ry}eud~t+?9LabY2**M{ukamyg^t5?trJm(Fz#3v>wPox#@Bvt zHd#}9(h`n3%W*;PZ*+S5ogVyqfV#mGoquV#BT)DBj<&CN8hZQS52&=ngGU3;?j|la zoYVF%@b&8h)Mdh;I;IQP6T@l0eb$Zf{=SGo1?`7Rv=ZwKD4(hn@dxWf{AJkZd9Qml zSStrv$4bwx+UK!mzgfCnNnLx33VW5%PII6lF~j5YA58xaG-}ghm>NZjJZ36{e?7FHo3HvMmDnA4uk=VenkvmyHoU8Vf$DH`AJ^0a5L1va_D*1 zMlbGB9#FXKw6)6(XEM4?G}&wn+?Nf+AtoF~0FS?6V=|&=45-Pm?tFM-VtSr4=6*ej z5w)r3L?y%q_D0u_mWw0>608#74pfyg&R-tPpZA^W3pn;3;P#$zV{ z9fQZd1I#}IF2UWT6BfW>n!!9|B3?v;oK*Qlo)2s#QJ9wk%(0@fE zNF0xv6M|;RJ0U2ux$3->o9hgl?P~W#6^!`VKX-0dQZz~wnDUm-Qp+kGHDxsspJ5Xz zA4)b|Y?WoyiBF5e@)Hz6rcg3h9~BRhpm2uJ6ou8 zF7~BEbrBQfrY!ZW;4aLfzSlA-*pCm!sk)CQFMb-T$;SxJGMXvl>{#67)H0`0(QXT zg1|%Eim-;^(;%t)F!-O~SM8bhq%9+#w_d5DR#z0)6|mx7B>^n#ZH0H~ghz-wl?-d@ zxS-9_2;swTSGC8cUMRaTZ5 zht1Bava{y)*0Qn_EYN!po=;kdTp8)iWL_(&5OWmOu+uAwIo@g~*<_Ut@2OcKxO^q94pAh5Ry zB7=v6$k!T>%WyE*DtJ5?IQUf-pcq}>CV-?x*k%B7@|=gd0wkuJz}RZwHC3{OXKb=K7txz%b@H^2yu${ z<>!PC^N~3X5=j*lE9V|xVNp}|bd<;E`H8?km~80%!9IUy@cY%F_R2WaPOU@j&7t;o ze5jo}@TZqUtkuiF)gJGwk<^^>CEAvQ^r80M>`;3Fka!R%yjgdlx@DnoJv!8$12SCC z0U-iF7ZY#i&Lts{uU+>|0Dj`B1YI{#wdxX4X9*)qVI|=LwUIDA>!iSp~ zoOav2)73Wv^OjAs^f^&AjP)-5q|`KC@7ZF&DdHlDo7QwvF1xYVSY#StfPokG79R1y z!%QYDYUkliqQLZcnZdY-P$Z=2ZVlbl$kR~@P~G$PWuN@giM@&sRiL+UJkK0i$QLnF zd2AXOL=m=mcx@E@b^G-^N)}{1%De+Vg7!V`S$kpOWEigbrFdrD8`>s{M zDGdyCYc3R5K%!#Yi}(_N%f`;sHh<>5HIsvH*lYbN7a7Yo?VEnIRQM9P@9 z2dgxb5xkD#&z&x#Ng}SO#QDf z@Sn2tEK`+LQmRUQ?ghYjzJA_UkZs@V_gj~$0rlc+`)HrpTISy{$DNu6&MT^zho2(m#La??7aM-z zw?t9dleFkG>?Y_?IKCN3qzpAX8DJE703f+;WE0R=qK3FUqmv_|5 zoR+pfXTFj4@q33FRoGc&U4mC6J7nzyl;bKKZq}&8F=Bn8cAC1&hfeOQt^hU0=UrV|A23MS^}2|&ns)W zwJ&=5WtCe`#v{ABSh@cKK5bfBPT~w|dvM51UV5r}>wYTuoX-q*TAd|$*}80PD)e3* ztPqF2@+RLr*#1Dx467;L$3{z=FRyWXC)TaPJG2R2FW%NB13 zLar&ublPjRu^3M2z$ecum7e;7PDSOM#zgp1>ZkA*s!h6lFa%gzSHYv6dYnh?_(u|$ zp{#yl%zf^7yi6uuMc}@kqo0I17GREup)DNGq-%tzLb55pQW#z!0|^|P19TsQIv0r( z2`g-p1(&OOmO6t@yLC0JO!=4hC6%2QE(O)Pz`_cCV%2=pl#4zVpuqh)GA$&x+W&{g zEAk@gmcKbc^`1IwhsTXhz4xRuQOrGjibI5-AlB``r}#}dm(3lzXNtKT6Yel1|AS-i zdk0ZHP!{-@wlBux%6ABO?%=kySFf*A2onQ7RqYYhsf|D#&yC6_;~oQkS2D5A{RunZ z%c4>tP3=_Ux*;`x39lXC^4-9~HW40Og`}DyiMxKQ-sV#z{{oL<|DxOP@N9-vJ&Fme zp>e9bdTp5k?Ytm+)EBSStM=>ZD;8)k7x)FB9Clm7Ve}0TOz{yUK&d8Ui)&&ILakku zOM#57sVY#X`-n&qiAiGU3&GIw>YS92%sQZ?W?foHJ`fkZRkWz8cx~A73&9;1Ug8`m zENp~5rADG}3d&6?I1B6){vuYEluqz9@*|N-h3*J7!KA2>7EsHEG}2CSh0sAZM@4~J zYVHx&YozB@uh%Q21%6Rim=!X_*16yEqKcT2R?B#r^Hu-6zX_E^(q=1*qF_-qJO-?} zHi{eNMonahn0&{Nt3m>aGE7-?kw_Ej1U|ShT+Eaf8bHwtVjgFN8Wx)*(jk)$*kl`+ z@TPY*57NMNE^J80D=&p=R0etOA%&PH=VtR8A103&VNpex!%p{n&{Nvp`V%)NQNgm#7e@caOPx2}-0xDrA|S*)G*Hou{wAy?o7Aeod2K z0$ES?Fm+-2;^Nuf>G?(Te8%Q)-!XqYYhpR;xA-c4mtOmYYuuhv_v~kT=ME)1?`eE! zdRRYh_xs(!K!?@DOAAFLhu$NV;Kk*&2Fup?1_@r1@cR%FJkfg{>6ur=lM?4em991? z&a2`qMQD%B9D9pn*Rj8M9R^@mY9#l>(2wI$|Ol8Abp z@3jJw3X`9_M*T$w)ys>~Z2nM}>bS zE(|TN49cwmrp5WBX31-Qa&sJnX+NCVI)M*{trSnqT8C2eJvM)Y98X18Du-Xx%bo*L zG_?*dbHYck^Zf@||0G(HyEI`hUXX~beSB{-cEm}p?NFbA<61|0Sk-CI;JgrB_uDF&EYE@W= z8Ov6hc==9bj;3&0AUiq=fyWEv4c*f&3u%Glt`oRpwL*&8f-GaPKKn#kyq zHUajCs~Yy|s@2U^hN>SHPr7PYeQ`JRUk+MCre$5p&{@86#5nrROL%fGB7IBFif27bT*(Vj$GaI!w z%lw&ZZpa9u_redu7DB{Cm0D43yTMLbcJECO6P<1iu5!-U_?-eB=G&{F$H+lB0&xE3 z`xkh%ih5lmC~t-AsU))F*6Br6#nh7~Xk%p~6g|!z2jVI^cS2xWlJ_RN1p|i)rwe@@ z&maE&j?jb3*>k0h6hD9FQo~-1qC1%U#nXS?E)lSROxh`C&81yk?k=+bL^g&@?Vh;W>xH4uMem4;z=2- zmaLf=rU17UU~mGPxTocfMlO5LyC8D6JZ}c}#${tRL1!ewQ(@(+<~a{L-IlIkf~Fql zw`}=G5@eV%L5m5Iu1KyM<^n$F{bi1O1GsWfqeKZwsC8qg@!h^eo;GqFV}g}RZ)Xw{@>))k z6ZSI`mdLrR|FL9d%B7KrdQ|LbO{~I>59=8_xMbNXVj-)&6)#(K;FOpgTh6Z; zW{beayUFCHh(&(h1GRM|fkpXNCyCW}v_9V&UP!Lo(V)@lH1z(pu0L&6nDnVJ6(oy* zQXR$=L^eyXRe|Ss^}Hc~(Cz8RXIH#18L(`bNfm@ba>HelmN@hvVCfeKkprr@-*K z-F~9>Pb%#s`3+}y{38kWQ1A0Qt`nI_2Epz6dInJ^&+<$sbutBx)>0>3x9oVAbkY@L zDArb0gi;RIhW&Pbcq#Vt0@DC6ixvB4P^0;Mm&woyR)dgUNl#)WJS#zFW))E)0Rt5e zOlBo@0!R@CWxhW)CvU#Yit5Bt3C8myh(hTyGu6qWwd|eW!6iN-v!*(sQMvnUGLbR` zOC3<1h)FInp<=6n?Fylm*^b(UqcoE!66>|%ynMW3FYHl~JZhcy+T5L;l}G7sxIBs{ zSy5f>D@da@S3hc{QC~qCi7^w{S=9KXLX2}r6o4)L&6>eBP!LbLq$xj85Hw=U1lX=$ zU%Y;*-MXL^QMCLKz))Sh)x%IlP{|qgryiwAOR&6wf=tRCV2NQ*`U>5#$u-O^S%iwX zl7oQD_DN>}z4idJ0lAQl)6qzDDKlY?wuCP4lsPVc`A|#O$tZz{g0Pf47R<(*VX`dTPV^}2_`=w;TP&+_-;62p#YqS~eFbs>Mf z)$8&$6>0;g+22xY%NaVWLv6$?=e7`KkM5B%*W0KA73EEqHLKgbMF=5fqxNdBYS}~* zv?96Z4D8340gfG;E<-xDrng#ufqBKw&4#q>LPRN79t#jfJS>4IwGv!i(W^z1;gW_w zKc9j+9t9F%sGw;j71RQdSDhc`(<~&FQe{!}iV=db560NH?uz$%pRA+~LxvmB@p%39Wie#?^yGSWJXCRZa2G^96jyX> zsIcSG&gpA)84gwSysX(-JnxUQy9Aq;S%Zq;OhA>x2|be1-oc@QJeAz8DDTN7+{~b= zfHEsl5CeK!Y9-V$Qx4g11{LhP@nuFD#5);nfl29o)VYE;VkXV5uN?1d7znJTk`bKqc}i2sly6dQft@u1#-lw-h8* zTh4pfZYf9}F=hfAR?v#dVb~kC`seBHA>tzm7}jb&BF z!+2-8C6D7?^{@vLFg$%l=~QZ2qplJu%ql^OQN4!(n~Fb6QZ8d<<_D3>Y3W-7!*$B# zwz^cQhoXvb;IcjeMLk_zqL`_)>v+7X1a1ywW>w+t*^R9rZQCkpcrNY!N0}K^n6%u^ zW*KXzWMT#8r^`h^3ra7*j3h**a=zQVz1@;rpmt~pdb)JWm_dy z(@|iGd2;^z@o!Ue$Q!-<3jf=SE2;OT%-+u*|4wShDojxhDT|5+mQ1d|JteUZAT|lc zOy-tun^&@yoW8)!Aeq(e9iN9L6&&Ev%h%t^Os&9POV!iF)Jx~XwQFl`s3QQ?|CE_p z#oZtQ|Kin%bZxwKD(6+>Dp>*RY3KT2v$sc+V-b=KBi$RAIA z0t0TaU@8>_H)A-7mDi?Cgbl_L<#8-?Zu+7I2pHTzy4pU_@PX)D-c&fEhcOIl>nE6c%s?yT8=QAp7AHhH+qMabiH*N$9 zKB6RGTCL70Pa&7YfLtBcUgx;it-ye_H!^ASav1qyHrWP{OV%%{s8>@gYV?`{uXT-d zWZCJtGsgyR@Dw4NME`FDRT?I1T#uvzl*hT%yF{Iz9uHbl>|CYxZ<|*-$syJ-+w4%* zI|ztT(`Ti=&C@ydd7?HM7^IBsD-TNnV!bm&2VP~;bOl~WREWi`sw2koN4~|yP6ax< zsnO1y$=x;k-~%tE?sD+`m4iJ>fH!+%(|opfZO-8kUa?#4J7;d#xYpUJ?G=1eprPT@ z4A{)6XByA;+@SH@_c`6k(S8be&GE7tXHS(%JC>R5H&pJFV-5wvslX`E0JVg)MVo5R zxS<%e;d#M4Q3yS5%e^1t=0Ws5Hs7YXY(F)2y6+^fk_ZZ7Gz1pN7rS0CcaBwid1+KJ zSX6u0bLPoKUmkAbSxdqv-ylnwZi=RsYZ|KdKu46hAe#Wcl`F57?9b4=&KtT^{X!sVR1r49=7JXvg?uqR zG|Rl16Ic@j+T553M_$1sq75``2D{S-uE(%}4Dux&ISii@2N1U|;XN;+%OfamJp_Q5 zgZG%FJ#v0z0&%;(Vf)Q&t;#}Cqo~mqw6CwzXiHT6RomBhCEC|_Tg^oGdVO%*>{oTK z@2=Fne$Z{{{R?SGrXMFrijPzwsb(b9G9n2-1=EZXV6#R*q*B}-iN#o^aoI3pq;GK+ z5;YE+FmLRdi=^R2tq{qEnVdsRPO zKf0@SRqtKTI1V43#5CBtTN)5DY)R5f+sCg8Up||Za@#vt^pr^)eo?DU@k=&Dz zSfk8fS#?fTlHN#Tc{ZI(B;6TX;e;MTOBLbAR1+xEy%+VhF`sLUyp1%*u(PU6h^j(G zr(-+XcI|1lGiuE2AztXO73LjXW%1cT)-g(1gQX{&7@Em?od zGbzWWsK+SETgqbLAS4uQOj02d4G-B>!^sPr!$z3}=?ue1;1-DLil9htpMt(66uT@q zeS}l6M^=m2?fE|nZ!b$y0t@dhwWg!xbqjB&{ltdCNG=Z0SZzpWf%w%d=VLG;3-ePh zQi0qSthIC<>hXJ6rt-|*kwhO-3$xbbe?n@5kEq75YG|0ejxLC4^8Mp}7_zjUr*wU; zPwX?6x#i9s{4hM#tHV~I9(t}2A!~TGbfgYnDktxhff6e{7&zq7Q38zs%D^n+foAh) z*4>*)=Y2wFKwwQg*>IB%{{*1uRsf?<>3l(FrT$N0q8u$t?8PkD3h?ycmm+#|(2x-1 zYSP|lULJ$c2nb%@xPcua305MdD?gEDU;u^JTT7msjW6G|OqOr^hU-a>Z{O3-uRuL` zLt+QtHG%}5K@VL`iLmY(jsD!M#?Sq#zWi=W&!S6SOWicHf9GR{iRC(d6pKmR6=!3r z*(+hKyPz6@x?ZjSBnDCO>l1@Bt&LhW;WTGa0^GiN*lD@EZfAuhk-W(%>Dm9*BN>#plXI1lB1K2$`dXKc4JEWwZ-WuH;0to!lKc#VfRK_c9uR{R`tN zBg-9+5%%}Q56zPFtHIQ*DfKE!QqqK*9^l#K5J*8~LEWs6l~;rjqA9e_%je3PB_Wz& zSWVz6&Lu~OcnK%Ay#^dF86{8-7~tf@@(=5a$%f~ktGhiZT054)z{p9w&8Nb%esJ{} z?x!i9N=6LuR(CAWoHE|aXsKkIo1yTbx|-Rl!hvfe@0;!gj!b7}B=-$e-_g)yj5dIb zBy;TT26-3Fg>yY};N1?@dM#}!Jg@O+qtep0)l77N^6r8@YM~M4aHE6HgGsOm18cC6 z^Tkk93b^po@&pc`=22fisS&bkFO=+3g?PPoiCy5tozY9dmTP+pYt})OEs&!q}JeW)ccbXQ+vV}*@|N?*P^r?zGr*$5^67}F?YI_6 z*)x(?D6CTLw!OThUtLUD=Ef@4h+QBkvR4fAJZo*fH_Goawz{D?Q+EAWxCSwlcjvML zv<+SIr=~Ln*2sGLxV1TaGbQb{MNivWCChR2l1o)G?a&=Nu0no8H;SF?K+1;HB(Y5}hP$aM!gDk!XxRatbLtnFyd&aDpg8bH3MKfQ4F zv>Mr^Q<~g+tDqP8byvEHso0}^Q_HnIadTH|`e1sEJtl*phxoq%m(FI<=A(S*gm1&- z@$6z0evAqS02!U$_IaUsyE&OER8E4aXVcIw!>*Nc{Bw&sb%!C?j+`pOC%Kxps)kk$ zw<^&%gqjE>DZ#d{I~3k>poExCbK8X)jHX9V?>sG+0V;)x8-&40Cd*=GrJnDkD~Gl` zr(+LJ^h5jy5vCrgoDtS4yHl{>DYx$rrs5Q`P>DzdDG}+T(udM&#cZW|j3$%)R{>Dg zN0uK+D8`$Z6G8?zK2Fw!vdlsk&kf#UE?%jGn}a)98h-6Itt8eTiQs6P(#M3+1MtWC z7A$q3^*2fC&sJiKs^7l z?Nl26Jj+uFZK|P&g$bvy^vtB*OORPs!Y~1U^kFgYZW}ZW%?;A+;kO3kwUl>oQ80*8 zCu&=V!=?I51=kdwnUu&G43#Oo3#i6zYWZvA#8Q#!G>gy(o@7N z1}}b}V}A5zqOSRS4l51aiiaPOatbv~qV{*(4xlytIT{#3Nd9l?^vBl2HT)bk%^=zk zg#vIjjV6MlwjG%Y#ZnMiKFHeKpLmbTt3;|L(wWI6a7{-Pmt!3^jKi`a-gPe`(g7*1 zpS`{QxqaQ=9%wFhXwN1aBtD9!YeS>ie(#Xp=qC%sIx?-%+=SS~haZC7X+-b#C8h=Gl8C0tzL%dWk zmd>BO4=IKtVpJ_fJ+p+j$@yDkRjR7O%BZe;Fl8>E1EksdbIds7NoL> zJyIoKCHgN&o2}mAEBKSEXWC4HFI3^c#WqgD==`pN0(Ji+s_;#xUkfe4Ny$20)I;i; z`GjF^##r+d!F`;d$1T?~Qy9rdPzdHLDIPactf5qV-#_l@9-6`#jo%Iidw}fAzl;#W zwyXBjw`-=1PNCv^Rl{GFQ=&QYZN(F~QHAUy#nIybX*K0?xmEni75ET2ZdPy_Pz#J( ztB0pOduep)?uR4~*^8s6WG9KBGKAR5t`S5lgagUUA9Wr7bQN_3{LYa z2?M7wQ#+U=`-G0oM5P{X>@m)uXgGqwA1IFV9{e)iKMGEB?soY%_FE&?t8M|RI@4>` zR?u-zX z^&V~fdh}BUEBSsp&Efy7k^jCq_3?fS(f=Bt|JHnepzrbgc#zNenlADAINYcImV7_t z_kK%}|AyWE8HmaG8Y%gP`~KRN|9%+v=@T?i>pkPld!qwF9)ID?FRgmM z=hXAdrFWt#0?U~s{){ZA+iO($^{|TnrgbxoGw*L(bHe|nWPS20BA7XL&AC1ONfE>V zhllppyM2)x^hYwz+UzWGB?2Wj#m!jS?1)9o1+5y=9yt4(U&>MF_|%dq?t;IQ_-&obf{B8%zWiTU)S5WH-BP}G2ssw}wTHT2!zYsmK)q4j5+Zciv%>@Px z9z%leo->bR^%^{+1Zd~~QqkHX~pXQk>Uj_Sv!FZ`n37!0Y}{dW@Tiz_IHAy_PQ-sb#ZL}Pr!v)>M%e~2J_QKYLP zN6hK1Iw5Bk()g=prC)=PTec+Vh3}QH+)H}=>i{dPPI*DEXf~LDyp;EoW7?6Ru|})B zyCin4!Zq8+KgAaY6aCWk+#s223p@3Y^T4v*K2ogSe-93$g8Re_7{*`wFBE&S^T?f9Hv|Fu2(1;#JF2A)@=-j5t@m?aH0hIH&d? zwX$(>_u7Efew#roNA*5R{_5XD_*#ip<==q%JjXk-1*?v_g0IB^zHs4gwE_EI1}Jnv zY(rkHj2FA`4A?hbplhNdCLMTyR|DE#uzZQ}C`1woAkXIZ(E8|+w3o)Sgf&b4$D@yx@;g{IX8s-&H z2U71>YrwhK&RZdf;Vpy@V5FSjDv<7fHufuSW5H&mlHe+Ij@QY#w1>~Et7D=SYxK+JfBb|t{NtyM zXwBp36JCc;9-LU4*1uvtmP3ky6UwY~3+0zn+ydBJaIMc$| zyxR_hCJ14qVlwiX+8Ln|q#SxSM75^D8db#|w9EGeHew2r*hSlh*LxqD9y`rXf( zae7`Xnjc0!4|1vOu%@Eese0;544$SM!Dfx2Zkk+t)j35u1xo{IBM0jT>aOeMxZaki zf@_%B$Gb$NE^FEi<@b~D2+hi`4M>y$Rab;nPacDDr=?kRQV8}|=US|d0D12{f*J2* ztaBi3`T&-Rd=sXV9Y+vrwJM$y!5DX(mw7=6TP~;;Qfzw7v6Tg=z`vMBBd`t>>z6)n zrq&{Jdx^<7b`5$k(c;*45!PJ|7f&{Nt>4BK!t!tMS~ElW+Et*0U=!N~w_NFFJbeN( zT0^d1YNtJ^L3e)InDLJP#Q|hUCT0g_=hR~7{A8@0L~XQZ9IVRr4lABF=E&S_nnL~# z(0Z*{sy(isRW8_`Ka_8CMeHcS4EuX)-x;W!w}`g8cW)>E@l}p?Km2UwYV+2%#5PB( zToMvfN=S4O#Kl@!z(U2IRR~tQf8F<476a~0dWIgLqqwP3si5L2VWpM#&s}6-{NxxB z`HI69{4JsGq+HS&!2JVJ#db0B1Fg`S$$NdQWHaE%oBWiz62a+E;E+W-E^u5AyLQuu zA(t?_(VQA~wS<-Dw_2w>P@o{*w^EfAv_LT~=n%6Onirgo{1Z z-f;j$6%2&3odUIu+5W){0cDn38@s*v0UX|#P0=hi60#%7Kapa=Rz>b;2Se!OhxUk9 z3el?2gl3o3$30%f8I#>w%u;_$m0aZ|Z9$Uata}Jxb?9{&4C7Ob|e~iQ$i5bcaa2O>Q zM-js%LKQ2{IiLN+e57e}&d!%z;PQQ6A={)bDa+dQGqN{cBZp2AHp)kucLXf8{*na_ z)LSv4XCzJQ;skc7 z0oY_`QxHK-43gtf08E{n2CyU*O!{Yv$R1bJ%mh+w+_Oc9uog(`nBj2!mj>S{9iYNs zR8rX^=m^1xlRb6RaGilB)*{X{l1Z+X7Ay>E0};-6Cec^aa01M9-@}YEmCc@oU1mMx zd-qwqs{P3>Ir41Hx~Y`W98H0mDld_$smroRjQ}@C_a=Ltue@A!ny#YYwMFg_yPSok zyH;}X+?sb-DIQ)pE{;`ffZqKoUsTv?m#>NyS0iEP()+f2x(;o|!VhlBsA z%sVB6mw>RDZ04(!G!-8?maGaRNhzWFjvuqX$uMQmjHm!K4;OSVa_9VvIr#8Eo}HeU zoV@iO(0*^|jlbs(p=47pn-4TYDL5>Q1JVYFy7n3Ba?(bAAxjNg0uG`38h)xgJpi6~ zCcmUKOsiKeXg~QULBH%e^|vWJ+sAGpn(u{Bd z0;7wierFiQWp!nAm{vB5qb@ewHyIgASb`73;z3zsB6nv%`7>P@+ZzC=W!8Czmo7bh zUc5hWqaOw)brv{6@5qtGwY*fT@F<qur+C(jI$A_m5D`Vc)=i%jQ@9MI? z12T5Fn233)5hvdcbqU0=n)+xTL?(mbd^QTr<-{qNMCbO?hx8x)Mu_F zzia%detiVQ4y6#FC+~|1dZTvP#v!rkL5r2<#rVG*J~#i!agrlbJ?^VL<@yG-f3cF6 z^1Wnzpe1HpFmN_^WM`QW)u@~cKlQ*p3wz6J~_*)|}EV1mg zoo@d#l%Pe{!BkV!ezwa?<6mOjKaTP7N!`~iFQ1v4xLnAt*Dm`v-k4WZVuO5^r*+ES zG_IsR=uTN02Fo_>zcg$xpCz*7NAT``?t3rawS305lha4g3mD{48;DlPflxMha9nJ2 zy5P_zIr3%$as8`LfoWE^jY-F_&MiK8I6T~snU;K-p_5>GomMp&a4XY*OQ@W3Jm>a7 z-WLwLKf5mHH&VC<=)n#+No3lQpcUAt$Ftr8BguhaLmB2WO0Hd)ie9*{^535XF4Xoii#BUL3dq))cwFziQqxSTxDfU_K!1`35jf| zzS`j)aJUe$KY)Kc6Zj^Uq7~6!<8~H*350LV0FoavErd9VUtZQ` zgm;u|bhi`ewL`~^KdWyLPi0Z74Dt0(U-5PEb{J}aRPu7^Mg*DcSshw{-POi9QQVD! z35S7zSb!BrFq+75`&V7Tr8w$b>t8HxM9FjkDpxIkZOqiCG$Y30QNI9BM9FMA&2CNx z(A1gnvdeDiJ5Wn6raVhMM|o-=<(LApNJuc#e6p-b;~6Bbh=RA z_c#j8;CHAq#+QySuvEHG%_D~EDMXJDQH;9hMOl*TDCp*^Bk@SR_R6XS2kC&*v*Y_nZ%@+InyP;5Gv}RQhlNM%v$ah1a{pR{eet zZn}mv)&2#P+4<5!?wfl^?h02tLhogiLw1Ay^=PJkE@NO~Hz6l-;g?Et!2aGfhD$DXIO=AB$zF~U8P*V zWy@Ukb(aLCQMQ@P0ayV_^sm4skzKVYOPB@us)2z56h)XCOYEW_?E?_~9Z1lol68Z8 ztTQl8*pSYD!*=+cUt||#z)EH9ti?Rct(IO4pD~2LW7BV;T4y>^S{|#_ru` z6e!6$?1}WfJPGXbz{Oy(w{`U> zlwP9P(_!ZULQ&Y%#;#c)v?8M88y#n%K<5hA=!li#HRvd&1xh`ZYK37;?%YU4t%*?- zrlXU*?~hMcLYyDMe3JHC69ZM?VtSkW?V<=%`U7cV{XAL_P+2JqWP@;JI&M@RQ>^OQ z>ACMYhQ<;-!E3Ld{kJvh6(8xx`V6!Qlm23)i{I55T6IEpw_`w(ncT1NoC;X7KHcs;8l z;0`To#~2uIUv<4+-3?|%#i9@kqa|5hg^D{iP1@NM7Yd4Y-69=KuG-U#65^bNsPzp8|fAc%%(%#E3Co)cv2^>F?SQ7_S@W#UBJu=twOReSo`nPs_u7c7EtwEI4 ze1(MnR+j1t&60xD-FrR;pu?ib96VE)i`Rz1#^u=-*7hK!sS8M(b7hD+)HBNIxFge$ z&#z#ZRsbfuzAWKF2^q|L{3Xv6YbIE&Qrr7`YDeyQA#F!zdR%4k#2=HZ0)HI=KGPgv-jg@3XCiiK5- zLnCLqGl|)OYtdc@M5dKkaF0?$7^Bo+eVg!GI4`#McTVjYnxuKbUUoR3z%|?)HTBE1 z4LL8TJZ0iej9WlM7^U6o&GYPj&>krnucz43RB&fn{MMDSYo-giGe?#Lx2QSPmmzR% z#U60>e!i}V?`Pd#LR%(Xbw$}8pZJh>;&8vz z$cCff$DFn8>1ykGd0i*)>1z9Ud^^_f?n&jHbTxl`D`SAjP8+D(#}98Kd4abiO`LbD zgso&Wqt5#xS_6V|5|*{GpmZSCPK-3S9I1n4fQ`}|BL9Ue>BjD@`@>-QTqT`Y6I}wg z1WfcAzhDvp265muy9p)7>OM%0x!AtPw5$eE8Ifk8gSN+Ph$qEUaa68x_t;0X%vxru zehbjTch+44(i^hP4H&x3H`RuG3B0mSr;yXYUUG|g zMr8<-mAJAgcjc*%6<4!-uz7A!5i)BkTsx+theJ$ttKr#_*%=qvaz1rxcl8twR@^}B z+88&;qM`5ybB&AZtL!xOA~7Sw7k6*cL6l+Xe8F68GP%3FQ4Pj1U1 z)4EC8w{MI5riP!tsg#Ivj`e-Y-sB~-F=u`oDnzf>@%cwmf16KKBQ7jvD_*rydG9?= z&qK{VT8`ap2;pbo^yjM_(!^-o2hjb(%}M;J=HUn#Rcv2sRBW9i|F=pN4X5#s6=X!< zP?7g%sZ8{dQ-#}Bxzro<;AA7DPZLcy2(Bnvp`=2n=;Mapuip;qA&SvuR=qM0x2UdNr>zL4B2QgVo*~w30 zlVuqN2V<398&#?kRT^?L)&#yM$b)K~I<8RL+Y2;fQn}Q6{bq{~@8oWNy=Z{Jen72? zJJj7lp3eQ5mnp>IOv0>gh=6$9i4sHag~)Q7bp{7r%)5}uWxcqMrd<4+zygMm{k#Xl zz|6dV@|%-+pIkP16Pr025CkUYd@$zA0`o({^K#vi{V(=Wi5(_`(KPgvuNd~Plpyq+ zRv*m)kT};pZYDVbu4|t{|M?U>e0 zX@Xm+QOXKDN0YtD;3{K%&5F?}ev{*8POQsS(q>2_T?nd105tVI_83Ug;g9Ga^_}(- zfFGCg1-N!@@6FxWdix0-QF*&PeE_Rns7F8>xkuufM!af0B@jOKWxl=XIr-;}T!%7m z`sn*69mvzhjI5RZj(b}K;s=n}#gf^UZFB91RjL(6wD zw{KkAiyfQjVx26E{ws-$s|cd@$~{lcvG2caf4ndx#hGafl~$s$$TxQ;b_-NBKCix~oAwrt3z}{*5;eJn@ZOUCsy$K0ZWz~bi8p=7h8!iq8^M@hv@uCl@31HKfnx*y~w>W)gi*Oc&3=m z7C*{Cr3|Z(L-1!x-jycMXvf%j$89}cN%`wh!!(Jcab0v+)tcNkS1An88HzGtMZ(!T zc9jh3)KucAF3|CI2!a{I`yGIAP`ar&X%F{-|OgXa)_ z`OsL)UN~z0DQMRl^|-?7pr8o3QBf42U%!z!L`SzoyKvhT)79qiaw!sR_pV*N6n!K{ z+dk&&6egNs!W3WYucg9e52RQ26ehx1GQ12v;gOUrI`1OAB1j0V6v=<&Qn}(8Er4sNf|9xT+v_DsZ8ubs} zUthdsE~Ev>jMM-=3gwdcpL+4fW0!9)bQosO>_$L{colddR4saTSaXJ@tQ<3al2pfa z`8C+(!a8YGTO~)@4JpWTHg?j^3W{77ryO6XA2w~ZvlE}l7M$w2p-6snr!&|;MO&Sz zjE-nZ^%ZkIeW^f2r+F7$0EV_1^f{Z7@X|g)dwL9e~$InX!CXlRCUPk3k z=+R`BJajM3PMH4{e8|`8p0caE@aD7J3r+anIOzCa8h{duf(vJ^DT$F0}mSgkZQ3%74DRyo_i!C%#%Wu-0N^Ju)B*v>Zd zj>&|swO(hG|EgJmOMfa(b7%`Z!{m89UjAOPenT@~Z5}va0p4R@fDRc#Q}Zo9+0$ph zyQl7oF2n=I4P7%OK-B^9mzje4aIC2g79_4oTGPspJEi4vXVrh&w{y`({kS#_i{VK5 z2L&*{8I&V3y}=*<$y9)tcfFWitl7c`bc+oq39mf>tGECnZT`k7S-kr z{#IxlZ-0`Z-U!h+j9o*2(vOrlA|(k>7b3F7vT#Gq9JEC*@Y--C4AJg4uUyhSgW#_; zO8653+ehP|6cW$dx?rNJvO1UVO0 z*PA{exjd}gc>r#U{$*`HVN*j@1&o2ztqnmsFIJn{wwgGouCjY}SzOFj?RX}V*`$Ik zY-1l!2)UPUCqr44FpcT-j!m-bAYUrp>U*X2j@N%v)L(8}R=v+8HulCXHKldp)VgL5J+4D7ilT;WHZUhuik4me*`;Ew!5 z(3LI-O$s+?kO_jzZUEx9VXW^M0xteb-whtUZpQ1wU8EPo+^C=IV(1oEs{lV576B%I zbU(C%5bw4r->n%g(qSJl7k#Fx?F;D~B9Q<0?bf+LfaM{`0eQ}Nld!$L?9o4h67H-i zWoq-V6&tFok|qmO+1{jB-RoR4zrqKG{zTQXu1kNa&k-B*!R0ZmdeCe-#!Ty_zgZbx zder9hZF|y(#yLMXtVyKzrOAsQ`}1{fc6c_{v>IQ=(u%<*-+HGdVvjhVxJ#r@T5|s} zI~Rv2M$&2jN`2H-L{SSdJG{fDk%bp{M#Dovh3#^Z>;ME%L(gL*6lEuJ_obGb_`VEO zhzo~wiItB@EPUIqd%ruI4)p!%RwCuuH8ownATRedYWeXY$0_(Fn|762w?;7yQ;T+9 z5)=%mF{fzfnk44HV#}zFU#2NoyJ~8YRDU_b+ZOir$e7J`$lSKtU@L-K-g~=AXB4|h zDuxP*ZxE^{1UZBk@|VKRx0<9rJ7w1viF1$TzQ4G)G>l2DbGk@wbTlHrVPTB`=O;$o zVoAV%^cUf_u++T*2~+{F!`*)X2jME-9AFblEROdL`OcN%Vq`cso7vHZJop>Oo}!Ms z7i(v!?A($-9yF^dH5Hd^Vbh|q6>RB?N2<8=h*qS?Um?#a*9C)oUSCNxak<6v7rVd{ zrf$nr$b6tL%HIlQ-Q__APKRm9(^M}#4Op9Xb~gGgW5+~43UNGebMyC0ro63LD-{}o zMkVZ?60&|Tf}=}Z$&YTOYdMnVuzsRT(Pi+!EIE7{T6iID%YKDMkNkDUAEbT(Dwabi za-WiVl`IM~{pS2|NA)%(7_F`4`b*Qw=n@Lj5@ORdG&QNxyl$$r9!bmhnQf5bW%rYNdpX@DJpN(2hi=I|5Yo|#x0Qu@Jpp5} zedH-wq0#byh5SpP*a00e7Cl54$t!Quk>e8Jryz#lV~6h^Xqfyp6P;AOwXFN1u9Hgx z=N;t@hGcXXjfRH`Z|dE&M-f7(=15iVYwnIZpXnW#0~u(KBho;hDu{!p^<=VTSkDv? zzLgy(Xv!PwIsr>+v+-(IR~jwG(Jd{!8Zj#<1%np_o9QK7pMWeZt_P8r2^=&DIQ+e& zi2IVvmdlI}{JVD$6YWP$n0n&kyx0|Fc#{!X(t=gz>?dgKeSfFIqhjU&inJRk<&h=m zut*C6qSx^dau|}}1R4E&B!W#Y%LEIhay?X^(_whL zJe9syNYr=>q(%|qcy=P(W6Zm;#c&&jV*KUgxYRJ;Jd@}p3E2c_MAYf2 zmhE5#Ee5xN-|cFIVb@>iMN-cb?X(P3~$?S^+QNwG1qtNW=!7? zN?{qCrSd>vDNuVNP< zcA0m6?kg>%?G1k^BlwIn>w8W|(9+y(B{zbA*!26CD|5(@1wv@w-pOU)(B52h9eQPg zd_T1&X}BQaAodn>Kx%4STE8Wd6&2eQ+jM1{u}%Pl&mwu`4xiP+ zp<90(HzOW8awoyUbQsWOit=Fpj?oX}22)8%8G3K-r*A2=4HECcB$hAk{ri6J+1~hw z_Rt7v!s%;aC7D?rVU?g@n#m`1Eyd8hbq(+Ncs%x@2DKV=$Csk{kQJrHV8Lswh#2Y;`SKR@PPo)}K*&zuJ%xq6!jrfw`nErz z1|bm4Ch818PJFUXaiPTllA!Sb$xndEr>P+wjK}Ni!ugiWT*4TRfT-qnSEaIuu0oSt zk*TxgO%^-BM}copk|((Bq56F&#QFjCFV3pfpzsu%I=X!p`g3l<=0mpx)Ep{yw4e8bGo8e1 z5nu-4MxIIDifD;`#DwmT*zdEx*E*YjaEDVn>L4Pa!#@c*{nJpBYV}93PQqO3*W0}h z!|N!KEZ)N|)+fK15PDK*d=wS`p)ha^{F3v>P8HwrMd)b8c!XAwj`pXiapf(m9~wLg zO%0LnBoaC*HXG=Z=p~b^c#@wuJ_8ltHd+G{<6N;FgFoRoI<@_rp`Zje8iKo-FD z>C+y94kJXYCLD8$^a~0kx|JmW1Nd`O=w)Wo zRG@!;UZzw=?UjeBQAlsTsI@6+xA+Rb$ z!tyX^a8HQ-@U9;86x*Jj*#yNRUWn7Hzp+NTCCu#8umyI6sIk})au+X&!#{|@V|2_O z9hE`Xp(kQ@xe)#U^bQp-S*jAT-?0?3H z@`r(3fUvC9f-JZXy=H?kyg1Laur@p2D(u%rPqtyH-%h9IJbrd|50 zy)o)*DJ`qCo}3={SDyoqmo5A)KHZ-0Uz_XwBN^xC=TGnY2e@wUrNhjJQ%o?WX8geY z-bRieLc^R1w^^uI<`4PV$r-;Vb8TVimu=YP$CNe=>x-6Vm5)B9e~-Thl%Ia(Mrc(z z{l!CohPSl;9ArVr(j$waFOFj_4X3uIGt`{gH?mZ|TWM^M*G@}+=t!nKv`Xi7E`t~~ z;T}>N@`i5tU0632Rhr6|<=muM69Q4U(N@w!JtA{x*C%sdcD?ekgUb!A1g-j6Q)B6h~3EZJ$8jntld;jJCL?cEHl5S+6a~OZC}& zJ(}2iL+dD~s0}+?CZBa%k`Q`e3gX zimOWUkQ3iQh-r3>3adVJE{B5kW;k6_BPgJ*W~HHOaVQ`yiSg8=jL$EXtRWhNc}&{z z`U9ICa@_*d&n$${Ucmu+Ml;*j49*r{%OvZ9xzP_3$EC3=IIa;rb-YFeX;rx=L=n0( z2id(i-}C_XeF%gMnd zIqsw%AhQQJFG-K_6e8nO7Zf^Ejt&R(ivA* z9df-Lghs|}&jv72EoVJH%@RxMm&e3Kmd%^(0YTm9AZEoQVr4O4V0e^#i(qS@3`vDtPR!} z0u0aTi*jL8{XR*cOBqlqMb%3@%+A#?SauOG_vxuFyUR0FV&dpMEE}z1-hjSO^9`+h0(w5I5tZX(w7DzyfIx=8GtKO)V(d zu$8M@{X^mGxcTFnE!ZVcTl*J4nQm#6tb#m$#vuE6qxR;%?X+|4@AD~q05{}N>)70s zdO~%%Ci-cFmana>Q-i%NQ!PZ%fP2SoA9l{$SF4AOe8Y|raHPV0lO;LZGOfqV3po9w zBc>C*mCaauiyRdZHoS>y6YE9mru1*oi#kgszq{d8YA(alLLp4cn|=ohMvPx?Tc@Y% zRR=|74!xQk`||uL+@36Fk}kfb9*cef z`>*7zb_`P2G&53gAM2RE=Ccu(aO!%@Kmx;x8)j5C-n)xsvIW!DR&4!OOer<- z(b+(s!7_t31fTc_sm)M3%}Z_tcVEz+k$~P3_2l^Kjuz87f7x;d^S)F{y|u5Po3M9_ z4bL8c+y)dPXOq}+wy9lz3d3_hC;dCE&%IlUI9gQbOb1pa!^gsySUgkPj-j*-)ds$Y zuODTf9}PLcO<6$iFUdj$rSm5Xiw1&gLAVqgTGE-0+@QU}s8b3hLxo!P(cWB!AC@Kk z_V>fn*LsJ3_xEkby~|}s(*Xi#doQ}0`2#z;Jr7a@mQbWK-FI@&MZb# zhZzO4*pApvT5rXm4y!Khuk>OMQyKD6M?qJA`P=b z@#XINi6R85CzbGu660%LA3Ych?^f$=eb4v#j*6D&p3WY3CY{u5{^_8U>{}&$mQRIX znCWb7I$X>SMsg=%WMeiCb~v*TFzclFw#uoV(u@@Z-jiHXGcAaMl}}qkxkOasf+hdD zR8;K|l`=JYc_C5u&0{K?0k=x*}#HvPSTLYV3!1%wR z7`+WVpIhvYKLe>azwq3Av zs?7i!p>wObYI|x&Qaz!-N%s!#OVqTco)<5ESO=&P>s$o{0k4b81UTMiewHiD`rx!Jk#x{~5@NZKUY>#{H#UUkG5eyy9LwhYRam&Ud&)e6i56lTjqm2{F zo^sg-u_6`niWD$pv+f$xgFa7uuqTTw(=TI)m^Wn}=hd?D1R=Gt6 zL@Z(2r>d&4mLyg6eB|otEemb7%Ab^ik+P~qlok!L6+k+3F z2m7~~H$dC_WzILB$^LiLiBhYYSsRJH(x-^BVaA*t2crpsv=A8R9C-Pre!$1-1?4Sc z$HJYv34^*Lkx7|jE$#9B=Oh7I95w_UFwT1Ik#;;UI)Act87nWz^+IMV> zuR3T0?ap1*oaiM&=??uJ4ny|qi>HSn^J};{{`9p3n0DmNvPQXpy3b>V&H0Q2Q4cIF^pIJt}X z#b7*Xw9Zeco_tvWELM;JV>SVt&@n=^vq^@2O5RMeXkO5pCJjo04+f@j;{5qlgltUH z{W$5d+5lv!4W9kLw0F#1k~6LX13n`DHPFz6D;?O{(bWxu>le!?7m+3#5xPj@sWEgB zy`AVnT*}5?#=iWKoRPUuiY_;C@?5mt2r&(NkeZ%mU~QPdHiw@AHstU_mB@-p8l1<3 z*&;Hi(vTbSccu}Bh`p}7^Tol~ykG=;*=B*rDi8-pj*N|{kfo1-03tD3@{6Twe?UfE zPxGfGEltSFzUXSSoiBI=xy$*=V)=7QX=vp3j8bf!6Un!s^U7BNlu#uu**9QR1V=xIh-q7mLB#0o+?mBMW#dAL z{AICDb?Z{5k;B+f@k}n=QN21SIR~M1?^y-_2QCf|e6Zywn%pyfH2z8DC47?j2|s;d zHaP=pY)++J9fm(vPeP|?o^SiWM_(76?rdxI{QC}}H#TA*f|2doddEY_dL$!PE9LX5 zeA}q2TCE=1jBgI1NT*>eo};A4{%L=2qq%V6;^B_aQn75N4r@j;!i@rC`k|`QZ_Z_1H79ke@FKF z55a#O<-lem=2FZ31LbgHdBlvyDkiI0imQHRnC=2RSP_pt2;3soqSEekZ1$+rTm(Kk z^eruX4_Z0vqJ!iBQ>wW0>0s_NpOeLVPL7K3fiUTfV~lG1%^fNF6xq4M`qXc*1pEVx z0!DcsXsbIsK5o(wYug&xI!4Z&$*^O=nylC_9;0^${WwQ_z;z!MGzE(S0MTd)1NbwD zd^9Q0qlV(&LD2Y*g%wKdEB|#y^oAJ7qgBZ2FmY?JoHf*4xmGI~aX5NA;jp;021&-p zBnRkN8iw%FL45s6C@M6{gRwjBRJEiMVn3t`GbeVXNgq_oMg z8D!b>NEWCykK_tg4THq73F?RAU`i;?Um~|}G-uFJJamL`4XL0SSced%9g=WH&nf=f zzQ0ut+vq>$)2~2%qwMJ+e*YG?)Pt8jQVfxVis`A2gdE=CqvmN^-UuubfW@K7#{LXE z=ZKqfn6VR7Heo+L(bk$~UfB#xcn3I8hk9)L%B_uAm*i5$i=>RgHt8%s-nTFI9b}@f z_-q{dv8Ys{uQqbV08*1YY5u6~bK5cY2ls^v z{41x%G$33u11~l~Pdn!p96a#@`;tJM} z$?H->AH28ysOkpgBZ5^{s}{)AYSs%KER7Oek?sr-rK!(Via}@Li>AX&we5@H~llSK45LVMTtBZ$92mYr02@g>}{|?K%E&zD!udo6w6)`w~{$ z|5>PUu7(#!QW1vP0>M>|^hM?@&{c5ctP46lH@zsN0Nh=!&DY9L--sgO7doKZABTtb z$;*$_!DSoSSC~431}N@m%Hc7?43vnKtm4#OhrVkoE_0^3k71iAp8pRI22~#PyorqK zb8E;b?~Cx`f5A6)0*`N_-QUP=<%kgCHOZslF}FI=GUEN*Zb&8KweOCM75Z{Wi-{0z zAaW0=hKLfN=of*4v?d12v6r*NUcmXH*$aBC5x5tsY4Hrg0As+^FsW{j(#F_tp8hBr zx*^TFst1?^H)=}Xw!G03rCu4pCxG;U18$^(DAZrL+gj20+(ML`j2Oxi6J&`pRKYs$ zdc^uDvjhFChW zl$`vi+paeiQDG)ru}n%r=Ae-cyq>pPt*Z<$nRiEs6(nGi%^eZn0d8($Xa;x0g39tV zQ1CNa(5N~MztV8KYY|oZ^-n=#O77+e9qWFFzv2zyRVq-aBYq=nKX+B~kWq>F5imP8V&l~cEg3;S~Ry)6xjTGg$(AqgXDz&qxeVk)y zlPv$HWBr6l_EOJYd!6y&*v7I56A}A@dzi6F$tT)paWskCa6bWLHII1a9nXF20=gRv z%yMkD{e@w(?%w1Wk$5_wb*v1mG2Vh^bx1$$`&$_y^6W8p;`gc++J=Wojuigo9ER9V zBtT06Ts+E&qS-8LS?Tj29>C|UD~20c9c*aeM|s2W@U%b0XHeMPb=tRbL}mXXCoQa? zO5@@??UO=wPF^*KTG97(gni(l0<#!2bdnk|L05iKGsU((`;kx;8qHQKL$kgZRY5q2 zB``mes!)$_5XT2>r9nMeRaj7Eod$}Og@d+1kFyrk%=*<<^Xej16}ek!duQ`KYy_Dg2%GVjXz(#N93MId^m;7-qtHMC_924tZZ2!+SFsg^kmj#_YnMTv6_LGp9=0Kh$#GEGiu7`e zIf1sTYdD2IZ?YaF|L3#Ugt|yXle>(tOc;us|6mmne0#a;Qsy_!)Zz z;O!#ap+M;ld}xH91Zhs;*K2$TpNcWmZQH`0%z?KAb#8zwXrwOgkRFdKM6Atdv7Aiq z&~xEkXSY3aTm{F3PzH+7guz3d#ucoub4j=2;Xv$$x(S|^zg1^5gK*cy-uH8w`Jux^ zQzXKnpb072(f}UnJ<0)f#8apvi_DUW-`Gw9-!gVdh_U$E^?IXHmch4d7GHcvQa&Fv z?L@M7ByAKIG(c!Kz|stA_~#$#p50h!-(S?SAYo(UbYJ!&SM*ueQf?JYJMqhfqo#|D zf4838v-9MtQM;B8D@1SSop<=99p_Yu$xyy;(U(HUN>8_eU9m5&t!l1vDDL(>{5{LS zuuYJ7azs}}Ulhkrc=%l(311Feh|TN=7NWu@Hq%@SL<`(TSw-5w(lsV}U=kbX;bqm< z23W4a*F3zvySTY6R0`+{{q^?#Sn)5M-`+(pT)w}EUifhJ@ByzJy;hj24M^ykxG8cu z(XJeZA`#o}c%5*EK`k^=GrX`3a2Z)9_08GiMx|#yXz{fqSncyBm|5kW7mxb-5u&SM z;dm}`Urr%q6qOF)Ly(fpE*O|%KK&uKy`|jqz`;BMk&Dx0z-$&#)Do}y!zb6OrDk2} z=&n>;`I$32@+ME6oK3yTx)g;$Hh9QuxJ`?zaH`>p9nxM(s)lVUklbz7=grA*W=YVz zg2%JP8BsGZ`Z9i@I|1s_HGwF2#u#I;F}=s$OijUbH?iDV2o?2EOdoO5VJ;Q+c%v!c zaNq&=cLzD^zGtuVexC$wdPIFPf_D2PuAGVEf<8YK({Wx%Fdc?C$QQks!nm#n{D2|rI<8AhR!}( z7j>+lo>DyWrx=sBf4UNW6WnJlic6eYxrUZ{F~;KMMY&qbe|}Vbs`vA>vAFas$wslc zWs?xBKeFFMINfiEDP^?9b#`9T2HjH5UCumLvkc4{;0s~j+OkL%jXq$OPEhYj%e?X} zvS8q*8mYC+oo-{8RMuxK2??}Sv9$or6GEBe4s1Rm7)@B=r3&g%r}NrGg?QNNnadr@ z$sPn=U4kahQwTDB{y%%)zT38v^!X}87T?DH)|NzF?F7+4w(OH&azmW#!7K*&KuMIv ziA3s4T4{bZZo~;>KBMZnRlD?=rYAsKp;Ipjez>04NgM_zLAoQ zxOu7%eNd9Iv1;VML77|>6%0J_Msa%@hdE+`2+1FzH6upfcIR##PbLWSpts~B_mj|; zkCI5S_Im`GCpD1i!OsgA%2;+q=l1?NmHRjdU=l|tPa$W-F-y{g)d71)raVrzhg=gc zmlJCC1BfV{qqd@A)DR3MsH(dgyLn$~DhF@6bnIKcnmVbgrZU4znh@5o=@1Gud_G5u zxT5Gu1AR2@6s*+a&`fPnEomK@TySh&MS;8Av@0@jzTKUh` z##tZYR7nVA+ZfDFeBYdEm3@f@=bp$ul2L${L2wa?GaO*@i?j2wY9cXq4K93kxr5rb z-FItkQTGd-RVIm_QEVA6%lsbdK)@N9uPvr9`P}m7zq%H4m_L~iYkaOTf$n4Vcvv(p zHSe_7y}VGETAt-{EQ6!6n?YA0R#4%LiYz+^g>w>D9$W>gp#trCNwDjkui&GE7`4Z7}=ECwF7!ZN1 za`&ff!i2%veION*+LTf4NSmBbo1YS0N{Mr}Iagmzf1Xz2_d|>OsFwv2z!p3Z0ssmh zKq{9c+Pj_MFBu zJ@M>8DZBi%*e)+31#QAKGMht#2z)4qt^54lTOzuY!CEjDLTy7%Px}2yQtk4OBsQcf z@cp{5LAb~~rrR7zACEi%Z`a#MN8)5WT#pr>l06xv6O!^zhTeGykyR+8pwne7**_PK z{oL2S+R(;IRbqV7wkF-1-A|WFO0A}{V>svzE~oPIIFpxC@8C&q*p=!XtP<>OX>YJn z4$^AS*P2UP?Ep}X3lI6(s6VJcME3OBho7&0Wqczi)WfMS@E+)Yg74L&quHnnnfFc@ z)l9ZJff_diwmue3a<7k_8}3Sgqd*bC&?jJqLR2@db*It20zuM0Q1C%Kofc(dJC)qJIc8$3ix6jVK}og zaB`DWWR#VlpJKE?q%G+V67*BkmiYXvwk#b9SEYzvFPRosL?znl*G?heYmtU25t$K^ zd{{|AdY0s9ggl?%5`!cY1*15|5&$AW>pckCtLdebBE~Y5Jt5on3@x)a^Ry{ z0gD6kB~cw3m@!RipATEpJ~L)!gY!R*0LKE({&Kfwx)TDlY%e(n7;a+EnQg#lP)Hzh zDvANY{APJEAl%Fqql617`q+47jfO*gs1E)8LOz`4k26xM4Y2$!yBoKvK}2&Kf$51A<3Aj6kA6wi*A5=3k;X5eY856) zX+FZn@!)W8Hf+N=#zWXY%_O&V4G>yj%;2d%h5;O0l1qr%pJfwrxReKn=1g}%UuW## zWc#(r+=VlS=}ePZj($85!S{p%lfkB08;Fw|cC=pZv`Zzs^oEZb zg(fqT0s>nH+Gj0v_czWAZ1>ge!gbj85okLF3fLKPamO%RMnD5l4Q7%&b)xVSJz+P4 zEe8lXkL?m1&ez9ydoYV2^W=HX9D2fnGKK(OIza5@=kpN!M1;gK^*>XkZ^uJhA;uMZei6JjSvngMEvjn3SI2 za~1=KjO`t7Kw(m5ZQPQ5=%cN_FkwfbG%ARCqidLd}aWnZD7c^p}Fjr(8;~AzJug|DnUM9#lLYt zOKu!6iSRAwcsq}3JT%140iXr`Wthl`Xd%JL)8SyEW1pZDCySaF=?)T{tmbFpdCB^j z>AGGOKeGe}y@(dXZNILJq8pTk;>VDp1a;yC>MLE`2gaN2q;0mMhn8mCa#*x;0HUO6cf26;USOn6Q>@wWJygKj ze7>Y(Gi#~ACXFn`!qE z-y1aK2B0i!t$Q2*To&EsvagS(1xY}E{IYl$Yxy#`_#vz(<|fr5*jPrp4Dun&AF_6# zq2K{3DM+H6DKPNAnd=w}sDQF)I))Qe3V~5QUmKoh$_$fK6f?=oi5~Qk8a)&ydFeqB zh03I}F^!i%#buB}L=CvJZ4ATnahpeEoF4HGBPyCl>keG+kn%~mq$fHORaz2Md33g1 z;t0|kC;N#Zvg2Av6QE3Bh-L5$A1jw&0#K1la@?fQ~F8pK;F*8{) z-0ActBl%()fiH169iDUtGBi^2CB#_Iy}e*P>m^{%{2f(K@ULZq(9iYG$*{=87T*_) zJlN?yESY(wBH;{SYR*b?T>8Y(BKRANFQ8VXKPK2z}e zJllXy5v1B;#WO`LtKQwZ$H5jsK#4|Gz>BUO4@m=cm4E*6uhf(8B)3FsvrX@=o7kBY z`nQDc8g&MpQFQLhghBFh6bAgG2QCco+(VjPTU#*tVktTWcu)aP9#9n|y!(42p1hTa z$*#7*N~{%Ko;u9*nk>`;%ughYlkn=jTBiAjqh1kl-e3Is@#@3nW%&^-GMWSw5ZK=Q z4iXelv%SU8xxE_Dxq1n9Zn*)8#&lr$qM0gik7Gk|q%2KrdJ}HWLyrb~6zlb%+aM}0 zUH5>|5YuvQV%JcL-5n2g!kyU>z`^=SZ`mB_$jm@k+c6>FWM-%`pW zR`Qmvl`1@s<1bKvOhaI)_B5JMKpR>vrXGQi4q(*6U)=FoVgmom6CoQRiTrL2X|9EdZSlk^oE|Dy^-_m z6ufY++Z}d?&?S(3c9u7#mxGQgPTCL@uc);;m9C&#ny;Dn3_3>^j+6(^d-{am<-;Ni z*LKnyO)jF+zhZI1FIE#Lxq>2gw;ZyZVbC8Ibd;%D$Jjitek&3Z+|gBibWyRC>^;)O zGB{zC_gFsz$Wi8~KTCCXp~K5OSug#$?`Y=Qy0&m^Nbrfr{84XttAz=PZ_pDy2bkJ& zq4xOr;R>J%tPPDEv&ggG(i{)O4f8DOZ6}fMX$PKZYF8ZFsEA2MlaYQIg6K)FNAK6> zkuYF1D{jy!W#jRM{8Gkz#1#goAhyA1$#w}E{NGx2=RG7I^wz4^l~+zc5)4u(1dos5 zKQw~nlGu^DT26XjV0Jr5KGNMG$R9|puhten3?g>Ggh_Gt$mN%EMR8-$kN33K0I=}q zAOFf!nf>|4zhA;uyXMjXv<8a+MS|i>-jSBfu%~)r_gCVWpjBhVi;26+l_l19FZdlK zI9biTz^7!~i++s>B6@a&NY1nI-LvjRdPYO8D0pD*g=z_0Gq0%VS@2#7;dkj;t~#qq zttD~KqSGLKPkD`@6i{haW0b$tXE4q97SdoMf=`GQWX0#)X$O#8L^xTCD)HF{&H%lO ze@geD??SLBb8(2^_YN3^Seb8K+e}<9Ak&CQpn>}ppcyU*a;K*JZR&Wao&~5ZLhLF8 zX;>TcuYg5{w8WI*L3L~LK{L~S@TKo!;~uAdks#APnj>WG3q@8HfmTV^WvJN~VsPYs zjX6x+>>Q??XQu$O0{bF8)k03YCryc@**MOcj<_3W7>C5!tF6v^2Fng2-}wq zJ~GX5`#axj4v~bDhHlKoHNfyXgqBDZJg8Xaj=i+5caan_G~e`HV`VO&7`r)1Bl+UI z%9cq+OQ{xdZ!|~0ALMr;vYSgm&nL>`uSJW3`X4n-~+n;#RSzvFn+B zlmf`QxENhb)8SPmdB^W?U-B*v4-gXT$!w}+Hg!()^RskTKrt+XcaUHTC9`QLMosIN z4&*8@o3dlKa-N++SqRJ~TzKr+N@f#skxWaDoFO&j@hRbV`A`9qe($W4Gj&z4-^t5y zzxhXMLO|+x*GrJ1B*nI`CQXe%gC(SUV}~@)hhHWPCyw#USY`nLmVDwG`1mQH0zQ$5 zw}^q7Ie;4J1!FR6%@hx$3XQeLVb7ecH3w1ln&}y|>WRAMcUXxR(o$%e90X5+HZ{T= z2AJXiy7=%fO!~yrZc++r($&vTa=pgO1JN^KQGn(v>!6+c-7J5f16odnq zVUr#0-SjO^+J%9vU?=jJ5bWIf>o=b!ZxQPXHqSHtmKK@RWT4UKaHCG!SuSZB7u)ig z1)&i6UU9_;gGeao!&CiaALPxcwj*jD1!U5-SO5Lme_6=VC+tiPb87z!9+ie}D0;-% zv^$v=a(gf}3!5O5Zqeb-uu+{RHfo%jmr_?!$|N18`cz>`Q1Wt0I?zXIl)t&_qyyiu z|w0Zsbdp8>0Es9E2F8ZPaFM%$#qL zYfNoGhG2eXOS^!H(|j;c+zJDR;Vi*^5Mm0s92Jrd5QcT&O3V(mH&`pv25o=6F>T02 zur(ElQ1ur2+>n;EaIN`Xl`_ALV-Mk!5m?=M6Mb?AhXbEEa{0GR6YHa1jdywk?xjfSo5Y}BJ|CgLIY zjFU$(`G5%k_VpS9^NhdNrU8(rHcwKA7Z!=NQr68`7e^$n9Y$a}3;$umzH;*=k-w1Y zhxl2n2JpZ^ct9-xVE+@m0-knJA+C{I|AB9mbDkG&kRF+OL(z}-q zR8ic#Fub{Cy?XYG>A2UH0gqcvY%lgnVoSExoW10?7v9R)GS+1R`M-Yg8kRVL$1>Lr#C4nK>1a(B%a zvIf&bnsskMiC_b2@lk7|oVLmuQ%}3usi!&5&S|R@cK1C3ZB%u z-9#045Z+}s|8;fC2RUQWdU858SlQ9M^=sGJZ7GcJt-#n8$66BHblDk936v?1Vc!A# z3qCIIKGG~0R1zkYa`4(R-sh7}zAv5J?8x#*qm$1@-F~EGtLS8Y2MLB#)5$rlh^5m5 z3v_aJMqtjfb6OFFJ%5itCtn%g%n#d#?;;lTTMm)-LKZ%s4$dyI14E956C95$%Qw)H~nRacVzAn>G7Z&DpWa_Xc8tVBW{T&q|A_C##!WN?tA*#b*(B%ScZN zN*LF<371AG4o={F=ej12$H1X$p6_8b)s3UgjjiP~@B6~OUR&NuTbn*M%<<8_I1p}Y z5U9`6bvCL?uDA(>Jf7JZ}qb&;dq64uNBdl9un8>*Y(0apekT0tQ%CTsJ}6Ct_7WmJ@3^ zp{LHF3DY>=-VDnrj3s6Fq2Fgw){xN*!5|%R#K~Wf^xYHsg>dbdH#qsf&pHlUUXud=4PX@}u*L`040OALn%R?_(VW zh2P^J&dEW9QfvhJW>{-P`CmHn8MJy*xGd?{5G|DlELM6-vbb<&&W)XC1|~LD(_$>~vD?xv4CaPV zH{^y;B>-&z8(7ynQ~U6~jZlbsyK{JSKWx1p(ge;%RO#ORPyEj-eVD*p2wXL|gpN6) zfWlQg+!=&9|NP^h6DVcySFW?WUctXVLNxA2A{*!r4=R8cY0+nX-fDCullKdi|tlFy;&G5P4Cw9N87DL z&$GY6knzsfo==`@NVywlw+0kD!n4z!;chKpQW)RARxFZ?zku)t^r6#>koO9OV9Omg zr`e{t;ATXZZE+aypuyO4wm%zZ0gr-o0k*{RjpdsiFu=hMo1$ihXC8Nlp~WJDm48ol zj0GDN>wmFeG=*^i9kaw|imU^UZp)Io5i>X+1;~QU9 z8X(7pwsxGa(5VT;3#PNNlin;HnUxCk6DPOB!Dm75`xo{y+Alk6A=AhptYJI7?4S1| zII0*oCzIuSDF8}}ovnX-_DPD#`J!X@F1!!Y6(mhzCs`4B>bwO!kyo}Bvx@p#<>-T@ z1BEyD^{x`2Qi_~ds}zm?MtP+KJKh=V;R;^q?eo*uy8iw{xAop=&-LTp@!()|&^tUm z&^w2E_i%XJKjH3P%?{$|^?^u7iXc9W>Neq{YVQ`GYltvmQ{z*nZiK-`2g`(=Jd07QA>PbM=7f`m76V{MH zx2@e1-ClF#H*J(2zue$*DtBdEb{M0`qwEP7YtUgAON~QSYU~`P1{MX}!<+x|xhJ15 zva^yBTTw&`+VeL{ZDB2!rVAy?UV!b#p7hnYHUSIHS?uO!>>7OcqGz5=`lrQx=ea>M zxg|r&t>_M&L9a7F3`-?yLKd&y!l;>FV50$b_Bf2_FU}cb zsl7_c3E;@uw-FP6Gwp@r(&TAp%WmX3JD2gYZvvV#V(rd$7L}uOHMZQ@m;^w0Wate* z*doi-0CQm*06`xxk5|q?82WZ3SM^NC}~raaJm23A5tu3Bt0B@`#bu%o z%iev*rZ)I7Z_rG`IWyjeygWYR&6kgp^EO@Z8LXLyyGJtHkt5`o>3hqLga&mD>^!HA6Z?LvyXG1L$030IXu4lQp5ecmnRynYH&%Y96Y7EtPAH@%I z!v;|#t(jr0N}8_%W{UVrV&fJ4_|CB3yA0ify}DZ|#Q4D7;#f99TfB5`tvbg2u$6_l zPi**P(CH2eCz&NEU0FvT+j2<{3Z`GQv!NltRRr^CR6>TW|uDMkgRFe=dtjn*10EV9#5c1c)gDBAPK~gX?f=CSbkav?uqT1=I)tWq?O3_ zA#K2z^%fWo4Nn_C_f}Z?>+WoB*M$97sa4j`!{I{}#8NYDZ-+)aR!O75NhD>z4F-NWV7bj5W|z->nc&3Jxo`5^ zLm4{6y7?R%oZC*FZcGyYkf$FiXPFzyAsEBl-Nt03uq|(+IU5*491zCgB9Svacp9h- zEuV(jK^(}MBd`ac{H(!5!M1>qsbiK4z_0k0zr!a&Xcj}}4m4kwFx}2&AJ3f~z^ObP zgu6WmJg7x;j3EB!e$Dy-kL&=9-$7i3;%yMKr>G=N;KdYx?F8eSf-pc!!{0a%PvI8< zIFMxo6p8`{2WIQKr9Cs@7yu?B=u=O-2?jW(FNZ0PHZwAyf0@2@tOX7Bb+jAmkFlRK z9fDK9nH*|8%Ogug>phv5zoXrJI=Xv1x^GB?rx`7r)#|tu)V985a*;oTCX3JA1Q8Y^ z2A5(G&bwx>Z*!cXJl1fwVO-2<|g8#70@YwwN8lXPZY8v@yFR z6`Ja&-brdT)g_wRmM1S)+;ZiCJ%2O3+y?D3aa=?ezHRvvy##A%Y1q0Iw3SnDQ|rMJ zSVd(7Sl#>=a(feF>k#sbnaMEvnYv(^>u76wr`zLp_|HqK_YU|H0ZF_QN5NSBU&Di-XhY{z^H4};-;S=bZe)X)|(MQJ} z_TT{9M{u)n1S211!j#t9Jkl11fyeGEuJ6#y6_2i#>?gW*8HMup<{Q3c{L zS+u69wm4GmLJO@saK7kU_78YDc8p&=>kWgeajEnty?b25 zC1{Q(M41$E;au$mku>?%()3nm5KPt%s}Fb}G6kCA?Y3Ko8S*8_!DqdpenwRkvM1}$ zKmNIfNMHIOFj8eGhB{G+OB-0Bn1}$Kz~hQ0N@XyZK&Nn%cLGFo_W$370^aL(*9?UdCVW)28Ds3h0Qrsu(`L{ zax&y%p;#Ak!Sr-EIE^%Cyip)}3!yOl{9*cm3&5<@Jwah5d2oh5wA4MpHi+snB=5AY ztn1YprgjH!b!&oU7;4<~j$nPd@{aI_&64(WczX#h20nQK;|R% z*dNi*N!%;ZLUj}g_YCk>;jvb%L==SH&Yf%9`W=SA{1Y@5v%M+K3c8wEG;`+N`OuSL+1k4g zZ`)VXOCI+SCR;^8y%Ro~R`?xKQpgn0oq2I7&lHKvktz5`5=?QQ_59=a4y0*8tbm&n zBYC{I-Sk~!WiDXuMLG^naE5ssOO8A9wy(Lr3`lwZ`m+7=kALIerp}Fxf9Eq!FR&_^ zeUdr9f@sWibT*am+Y^P%=?;ybTYP@@-14r^oF9p&I1WlHO!Loec8Fu*+!oQV_}p68 zHfW+WD_BbyO5ix|0#FmpV|GHB3Cec0Gi5t^7(2P~^BfsvPz@(_q*H`Ue3x#HlzP+Z zF?=;1OkS?YgUwX2{|(w&%3tiKk$-QX7?yd^5Jtp#J%nNj{LCa@q@l7h5ZrA>Rw&^N z+WKOGuBE+pZXoV-1SJDd+=US*FL_r%#y=5V%WrZ4CP#QnqJO_V9@O;H1Nrt$7D-T;&66l|CTNj2913B-r~Fk;4L zUqJjgLE&c;2Nkw1-ZD!OUN|J6S16xj^Q^(va4p}0!x4?fnL*{XYXL-kP;<>2|H4oj zjMzy`U_a8X-o1HyaV24oJlMvT6I@i*w7?%1ZB3Qtl@jcU{Wq_$gG;R9n!oKVUaCgn zFbb5yh6lCVh0p?3Q~z9OBU{#c87XT>G;4c*4K<2}K{By)hlYWQXi1lfCrDZJ!U_)& z6P%!agVup`OF^8GNMG~r!6yr@jIa~?mf2iEswDJWupbAVnzG4Y4_Fn7pOgk%0*x0` zg;*OggOS($zj;L*c6Bf&^RZhMzqqkLcrF&{A2K7B*^bv1SgPSCp5a^G^7c;XYNVo| z4Ulzg(p=6z|M)+U`Q;;n*yUh)%M{W4+$S!yFqxUf&Kk^bj7G)=Wl9pPv7glyv^qD+ zmd$ge-s$|uvCB>ywvC726bWn$FjyV;+OVNf18my448J~DgY{Gln>I+-XDY~7 zUkfp$%1t?_^P#d;*h99Jpx>9;8)%Pt4pA{c9RfFocZph3(e2YJfNIr^zq1p4(w9$_ zBrivf;U7tGjB?2;M6quim^KE4PV~xwAd&&4zn|ArDEjMRc(bim1(|P|gjyXtsA$@( zYdJfQQSJsxpJWWppN?vx?lYhrQY`FI!!U&7E`p{4=6uR`Y(8e1*68u|$5Aten;Di- zxq~;iNCqN4YvcMFX1jaXjb#%QSZED1qeZHH)$6idU8atorIKecMQldOJF8nT?f0J76T}4-ZFc$)<^<6Wx zXp=rCBsF5#i6IBzEU=7+3f)`0_xRf3l9@TeQR^|`EPBOte@&KIH%lt!Y%dFE8C6*N zT@4zAWEdr9xM_wM5(@_k0D@hl4s(vrC#44(1(84=TXO8erqoa^s^N@sZ#Vk~1!tID z``eCSMN`P)&f?B;`e< zHm(iJW=<{Q3vj4)Fj9Fi;jvNyt!vsykXu{RT^U;pBZD%BH``bq)-}Yz=4Q9rid`;o zx+YzHaCRZ)z z#fkHz%xNTp>KZDW%)&dL^hT4I9Ua@~vl)UZgl-p=)o|dq84NQ==M1h47ZzD->r;|JsDmg9uYt^tW=>3r|p67n{}|>#`@zFCvKLd**ss zRUtiSIn_lubtLp37A8aoxxklb@;E*23_o`}FM6H4UXvs#rY6K4JEy&VM<*T3p7`1P zp0iZOY+xP1^7wVJyVI? zO1{X9_e@|NVXEjosCkbIoyi7bP-Mk3^Bz&ZDK~Dimx#ibc-q*50Dz4BAPqM5$jN_Y zGGZ@|0t_ai|H=TYb4WwQC(h#O;WfGdFz7>ZGEv)Q^x3le5P^uq2r$65aUE3~%%Bqm z2noM50g~PJ*S9V0GG5=wo_!S*d(d*$#{4Vvzp$0s6m7w*I{GO~n96z_#u{mPN1Dyy z^r>na(0}02pB1P zNw8$6GaAKMvba9568GH%VVQ)Km&QoYUkpO@6L=4}mkdMmhbHH3SZi8QVw7Ic_R4=D zZ#O1c;;er$P3H$1Sr3Ig8-F&8fH99lOqFANYugYop2r46+&yd&ITnFd6vQW< zj!pit*~5Mu%$Q#YN>)Vtrq2fw`LE{fK2OCMO#y&W1sT93!HPzjZkW1$F#9|HfB*M> z_*~2c63Kv4vXh5B$2bBv+7=en$zVV7+`R=5r$fL1OwH*-=fqeulW_q_FtFyJeAg`Q z(R#qA@jez)6ia!Moa3<9tR|21aR||5NIqc><7KgEnIHm%Ep6f4$>hYz=f4C2`=m1b zk@eA&u2$C76xMwnA5coU1wY*j9($gEjW71FwqSzI0r<}KZpk+DFsuW>@I%nh*7-M<<^$xP0t?YG7(11q|Z_q_UQ z`tx*mNVBdFzTxhM?>tJiQS~2nkaEORTI%icxO@EjaNAY1+ju~n>13W{$g;d z3^troPLYF~!!cqK>yrkf4A&=+0Lq181zq%GJuN}xZ|je9kt8cFH0MNRO$3!i7TR3R zF0|GszL0k~+5?rtD(8)bFU^GsY5#4Zmd0;-nE1lZ>uHuOt{u&N@^e6RQzv z9LKzsS&}p^Vs+A_hvo>2q=NRDd|bl)OZ1!yw(wOFgp)>cj0^XGEbxK_Qk=eYSq{&-dIri#Fl?w&p8T)ldXHF_;Yb&-xO30a;rTJ)1Vm~NN7}weR7C4`PCNHbqUO&}E>En!0c6ECxgET0f_iWrnA}lpbYvaH1*#ibNEGkUz_MVk=K$4{xS;p@ z3u(pZWpAC{aFEqRdLqfll>X?^vkxIC%0A(PsPZQw(q#tR;p5WOHAqn8Lc5VjKNaNB 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Ξ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

3.3. What is the InChI Licence?