1 // $Id$
2 //
3 //  Copyright (C) 2003-2006 Rational Discovery LLC
4 //
5 //   @@ All Rights Reserved @@
6 //  This file is part of the RDKit.
7 //  The contents are covered by the terms of the BSD license
8 //  which is included in the file license.txt, found at the root
9 //  of the RDKit source tree.
10 //
11 #include <RDGeneral/test.h>
12 #include <GraphMol/RDKitBase.h>
13 #include <GraphMol/Subgraphs/Subgraphs.h>
14 #include <GraphMol/SmilesParse/SmilesParse.h>
15 
16 #include <iostream>
17 using namespace std;
18 using namespace RDKit;
19 
testSubgraphs()20 void testSubgraphs() {
21   std::cout << "-----------------------\n Subgraph retrieval" << std::endl;
22   // build: CCC(C)CC
23   RWMol mol;
24   bool updateLabel = true;
25   bool takeOwnership = true;
26   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
27   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
28   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
29   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
30   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
31   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
32   mol.addBond(0, 1, Bond::SINGLE);
33   mol.addBond(1, 2, Bond::SINGLE);
34   mol.addBond(2, 3, Bond::SINGLE);
35   mol.addBond(2, 4, Bond::SINGLE);
36   mol.addBond(3, 5, Bond::SINGLE);
37 
38   PATH_LIST tmp;
39   PATH_LIST::iterator i;
40 
41   int totPs = 0;
42   tmp = findAllSubgraphsOfLengthN(mol, 1);
43   CHECK_INVARIANT(tmp.size() == 5, "");
44   totPs += tmp.size();
45   tmp = findAllSubgraphsOfLengthN(mol, 2);
46   CHECK_INVARIANT(tmp.size() == 5, "");
47   totPs += tmp.size();
48   tmp = findAllSubgraphsOfLengthN(mol, 3);
49   CHECK_INVARIANT(tmp.size() == 5, "");
50   totPs += tmp.size();
51   tmp = findAllSubgraphsOfLengthN(mol, 4);
52   CHECK_INVARIANT(tmp.size() == 3, "");
53   totPs += tmp.size();
54   tmp = findAllSubgraphsOfLengthN(mol, 5);
55   CHECK_INVARIANT(tmp.size() == 1, "");
56   totPs += tmp.size();
57   tmp = findAllSubgraphsOfLengthN(mol, 6);
58   CHECK_INVARIANT(tmp.empty(), "");
59   totPs += tmp.size();
60 
61   // now use the direct range function and check that we get the
62   // same answer
63   INT_PATH_LIST_MAP tmpm;
64   tmpm = findAllSubgraphsOfLengthsMtoN(mol, 1, 6);
65   int newTot, idx;
66   newTot = 0;
67   for (idx = 1; idx <= 6; idx++) {
68     newTot += tmpm[idx].size();
69   }
70   CHECK_INVARIANT(totPs == newTot, "");
71 
72   // add an H and make sure things don't change:
73   mol.addAtom(new Atom(1), updateLabel, takeOwnership);
74   mol.addBond(5, 6, Bond::SINGLE);
75 
76   tmp = findAllSubgraphsOfLengthN(mol, 1);
77 
78   CHECK_INVARIANT(tmp.size() == 5, "");
79   tmp = findAllSubgraphsOfLengthN(mol, 2);
80   CHECK_INVARIANT(tmp.size() == 5, "");
81   tmp = findAllSubgraphsOfLengthN(mol, 3);
82   CHECK_INVARIANT(tmp.size() == 5, "");
83   tmp = findAllSubgraphsOfLengthN(mol, 4);
84   CHECK_INVARIANT(tmp.size() == 3, "");
85   tmp = findAllSubgraphsOfLengthN(mol, 5);
86   CHECK_INVARIANT(tmp.size() == 1, "");
87   tmp = findAllSubgraphsOfLengthN(mol, 6);
88   CHECK_INVARIANT(tmp.empty(), "");
89 
90   std::cout << "Finished" << std::endl;
91 }
92 
testSubgraphs2a()93 void testSubgraphs2a() {
94   // these have been moved here from test2.cpp
95   std::cout << "-----------------------\n testSubgraphs2a" << std::endl;
96   RWMol *mol = SmilesToMol("C1CC2C1N2");
97   CHECK_INVARIANT(mol, "");
98   int nAll = 0;
99   int nUnique = 0;
100   for (unsigned int i = 1; i < 7; ++i) {
101     PATH_LIST tmp;
102     tmp = findAllSubgraphsOfLengthN(*mol, i);
103     nAll += tmp.size();
104     tmp = findUniqueSubgraphsOfLengthN(*mol, i);
105     nUnique += tmp.size();
106   }
107 
108   CHECK_INVARIANT(nAll == 49, "");
109   CHECK_INVARIANT(nUnique == 21, "");
110   delete mol;
111 
112   std::cout << "Finished" << std::endl;
113 }
114 
testSubgraphs2()115 void testSubgraphs2() {
116   // these have been moved here from test2.cpp
117   std::cout << "-----------------------\n testSubgraphs2" << std::endl;
118   RWMol *mol = SmilesToMol("C12C3C4C1C1C2C3N41");
119   CHECK_INVARIANT(mol, "");
120 
121   int nAll = 0;
122   int nUnique = 0;
123   int i;
124   for (i = 1; i < 13; i++) {
125     PATH_LIST tmp;
126     tmp = findAllSubgraphsOfLengthN(*mol, i);
127     nAll += tmp.size();
128     tmp = findUniqueSubgraphsOfLengthN(*mol, i);
129     nUnique += tmp.size();
130   }
131 
132   delete mol;
133   CHECK_INVARIANT(nAll == 2433, "");
134   CHECK_INVARIANT(nUnique == 300, "");
135 
136   mol = SmilesToMol("CCC(O)C(c1ccccc1)CC(C)N(C)C");
137   CHECK_INVARIANT(mol, "");
138 
139   nAll = 0;
140   nUnique = 0;
141   for (i = 1; i < 18; i++) {
142     PATH_LIST tmp;
143     tmp = findAllSubgraphsOfLengthN(*mol, i);
144     nAll += tmp.size();
145     tmp = findUniqueSubgraphsOfLengthN(*mol, i);
146     nUnique += tmp.size();
147   }
148 
149   delete mol;
150   CHECK_INVARIANT(nAll == 1990, "");
151   CHECK_INVARIANT(nUnique == 907, "");
152 
153   std::cout << "Finished" << std::endl;
154 }
155 
dumpVIV(PATH_LIST v)156 void dumpVIV(PATH_LIST v) {
157   PATH_LIST::iterator i;
158   PATH_TYPE::iterator j;
159   for (i = v.begin(); i != v.end(); i++) {
160     for (j = i->begin(); j != i->end(); j++) {
161       std::cout << *j << " ";
162     }
163     std::cout << std::endl;
164   }
165 }
166 
testPaths()167 void testPaths() {
168   std::cout << "-----------------------\n Path retrieval" << std::endl;
169   // build: CCC(C)CC
170   RWMol mol;
171   bool updateLabel = true;
172   bool takeOwnership = true;
173   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
174   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
175   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
176   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
177   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
178   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
179   mol.addBond(0, 1, Bond::SINGLE);
180   mol.addBond(1, 2, Bond::SINGLE);
181   mol.addBond(2, 3, Bond::SINGLE);
182   mol.addBond(2, 4, Bond::SINGLE);
183   mol.addBond(3, 5, Bond::SINGLE);
184 
185   PATH_LIST tmp;
186 
187   //
188   //  Retrieve using bonds
189   //
190   tmp = findAllPathsOfLengthN(mol, 1);
191   CHECK_INVARIANT(tmp.size() == 5, "");
192   tmp = findAllPathsOfLengthN(mol, 2);
193   CHECK_INVARIANT(tmp.size() == 5, "");
194   tmp = findAllPathsOfLengthN(mol, 3);
195   CHECK_INVARIANT(tmp.size() == 4, "");
196   tmp = findAllPathsOfLengthN(mol, 4);
197   CHECK_INVARIANT(tmp.size() == 1, "");
198   tmp = findAllPathsOfLengthN(mol, 5);
199   CHECK_INVARIANT(tmp.empty(), "");
200   tmp = findAllPathsOfLengthN(mol, 6);
201   CHECK_INVARIANT(tmp.empty(), "");
202 
203   //
204   //  Retrieve using atoms, which gives the results shifted by
205   //  one (it takes two atoms to make one bond)
206   //
207   tmp = findAllPathsOfLengthN(mol, 1, false);
208   CHECK_INVARIANT(tmp.size() == 6, "");
209   tmp = findAllPathsOfLengthN(mol, 2, false);
210   CHECK_INVARIANT(tmp.size() == 5, "");
211   tmp = findAllPathsOfLengthN(mol, 3, false);
212   CHECK_INVARIANT(tmp.size() == 5, "");
213   tmp = findAllPathsOfLengthN(mol, 4, false);
214   CHECK_INVARIANT(tmp.size() == 4, "");
215   tmp = findAllPathsOfLengthN(mol, 5, false);
216   CHECK_INVARIANT(tmp.size() == 1, "");
217   tmp = findAllPathsOfLengthN(mol, 6, false);
218   CHECK_INVARIANT(tmp.empty(), "");
219 
220   //
221   //  try m->n
222   //
223   INT_PATH_LIST_MAP pths;
224   pths = findAllPathsOfLengthsMtoN(mol, 1, 6);
225   CHECK_INVARIANT(pths[1].size() == 5, "");
226   CHECK_INVARIANT(pths[2].size() == 5, "");
227   CHECK_INVARIANT(pths[3].size() == 4, "");
228   CHECK_INVARIANT(pths[4].size() == 1, "");
229   CHECK_INVARIANT(pths[5].empty(), "");
230   CHECK_INVARIANT(pths[6].empty(), "");
231 
232   pths = findAllPathsOfLengthsMtoN(mol, 1, 6, false);
233   CHECK_INVARIANT(pths[1].size() == 6, "");
234   CHECK_INVARIANT(pths[2].size() == 5, "");
235   CHECK_INVARIANT(pths[3].size() == 5, "");
236   CHECK_INVARIANT(pths[4].size() == 4, "");
237   CHECK_INVARIANT(pths[5].size() == 1, "");
238   CHECK_INVARIANT(pths[6].empty(), "");
239 
240   //
241   //  add an atom, close the ring and re-check a couple indices:
242   //   (leaves us with CC1CCCCC1)
243   //
244   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
245   mol.addBond(5, 6, Bond::SINGLE);
246   mol.addBond(0, 6, Bond::SINGLE);
247   tmp = findAllPathsOfLengthN(mol, 4);
248   CHECK_INVARIANT(tmp.size() == 8, "");
249   tmp = findAllPathsOfLengthN(mol, 5, false);
250   CHECK_INVARIANT(tmp.size() == 8, "");
251 
252   std::cout << "Finished" << std::endl;
253 }
254 
testPaths2()255 void testPaths2() {
256   std::cout << "-----------------------\n Path retrieval2" << std::endl;
257   // build: CCC(C)CC
258   RWMol mol;
259   bool updateLabel = true;
260   bool takeOwnership = true;
261   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
262   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
263   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
264   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
265   mol.addBond(0, 1, Bond::SINGLE);
266   mol.addBond(1, 2, Bond::SINGLE);
267   mol.addBond(2, 3, Bond::SINGLE);
268   mol.addBond(2, 0, Bond::SINGLE);
269 
270   //
271   //  Retrieve using bonds
272   //
273   PATH_LIST tmp = findAllPathsOfLengthN(mol, 3);
274   // std::cout << "\n3:" << std::endl;
275   // dumpVIV(tmp);
276   CHECK_INVARIANT(tmp.size() == 3, "");
277 
278   std::cout << "Finished" << std::endl;
279 }
280 
testUniqueSubgraphs()281 void testUniqueSubgraphs() {
282   std::cout << "-----------------------\n Unique Subgraph retrieval"
283             << std::endl;
284   // build: CCC(C)CC
285   RWMol mol;
286   bool updateLabel = true;
287   bool takeOwnership = true;
288   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
289   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
290   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
291   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
292   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
293   mol.addAtom(new Atom(6), updateLabel, takeOwnership);
294   mol.addBond(0, 1, Bond::SINGLE);
295   mol.addBond(1, 2, Bond::SINGLE);
296   mol.addBond(2, 3, Bond::SINGLE);
297   mol.addBond(2, 4, Bond::SINGLE);
298   mol.addBond(3, 5, Bond::SINGLE);
299 
300   PATH_LIST tmp;
301   PATH_LIST::iterator i;
302 
303   tmp = findAllSubgraphsOfLengthN(mol, 1);
304   CHECK_INVARIANT(tmp.size() == 5, "");
305 
306   tmp = findAllSubgraphsOfLengthN(mol, 2);
307   CHECK_INVARIANT(tmp.size() == 5, "");
308   tmp = findUniqueSubgraphsOfLengthN(mol, 2);
309   CHECK_INVARIANT(tmp.size() == 1, "");
310 
311   tmp = findAllSubgraphsOfLengthN(mol, 3);
312   CHECK_INVARIANT(tmp.size() == 5, "");
313   tmp = findUniqueSubgraphsOfLengthN(mol, 3);
314   CHECK_INVARIANT(tmp.size() == 2, "");
315 
316   tmp = findAllSubgraphsOfLengthN(mol, 4);
317   CHECK_INVARIANT(tmp.size() == 3, "");
318   tmp = findUniqueSubgraphsOfLengthN(mol, 4);
319   CHECK_INVARIANT(tmp.size() == 2, "");
320 
321   tmp = findAllSubgraphsOfLengthN(mol, 5);
322   CHECK_INVARIANT(tmp.size() == 1, "");
323   tmp = findUniqueSubgraphsOfLengthN(mol, 5);
324   CHECK_INVARIANT(tmp.size() == 1, "");
325 
326   tmp = findAllSubgraphsOfLengthN(mol, 6);
327   CHECK_INVARIANT(tmp.empty(), "");
328   tmp = findUniqueSubgraphsOfLengthN(mol, 6);
329   CHECK_INVARIANT(tmp.empty(), "");
330 
331   // add an H and make sure things don't change:
332   mol.addAtom(new Atom(1), updateLabel, takeOwnership);
333   mol.addBond(5, 6, Bond::SINGLE);
334 
335   tmp = findAllSubgraphsOfLengthN(mol, 2);
336   CHECK_INVARIANT(tmp.size() == 5, "");
337   tmp = findUniqueSubgraphsOfLengthN(mol, 2);
338   CHECK_INVARIANT(tmp.size() == 1, "");
339 
340   tmp = findAllSubgraphsOfLengthN(mol, 3);
341   CHECK_INVARIANT(tmp.size() == 5, "");
342   tmp = findUniqueSubgraphsOfLengthN(mol, 3);
343   CHECK_INVARIANT(tmp.size() == 2, "");
344 
345   tmp = findAllSubgraphsOfLengthN(mol, 4);
346   CHECK_INVARIANT(tmp.size() == 3, "");
347   tmp = findUniqueSubgraphsOfLengthN(mol, 4);
348   CHECK_INVARIANT(tmp.size() == 2, "");
349 
350   tmp = findAllSubgraphsOfLengthN(mol, 5);
351   CHECK_INVARIANT(tmp.size() == 1, "");
352   tmp = findUniqueSubgraphsOfLengthN(mol, 5);
353   CHECK_INVARIANT(tmp.size() == 1, "");
354 
355   tmp = findAllSubgraphsOfLengthN(mol, 6);
356   CHECK_INVARIANT(tmp.empty(), "");
357   tmp = findUniqueSubgraphsOfLengthN(mol, 6);
358   CHECK_INVARIANT(tmp.empty(), "");
359 
360   std::cout << "Finished" << std::endl;
361 }
362 
testUniqueSubgraphs2()363 void testUniqueSubgraphs2() {
364   // moved here from test2.cpp
365   std::cout << "-----------------------\n testUniqueSubgraphs2" << std::endl;
366   RWMol *mol = SmilesToMol("O=C(O)CCCC=CC(C1C(O)CC(O)C1(C=CC(O)CCCCC))");
367   CHECK_INVARIANT(mol, "");
368 
369   int nAll = 0;
370   int nUnique = 0;
371   for (int i = 1; i < 26; i++) {
372     PATH_LIST tmp;
373     tmp = findAllSubgraphsOfLengthN(*mol, i);
374     // std::cout << i << "\t" << tmp.size();
375     nAll += tmp.size();
376     tmp = findUniqueSubgraphsOfLengthN(*mol, i);
377     // std::cout << "\t" << tmp.size() << std::endl;;
378     nUnique += tmp.size();
379   }
380 
381   CHECK_INVARIANT(nAll == 6435, "");
382   CHECK_INVARIANT(nUnique == 5618, "");
383   delete mol;
384   std::cout << "Finished" << std::endl;
385 }
386 
testLeak()387 void testLeak() {
388   // moved here from test2.cpp
389   std::cout << "-----------------------\n testing for a core leak (Issue 42) "
390             << std::endl;
391   RWMol *mol = SmilesToMol("O=C(O)CCCC=CC(C1C(O)CC(O)C1(C=CC(O)CCCCC))");
392   CHECK_INVARIANT(mol, "");
393 
394   for (int rep = 0; rep < 100; rep++) {
395     int nAll = 0;
396     int nUnique = 0;
397     for (int i = 1; i < 26; i++) {
398       PATH_LIST tmp;
399       tmp = findAllSubgraphsOfLengthN(*mol, i);
400       // std::cout << i << "\t" << tmp.size();
401       nAll += tmp.size();
402       tmp = findUniqueSubgraphsOfLengthN(*mol, i);
403       // std::cout << "\t" << tmp.size() << std::endl;;
404       nUnique += tmp.size();
405     }
406     CHECK_INVARIANT(nAll == 6435, "");
407     CHECK_INVARIANT(nUnique == 5618, "");
408   }
409   delete mol;
410   std::cout << "Finished" << std::endl;
411 }
412 
testRootedSubgraphs()413 void testRootedSubgraphs() {
414   std::cout << "-----------------------\n testRootedSubgraphs" << std::endl;
415   {
416     RWMol *mol = SmilesToMol("CC1CC1");
417     TEST_ASSERT(mol);
418 
419     PATH_LIST tmp;
420     tmp = findAllSubgraphsOfLengthN(*mol, 1, false, 0);
421     TEST_ASSERT(tmp.size() == 1);
422     tmp = findAllSubgraphsOfLengthN(*mol, 2, false, 0);
423     TEST_ASSERT(tmp.size() == 2);
424     tmp = findAllSubgraphsOfLengthN(*mol, 3, false, 0);
425     TEST_ASSERT(tmp.size() == 3);
426     tmp = findUniqueSubgraphsOfLengthN(*mol, 2, false, false, 0);
427     TEST_ASSERT(tmp.size() == 1);
428     tmp = findUniqueSubgraphsOfLengthN(*mol, 3, false, false, 0);
429     TEST_ASSERT(tmp.size() == 2);
430 
431     INT_PATH_LIST_MAP tmpm;
432     tmpm = findAllSubgraphsOfLengthsMtoN(*mol, 1, 3, false, 0);
433     TEST_ASSERT(tmpm[1].size() == 1);
434     TEST_ASSERT(tmpm[2].size() == 2);
435     TEST_ASSERT(tmpm[3].size() == 3);
436 
437     // edge case:
438     tmp = findAllSubgraphsOfLengthN(*mol, 1, false, 10);
439     TEST_ASSERT(tmp.empty());
440 
441     delete mol;
442   }
443 
444   {  // tests for sf.net issue 250
445     RWMol *mol = SmilesToMol("C1CC1C");
446     TEST_ASSERT(mol);
447 
448     PATH_LIST tmp;
449     tmp = findAllSubgraphsOfLengthN(*mol, 1, false, 3);
450     TEST_ASSERT(tmp.size() == 1);
451     tmp = findAllSubgraphsOfLengthN(*mol, 2, false, 3);
452     TEST_ASSERT(tmp.size() == 2);
453     tmp = findAllSubgraphsOfLengthN(*mol, 3, false, 3);
454     TEST_ASSERT(tmp.size() == 3);
455     tmp = findUniqueSubgraphsOfLengthN(*mol, 2, false, false, 3);
456     TEST_ASSERT(tmp.size() == 1);
457     tmp = findUniqueSubgraphsOfLengthN(*mol, 3, false, false, 3);
458     TEST_ASSERT(tmp.size() == 2);
459 
460     INT_PATH_LIST_MAP tmpm;
461     tmpm = findAllSubgraphsOfLengthsMtoN(*mol, 1, 3, false, 3);
462     TEST_ASSERT(tmpm[1].size() == 1);
463     TEST_ASSERT(tmpm[2].size() == 2);
464     TEST_ASSERT(tmpm[3].size() == 3);
465 
466     // edge case:
467     tmp = findAllSubgraphsOfLengthN(*mol, 1, false, 10);
468     TEST_ASSERT(tmp.empty());
469 
470     delete mol;
471   }
472 
473   {
474     RWMol *mol = SmilesToMol("CC1CC1");
475     TEST_ASSERT(mol);
476 
477     INT_PATH_LIST_MAP tmpm;
478     tmpm = findAllSubgraphsOfLengthsMtoN(*mol, 1, 2, false, 0);
479     TEST_ASSERT(tmpm[1].size() == 1);
480     TEST_ASSERT(tmpm[2].size() == 2);
481     TEST_ASSERT(tmpm[3].empty());
482     tmpm = findAllSubgraphsOfLengthsMtoN(*mol, 1, 3, false, 0);
483     TEST_ASSERT(tmpm[1].size() == 1);
484     TEST_ASSERT(tmpm[2].size() == 2);
485     TEST_ASSERT(tmpm[3].size() == 3);
486     delete mol;
487   }
488   {  // tests for sf.net issue 250
489     RWMol *mol = SmilesToMol("C1CC1C");
490     TEST_ASSERT(mol);
491 
492     INT_PATH_LIST_MAP tmpm;
493     tmpm = findAllSubgraphsOfLengthsMtoN(*mol, 1, 2, false, 3);
494     TEST_ASSERT(tmpm[1].size() == 1);
495     TEST_ASSERT(tmpm[2].size() == 2);
496     TEST_ASSERT(tmpm[3].empty());
497     tmpm = findAllSubgraphsOfLengthsMtoN(*mol, 1, 3, false, 3);
498     TEST_ASSERT(tmpm[1].size() == 1);
499     TEST_ASSERT(tmpm[2].size() == 2);
500     TEST_ASSERT(tmpm[3].size() == 3);
501     delete mol;
502   }
503 
504   std::cout << "Finished" << std::endl;
505 }
506 
testRootedPaths()507 void testRootedPaths() {
508   std::cout << "-----------------------\n testRootedPaths" << std::endl;
509   {
510     RWMol *mol = SmilesToMol("CC1CC1");
511     TEST_ASSERT(mol);
512 
513     PATH_LIST tmp;
514 
515     // bond paths:
516     tmp = findAllPathsOfLengthN(*mol, 1, true, false, 0);
517     TEST_ASSERT(tmp.size() == 1);
518     tmp = findAllPathsOfLengthN(*mol, 2, true, false, 0);
519     TEST_ASSERT(tmp.size() == 2);
520     tmp = findAllPathsOfLengthN(*mol, 3, true, false, 0);
521     TEST_ASSERT(tmp.size() == 2);
522 
523     // edge case:
524     tmp = findAllPathsOfLengthN(*mol, 1, true, false, 10);
525     TEST_ASSERT(tmp.empty());
526 
527     // atom paths:
528     tmp = findAllPathsOfLengthN(*mol, 1, false, false, 0);
529     TEST_ASSERT(tmp.size() == 1);
530     tmp = findAllPathsOfLengthN(*mol, 2, false, false, 0);
531     TEST_ASSERT(tmp.size() == 1);
532     tmp = findAllPathsOfLengthN(*mol, 3, false, false, 0);
533     TEST_ASSERT(tmp.size() == 2);
534     tmp = findAllPathsOfLengthN(*mol, 4, false, false, 0);
535     TEST_ASSERT(tmp.size() == 2);
536 
537     delete mol;
538   }
539 
540   {  // tests for sf.net issue 250
541     RWMol *mol = SmilesToMol("C1CC1C");
542     TEST_ASSERT(mol);
543 
544     PATH_LIST tmp;
545 
546     // bond paths:
547     tmp = findAllPathsOfLengthN(*mol, 1, true, false, 3);
548     TEST_ASSERT(tmp.size() == 1);
549     tmp = findAllPathsOfLengthN(*mol, 2, true, false, 3);
550     TEST_ASSERT(tmp.size() == 2);
551     tmp = findAllPathsOfLengthN(*mol, 3, true, false, 3);
552     TEST_ASSERT(tmp.size() == 2);
553 
554     // edge case:
555     tmp = findAllPathsOfLengthN(*mol, 1, true, false, 10);
556     TEST_ASSERT(tmp.empty());
557 
558     // atom paths:
559     tmp = findAllPathsOfLengthN(*mol, 1, false, false, 3);
560     TEST_ASSERT(tmp.size() == 1);
561     tmp = findAllPathsOfLengthN(*mol, 2, false, false, 3);
562     TEST_ASSERT(tmp.size() == 1);
563     tmp = findAllPathsOfLengthN(*mol, 3, false, false, 3);
564     TEST_ASSERT(tmp.size() == 2);
565     tmp = findAllPathsOfLengthN(*mol, 4, false, false, 3);
566     TEST_ASSERT(tmp.size() == 2);
567 
568     delete mol;
569   }
570 
571   {
572     RWMol *mol = SmilesToMol("CC1CC1");
573     TEST_ASSERT(mol);
574 
575     INT_PATH_LIST_MAP tmpm;
576     tmpm = findAllPathsOfLengthsMtoN(*mol, 1, 2, false, false, 0);
577     TEST_ASSERT(tmpm[1].size() == 1);
578     TEST_ASSERT(tmpm[2].size() == 1);
579     TEST_ASSERT(tmpm[3].empty());
580     tmpm = findAllPathsOfLengthsMtoN(*mol, 1, 3, false, false, 0);
581     TEST_ASSERT(tmpm[1].size() == 1);
582     TEST_ASSERT(tmpm[2].size() == 1);
583     TEST_ASSERT(tmpm[3].size() == 2);
584     delete mol;
585   }
586   {  // tests for sf.net issue 250
587     RWMol *mol = SmilesToMol("C1CC1C");
588     TEST_ASSERT(mol);
589 
590     INT_PATH_LIST_MAP tmpm;
591     tmpm = findAllPathsOfLengthsMtoN(*mol, 1, 2, false, false, 3);
592     TEST_ASSERT(tmpm[1].size() == 1);
593     TEST_ASSERT(tmpm[2].size() == 1);
594     TEST_ASSERT(tmpm[3].empty());
595     tmpm = findAllPathsOfLengthsMtoN(*mol, 1, 3, false, false, 3);
596     TEST_ASSERT(tmpm[1].size() == 1);
597     TEST_ASSERT(tmpm[2].size() == 1);
598     TEST_ASSERT(tmpm[3].size() == 2);
599     delete mol;
600   }
601 
602   std::cout << "Finished" << std::endl;
603 }
604 
605 // -------------------------------------------------------------------
main()606 int main() {
607 #if 1
608   testSubgraphs();
609   testSubgraphs2a();
610   testSubgraphs2();
611   testPaths();
612   testPaths2();
613   testUniqueSubgraphs();
614   testUniqueSubgraphs2();
615   testRootedSubgraphs();
616   testRootedPaths();
617 #endif
618   // testLeak();
619   return 0;
620 }
621