synkit 1.6.5__py3-none-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (636) hide show
  1. synkit/CRN/Benchmark/__init__.py +53 -0
  2. synkit/CRN/Benchmark/crosschecks.py +13 -0
  3. synkit/CRN/Benchmark/kegg.py +12 -0
  4. synkit/CRN/Benchmark/networks.py +13 -0
  5. synkit/CRN/Benchmark/scaling.py +13 -0
  6. synkit/CRN/Benchmark/validate.py +13 -0
  7. synkit/CRN/Construct/__init__.py +16 -0
  8. synkit/CRN/Construct/abstract.py +668 -0
  9. synkit/CRN/Construct/arity.py +36 -0
  10. synkit/CRN/Construct/builder.py +619 -0
  11. synkit/CRN/Construct/derivation.py +63 -0
  12. synkit/CRN/Construct/flattener.py +100 -0
  13. synkit/CRN/Construct/keys.py +14 -0
  14. synkit/CRN/Construct/mixtures.py +117 -0
  15. synkit/CRN/Construct/rdkit_worker.py +69 -0
  16. synkit/CRN/Construct/smiles.py +99 -0
  17. synkit/CRN/Construct/state.py +31 -0
  18. synkit/CRN/Construct/strategy.py +75 -0
  19. synkit/CRN/Construct/worker.py +42 -0
  20. synkit/CRN/IO/__init__.py +36 -0
  21. synkit/CRN/IO/sbml.py +925 -0
  22. synkit/CRN/Pathway/__init__.py +72 -0
  23. synkit/CRN/Pathway/_adapter.py +333 -0
  24. synkit/CRN/Pathway/pathfinder.py +500 -0
  25. synkit/CRN/Pathway/reachability.py +796 -0
  26. synkit/CRN/Pathway/realizability.py +1322 -0
  27. synkit/CRN/Petrinet/__init__.py +93 -0
  28. synkit/CRN/Petrinet/analyzer.py +486 -0
  29. synkit/CRN/Petrinet/minimal_semiflows.py +436 -0
  30. synkit/CRN/Petrinet/net.py +1041 -0
  31. synkit/CRN/Petrinet/persistence.py +97 -0
  32. synkit/CRN/Petrinet/semiflows.py +483 -0
  33. synkit/CRN/Petrinet/siphon_search.py +402 -0
  34. synkit/CRN/Petrinet/structure.py +286 -0
  35. synkit/CRN/Props/__init__.py +130 -0
  36. synkit/CRN/Props/_rank.py +29 -0
  37. synkit/CRN/Props/deficiency.py +953 -0
  38. synkit/CRN/Props/dynamics.py +832 -0
  39. synkit/CRN/Props/helper.py +151 -0
  40. synkit/CRN/Props/stoich.py +751 -0
  41. synkit/CRN/Props/thermo.py +584 -0
  42. synkit/CRN/Query/__init__.py +66 -0
  43. synkit/CRN/Query/cache.py +41 -0
  44. synkit/CRN/Query/kegg_api.py +99 -0
  45. synkit/CRN/Query/kegg_extract.py +714 -0
  46. synkit/CRN/Query/kegg_impute.py +707 -0
  47. synkit/CRN/Query/kegg_parse.py +480 -0
  48. synkit/CRN/Query/to_syncrn.py +290 -0
  49. synkit/CRN/README.md +234 -0
  50. synkit/CRN/Structure/__init__.py +12 -0
  51. synkit/CRN/Structure/_graph_io.py +713 -0
  52. synkit/CRN/Structure/_matrices.py +88 -0
  53. synkit/CRN/Structure/_parse.py +544 -0
  54. synkit/CRN/Structure/reaction.py +237 -0
  55. synkit/CRN/Structure/rule.py +55 -0
  56. synkit/CRN/Structure/species.py +46 -0
  57. synkit/CRN/Structure/syncrn.py +929 -0
  58. synkit/CRN/Symmetry/__init__.py +20 -0
  59. synkit/CRN/Symmetry/_common.py +1059 -0
  60. synkit/CRN/Symmetry/_ir.py +940 -0
  61. synkit/CRN/Symmetry/automorphism.py +472 -0
  62. synkit/CRN/Symmetry/canon.py +441 -0
  63. synkit/CRN/Symmetry/isomorphism.py +412 -0
  64. synkit/CRN/Symmetry/symmetry.py +61 -0
  65. synkit/CRN/Symmetry/wl_canon.py +967 -0
  66. synkit/CRN/Visualize/__init__.py +11 -0
  67. synkit/CRN/Visualize/labels.py +113 -0
  68. synkit/CRN/Visualize/layout.py +708 -0
  69. synkit/CRN/Visualize/palette.py +292 -0
  70. synkit/CRN/Visualize/validation.py +122 -0
  71. synkit/CRN/Visualize/vis.py +1152 -0
  72. synkit/CRN/__init__.py +233 -0
  73. synkit/CRN/_build.py +50 -0
  74. synkit/CRN/_native_build.py +175 -0
  75. synkit/CRN/analysis.py +629 -0
  76. synkit/CRN/backend.py +74 -0
  77. synkit/CRN/cpp/CMakeLists.txt +58 -0
  78. synkit/CRN/cpp/algebra.cpp +46 -0
  79. synkit/CRN/cpp/closure.cpp +29 -0
  80. synkit/CRN/cpp/exact.h +55 -0
  81. synkit/CRN/cpp/pathway.cpp +46 -0
  82. synkit/CRN/cpp/semiflows.cpp +209 -0
  83. synkit/CRN/cpp/structural.cpp +240 -0
  84. synkit/CRN/cpp/symmetry.cpp +45 -0
  85. synkit/CRN/cpp/write_manifest.cmake +28 -0
  86. synkit/CRN/kinds.py +137 -0
  87. synkit/CRN/lib/synkit_crn.dll +0 -0
  88. synkit/CRN/lib/synkit_crn.json +33 -0
  89. synkit/CRN/native.py +388 -0
  90. synkit/CRN/native_analysis.py +459 -0
  91. synkit/Chem/Cluster/__init__.py +0 -0
  92. synkit/Chem/Cluster/butina.py +140 -0
  93. synkit/Chem/Fingerprint/__init__.py +0 -0
  94. synkit/Chem/Fingerprint/fp_calculator.py +155 -0
  95. synkit/Chem/Fingerprint/smiles_featurizer.py +258 -0
  96. synkit/Chem/Fingerprint/transformation_fp.py +139 -0
  97. synkit/Chem/Mapper/README.rst +43 -0
  98. synkit/Chem/Mapper/__init__.py +255 -0
  99. synkit/Chem/Mapper/_compat.py +130 -0
  100. synkit/Chem/Mapper/adapters/__init__.py +1 -0
  101. synkit/Chem/Mapper/adapters/prediction.py +126 -0
  102. synkit/Chem/Mapper/adapters/template.py +412 -0
  103. synkit/Chem/Mapper/chem/__init__.py +52 -0
  104. synkit/Chem/Mapper/chem/aam.py +673 -0
  105. synkit/Chem/Mapper/chem/blind.py +160 -0
  106. synkit/Chem/Mapper/chem/its.py +309 -0
  107. synkit/Chem/Mapper/chem/smiles.py +564 -0
  108. synkit/Chem/Mapper/graph/__init__.py +66 -0
  109. synkit/Chem/Mapper/graph/automorphism.py +395 -0
  110. synkit/Chem/Mapper/graph/blockcut.py +98 -0
  111. synkit/Chem/Mapper/graph/labeled_graph.py +104 -0
  112. synkit/Chem/Mapper/graph/refine.py +176 -0
  113. synkit/Chem/Mapper/graph/synkit_adapter.py +110 -0
  114. synkit/Chem/Mapper/io/__init__.py +13 -0
  115. synkit/Chem/Mapper/io/idxmapstr.py +82 -0
  116. synkit/Chem/Mapper/mapper.py +685 -0
  117. synkit/Chem/Mapper/reaction_search.py +554 -0
  118. synkit/Chem/Mapper/reporting/__init__.py +1 -0
  119. synkit/Chem/Mapper/reporting/alternatives.py +451 -0
  120. synkit/Chem/Mapper/reporting/analysis.py +681 -0
  121. synkit/Chem/Mapper/reporting/native_analysis.py +485 -0
  122. synkit/Chem/Mapper/reporting/spectrum.py +642 -0
  123. synkit/Chem/Mapper/solvers/__init__.py +1 -0
  124. synkit/Chem/Mapper/solvers/exact/__init__.py +141 -0
  125. synkit/Chem/Mapper/solvers/exact/assignment/__init__.py +1 -0
  126. synkit/Chem/Mapper/solvers/exact/assignment/assignment_certificate.py +113 -0
  127. synkit/Chem/Mapper/solvers/exact/assignment/assignment_domains.py +162 -0
  128. synkit/Chem/Mapper/solvers/exact/assignment/assignment_verification.py +58 -0
  129. synkit/Chem/Mapper/solvers/exact/assignment/incremental_assignment.py +247 -0
  130. synkit/Chem/Mapper/solvers/exact/certificate.py +128 -0
  131. synkit/Chem/Mapper/solvers/exact/core.py +183 -0
  132. synkit/Chem/Mapper/solvers/exact/distance_search/__init__.py +1 -0
  133. synkit/Chem/Mapper/solvers/exact/distance_search/bounds.py +319 -0
  134. synkit/Chem/Mapper/solvers/exact/distance_search/exhaustive.py +179 -0
  135. synkit/Chem/Mapper/solvers/exact/distance_search/inputs.py +283 -0
  136. synkit/Chem/Mapper/solvers/exact/distance_search/records.py +242 -0
  137. synkit/Chem/Mapper/solvers/exact/distance_search/search.py +1025 -0
  138. synkit/Chem/Mapper/solvers/exact/distance_search/verify.py +378 -0
  139. synkit/Chem/Mapper/solvers/exact/edit_support.py +375 -0
  140. synkit/Chem/Mapper/solvers/exact/hybrid.py +224 -0
  141. synkit/Chem/Mapper/solvers/exact/hydrogen.py +264 -0
  142. synkit/Chem/Mapper/solvers/exact/kernel_solvers/__init__.py +1 -0
  143. synkit/Chem/Mapper/solvers/exact/kernel_solvers/branching.py +499 -0
  144. synkit/Chem/Mapper/solvers/exact/kernel_solvers/enumerate.py +1050 -0
  145. synkit/Chem/Mapper/solvers/exact/kernel_solvers/enumeration_result.py +30 -0
  146. synkit/Chem/Mapper/solvers/exact/kernel_solvers/kernel.py +256 -0
  147. synkit/Chem/Mapper/solvers/exact/kernel_solvers/milp.py +194 -0
  148. synkit/Chem/Mapper/solvers/exact/native/__init__.py +1 -0
  149. synkit/Chem/Mapper/solvers/exact/native/build.py +154 -0
  150. synkit/Chem/Mapper/solvers/exact/native/candidates.py +593 -0
  151. synkit/Chem/Mapper/solvers/exact/native/canonical.py +396 -0
  152. synkit/Chem/Mapper/solvers/exact/native/disk_frontier.py +415 -0
  153. synkit/Chem/Mapper/solvers/exact/native/frontier.py +390 -0
  154. synkit/Chem/Mapper/solvers/exact/native/hydrogen_quotient.py +213 -0
  155. synkit/Chem/Mapper/solvers/exact/native/its.py +528 -0
  156. synkit/Chem/Mapper/solvers/exact/native/native_distance.cpp +2803 -0
  157. synkit/Chem/Mapper/solvers/exact/native/orbit_aggregation.py +328 -0
  158. synkit/Chem/Mapper/solvers/exact/native/parallel.py +205 -0
  159. synkit/Chem/Mapper/solvers/exact/native/pmcd.py +203 -0
  160. synkit/Chem/Mapper/solvers/exact/native/runtime.py +40 -0
  161. synkit/Chem/Mapper/solvers/exact/native/search.py +294 -0
  162. synkit/Chem/Mapper/solvers/exact/native/separator.py +224 -0
  163. synkit/Chem/Mapper/solvers/exact/native_build.py +12 -0
  164. synkit/Chem/Mapper/solvers/exact/pabs/__init__.py +1 -0
  165. synkit/Chem/Mapper/solvers/exact/pabs/cost_lattice.py +43 -0
  166. synkit/Chem/Mapper/solvers/exact/pabs/factor_spectrum.py +110 -0
  167. synkit/Chem/Mapper/solvers/exact/pabs/multi_shell.py +368 -0
  168. synkit/Chem/Mapper/solvers/exact/pabs/propagation.py +679 -0
  169. synkit/Chem/Mapper/solvers/exact/pabs/propagation_bounds.py +436 -0
  170. synkit/Chem/Mapper/solvers/exact/pabs/propagation_limits.py +13 -0
  171. synkit/Chem/Mapper/solvers/exact/pabs/propagation_search.py +856 -0
  172. synkit/Chem/Mapper/solvers/exact/pabs/propagation_symmetry.py +66 -0
  173. synkit/Chem/Mapper/solvers/exact/pabs/residual_typed_bonds.py +136 -0
  174. synkit/Chem/Mapper/solvers/exact/pabs/reward_frontier.py +201 -0
  175. synkit/Chem/Mapper/solvers/exact/pabs/separator_bound.py +258 -0
  176. synkit/Chem/Mapper/solvers/exact/pabs/separator_spectrum.py +308 -0
  177. synkit/Chem/Mapper/solvers/exact/pabs/sparse_reward_bound.py +207 -0
  178. synkit/Chem/Mapper/solvers/exact/pabs/suffix_spectrum.py +299 -0
  179. synkit/Chem/Mapper/solvers/exact/search.py +55 -0
  180. synkit/Chem/Mapper/solvers/exact/seeds/__init__.py +1 -0
  181. synkit/Chem/Mapper/solvers/exact/seeds/seed.py +104 -0
  182. synkit/Chem/Mapper/solvers/exact/seeds/seed_fragments.py +148 -0
  183. synkit/Chem/Mapper/solvers/exact/seeds/seed_relaxation.py +181 -0
  184. synkit/Chem/Mapper/solvers/exact/symmetry.py +223 -0
  185. synkit/Chem/Mapper/solvers/native/__init__.py +4 -0
  186. synkit/Chem/Mapper/solvers/native/assignment.py +99 -0
  187. synkit/Chem/Mapper/solvers/native/astar.py +22 -0
  188. synkit/Chem/Mapper/solvers/native/build.py +385 -0
  189. synkit/Chem/Mapper/solvers/native/classification.py +641 -0
  190. synkit/Chem/Mapper/solvers/native/core.py +378 -0
  191. synkit/Chem/Mapper/solvers/native/cpp/CMakeLists.txt +120 -0
  192. synkit/Chem/Mapper/solvers/native/cpp/examples/map_reaction.cpp +29 -0
  193. synkit/Chem/Mapper/solvers/native/cpp/examples/slap_graph.cpp +63 -0
  194. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/assignment/assignment.h +18 -0
  195. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/astar/astar.h +18 -0
  196. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/astar/bound.h +33 -0
  197. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/core/pmcd_witness.h +16 -0
  198. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/core/runtime.h +130 -0
  199. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/hydrogen/hydrogen.h +73 -0
  200. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/mapper.h +175 -0
  201. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/mces/mces.h +9 -0
  202. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/pabs/seed.h +34 -0
  203. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/reaction/reaction.h +30 -0
  204. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/sepdp/sepdp.h +21 -0
  205. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/slap.h +72 -0
  206. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/solvers/solvers.h +16 -0
  207. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/symmetry/classification.h +140 -0
  208. synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/symmetry/cpabs.h +33 -0
  209. synkit/Chem/Mapper/solvers/native/cpp/src/assignment/abb.cpp +302 -0
  210. synkit/Chem/Mapper/solvers/native/cpp/src/astar/CMakeLists.txt +12 -0
  211. synkit/Chem/Mapper/solvers/native/cpp/src/astar/README.md +47 -0
  212. synkit/Chem/Mapper/solvers/native/cpp/src/astar/astar.cpp +228 -0
  213. synkit/Chem/Mapper/solvers/native/cpp/src/astar/astar_graph.cpp +37 -0
  214. synkit/Chem/Mapper/solvers/native/cpp/src/astar/bound.cpp +212 -0
  215. synkit/Chem/Mapper/solvers/native/cpp/src/core/dispatch.cpp +272 -0
  216. synkit/Chem/Mapper/solvers/native/cpp/src/core/pmcd_witness.cpp +36 -0
  217. synkit/Chem/Mapper/solvers/native/cpp/src/hydrogen/hydrogen.cpp +380 -0
  218. synkit/Chem/Mapper/solvers/native/cpp/src/mces/README.md +57 -0
  219. synkit/Chem/Mapper/solvers/native/cpp/src/mces/mces.cpp +287 -0
  220. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/bridge.cpp +334 -0
  221. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/chemical_floor.inc +181 -0
  222. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/endpoint_symmetry.inc +104 -0
  223. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/exact_helpers.h +20 -0
  224. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_assignment_certificate.h +165 -0
  225. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_certificate.h +125 -0
  226. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_model.h +365 -0
  227. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_provider.inc +319 -0
  228. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_rounding.inc +170 -0
  229. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_test_hooks.h +342 -0
  230. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/objective_reduction.inc +137 -0
  231. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/overlap_dual.inc +351 -0
  232. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/profile_seed.inc +214 -0
  233. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/seed_heuristics.inc +640 -0
  234. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/sparse_embedding.cpp +430 -0
  235. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/sparse_root_lp.h +176 -0
  236. synkit/Chem/Mapper/solvers/native/cpp/src/pabs/test_hooks.inc +262 -0
  237. synkit/Chem/Mapper/solvers/native/cpp/src/reaction/reaction.cpp +611 -0
  238. synkit/Chem/Mapper/solvers/native/cpp/src/sepdp/README.md +61 -0
  239. synkit/Chem/Mapper/solvers/native/cpp/src/sepdp/sepdp.cpp +253 -0
  240. synkit/Chem/Mapper/solvers/native/cpp/src/slap.cpp +810 -0
  241. synkit/Chem/Mapper/solvers/native/cpp/src/solvers/formulation.h +138 -0
  242. synkit/Chem/Mapper/solvers/native/cpp/src/solvers/maxsat.cpp +526 -0
  243. synkit/Chem/Mapper/solvers/native/cpp/src/solvers/ortools.cpp +475 -0
  244. synkit/Chem/Mapper/solvers/native/cpp/src/solvers/seed.h +80 -0
  245. synkit/Chem/Mapper/solvers/native/cpp/src/solvers/weighted_cnf.h +256 -0
  246. synkit/Chem/Mapper/solvers/native/cpp/src/supporting/README.md +43 -0
  247. synkit/Chem/Mapper/solvers/native/cpp/src/supporting/dfs.cpp +123 -0
  248. synkit/Chem/Mapper/solvers/native/cpp/src/supporting/edit_support.cpp +224 -0
  249. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/classification.cpp +553 -0
  250. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/classification_pipeline.cpp +124 -0
  251. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/classification_stream.h +13 -0
  252. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/cpabs.cpp +455 -0
  253. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/edge_deck.cpp +743 -0
  254. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/COPYRIGHT +44 -0
  255. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/LICENSE-2.0.txt +202 -0
  256. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naugraph.c +732 -0
  257. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naurng.c +94 -0
  258. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naurng.h +49 -0
  259. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nausparse.c +1771 -0
  260. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nausparse.h +133 -0
  261. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nautil.c +750 -0
  262. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naututil.h +355 -0
  263. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nauty.c +1256 -0
  264. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nauty.h +1544 -0
  265. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/schreier.c +1131 -0
  266. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/schreier.h +70 -0
  267. synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/sorttemplates.c +580 -0
  268. synkit/Chem/Mapper/solvers/native/hydrogen.py +711 -0
  269. synkit/Chem/Mapper/solvers/native/implicit.py +506 -0
  270. synkit/Chem/Mapper/solvers/native/implicit_certificate.py +187 -0
  271. synkit/Chem/Mapper/solvers/native/implicit_preparation.py +309 -0
  272. synkit/Chem/Mapper/solvers/native/lib/synkit_mapper.dll +0 -0
  273. synkit/Chem/Mapper/solvers/native/mces.py +16 -0
  274. synkit/Chem/Mapper/solvers/native/reaction.py +179 -0
  275. synkit/Chem/Mapper/solvers/native/reaction_build.py +277 -0
  276. synkit/Chem/Mapper/solvers/native/reaction_text.py +26 -0
  277. synkit/Chem/Mapper/solvers/native/runtime.py +242 -0
  278. synkit/Chem/Mapper/solvers/native/sepdp.py +47 -0
  279. synkit/Chem/Mapper/solvers/native/slap.py +266 -0
  280. synkit/Chem/Mapper/solvers/native/solvers.py +67 -0
  281. synkit/Chem/Mapper/solvers/native/stereo.py +86 -0
  282. synkit/Chem/Mapper/solvers/native/supporting.py +34 -0
  283. synkit/Chem/Mapper/solvers/native/symmetry.py +91 -0
  284. synkit/Chem/Mapper/solvers/slap/__init__.py +29 -0
  285. synkit/Chem/Mapper/solvers/slap/lap.py +174 -0
  286. synkit/Chem/Mapper/solvers/slap/sequential.py +696 -0
  287. synkit/Chem/Mapper/validation/__init__.py +1 -0
  288. synkit/Chem/Mapper/validation/aam_validator.py +442 -0
  289. synkit/Chem/Mapper/validation/annotations.py +274 -0
  290. synkit/Chem/Mapper/validation/bonds.py +124 -0
  291. synkit/Chem/Mapper/validation/cohorts.py +72 -0
  292. synkit/Chem/Mapper/validation/identifiability.py +150 -0
  293. synkit/Chem/Mapper/validation/numerical_scope.py +36 -0
  294. synkit/Chem/Mapper/validation/orbits.py +137 -0
  295. synkit/Chem/Molecule/__init__.py +0 -0
  296. synkit/Chem/Molecule/_chirality_loci.py +165 -0
  297. synkit/Chem/Molecule/_chirality_types.py +231 -0
  298. synkit/Chem/Molecule/_helical_loci.py +167 -0
  299. synkit/Chem/Molecule/_stereo_axis_evidence.py +202 -0
  300. synkit/Chem/Molecule/_stereo_element_detection.py +193 -0
  301. synkit/Chem/Molecule/_stereo_orientation_constraints.py +511 -0
  302. synkit/Chem/Molecule/_tetrahedral_carriers.py +63 -0
  303. synkit/Chem/Molecule/atom_features.py +379 -0
  304. synkit/Chem/Molecule/chirality.py +1041 -0
  305. synkit/Chem/Molecule/cip_assignment.py +569 -0
  306. synkit/Chem/Molecule/cip_ranking.py +843 -0
  307. synkit/Chem/Molecule/coordinate_stereo.py +503 -0
  308. synkit/Chem/Molecule/derived_stereo_naming.py +165 -0
  309. synkit/Chem/Molecule/descriptors.py +452 -0
  310. synkit/Chem/Molecule/formula.py +249 -0
  311. synkit/Chem/Molecule/global_stereo.py +175 -0
  312. synkit/Chem/Molecule/graph_annotator.py +300 -0
  313. synkit/Chem/Molecule/standardize.py +817 -0
  314. synkit/Chem/Molecule/stereo_evidence.py +179 -0
  315. synkit/Chem/Molecule/stereo_perception.py +1032 -0
  316. synkit/Chem/Molecule/valence.py +123 -0
  317. synkit/Chem/Reaction/Mapper/__init__.py +44 -0
  318. synkit/Chem/Reaction/__init__.py +20 -0
  319. synkit/Chem/Reaction/aam_validator.py +5 -0
  320. synkit/Chem/Reaction/balance_check.py +138 -0
  321. synkit/Chem/Reaction/canon_rsmi.py +249 -0
  322. synkit/Chem/Reaction/cleaning.py +58 -0
  323. synkit/Chem/Reaction/deionize.py +199 -0
  324. synkit/Chem/Reaction/explicit_h_audit.py +232 -0
  325. synkit/Chem/Reaction/fix_aam.py +64 -0
  326. synkit/Chem/Reaction/neutralize.py +207 -0
  327. synkit/Chem/Reaction/radical_wildcard.py +224 -0
  328. synkit/Chem/Reaction/standardize.py +203 -0
  329. synkit/Chem/Reaction/tautomerize.py +205 -0
  330. synkit/Chem/__init__.py +1 -0
  331. synkit/Chem/utils.py +315 -0
  332. synkit/Data/__init__.py +0 -0
  333. synkit/Data/aldol.json.gz +1 -0
  334. synkit/Data/gen_partial_aam.py +147 -0
  335. synkit/Data/paracetamol.json.gz +1 -0
  336. synkit/Graph/Canon/__init__.py +16 -0
  337. synkit/Graph/Canon/_native/__init__.py +13 -0
  338. synkit/Graph/Canon/_native/build.py +93 -0
  339. synkit/Graph/Canon/_native/lib/synkit_canon.dll +0 -0
  340. synkit/Graph/Canon/_native/prepare.py +49 -0
  341. synkit/Graph/Canon/_native/runtime.py +140 -0
  342. synkit/Graph/Canon/_native/search.py +137 -0
  343. synkit/Graph/Canon/canon_algs.py +228 -0
  344. synkit/Graph/Canon/canon_graph.py +531 -0
  345. synkit/Graph/Canon/cpp/CMakeLists.txt +42 -0
  346. synkit/Graph/Canon/cpp/README.md +123 -0
  347. synkit/Graph/Canon/cpp/examples/canonical_graph.cpp +16 -0
  348. synkit/Graph/Canon/cpp/include/synkit_canon/canon.h +85 -0
  349. synkit/Graph/Canon/cpp/src/canonical.cpp +391 -0
  350. synkit/Graph/Canon/cpp/src/symmetry.h +83 -0
  351. synkit/Graph/Canon/cpp/tests/symmetry.cpp +93 -0
  352. synkit/Graph/Canon/exact.py +1020 -0
  353. synkit/Graph/Canon/exact_refinement.py +368 -0
  354. synkit/Graph/Canon/nauty.py +143 -0
  355. synkit/Graph/Context/__init__.py +0 -0
  356. synkit/Graph/Context/hier_context.py +244 -0
  357. synkit/Graph/Context/radius_expand.py +252 -0
  358. synkit/Graph/FG/__init__.py +19 -0
  359. synkit/Graph/FG/api.py +39 -0
  360. synkit/Graph/FG/audit.py +155 -0
  361. synkit/Graph/FG/catalog.py +919 -0
  362. synkit/Graph/FG/detector.py +288 -0
  363. synkit/Graph/FG/model.py +97 -0
  364. synkit/Graph/FG/recognizers.py +274 -0
  365. synkit/Graph/FG/ring_system.py +154 -0
  366. synkit/Graph/Feature/Descriptors/topology.py +857 -0
  367. synkit/Graph/Feature/Fingerprint/__init__.py +0 -0
  368. synkit/Graph/Feature/Fingerprint/wl_rxn_fps.py +222 -0
  369. synkit/Graph/Feature/__init__.py +5 -0
  370. synkit/Graph/Feature/graph_descriptors.py +323 -0
  371. synkit/Graph/Feature/graph_fps.py +96 -0
  372. synkit/Graph/Feature/graph_signature.py +239 -0
  373. synkit/Graph/Feature/hash_fps.py +133 -0
  374. synkit/Graph/Feature/morgan_fps.py +88 -0
  375. synkit/Graph/Feature/path_fps.py +81 -0
  376. synkit/Graph/Feature/wl_hash.py +134 -0
  377. synkit/Graph/Fusion/__init__.py +85 -0
  378. synkit/Graph/Fusion/candidate.py +559 -0
  379. synkit/Graph/Fusion/constructor.py +877 -0
  380. synkit/Graph/Fusion/identity.py +184 -0
  381. synkit/Graph/Fusion/interface.py +700 -0
  382. synkit/Graph/Fusion/search.py +241 -0
  383. synkit/Graph/Hyrogen/__init__.py +6 -0
  384. synkit/Graph/Hyrogen/_misc.py +591 -0
  385. synkit/Graph/Hyrogen/hcomplete.py +995 -0
  386. synkit/Graph/Hyrogen/hcomplete_legacy.py +368 -0
  387. synkit/Graph/Hyrogen/hcompletion_algorithms.py +713 -0
  388. synkit/Graph/Hyrogen/hextend.py +570 -0
  389. synkit/Graph/Hyrogen/hextend_legacy.py +215 -0
  390. synkit/Graph/ITS/__init__.py +4 -0
  391. synkit/Graph/ITS/its_builder.py +120 -0
  392. synkit/Graph/ITS/its_construction.py +719 -0
  393. synkit/Graph/ITS/its_decompose.py +572 -0
  394. synkit/Graph/ITS/its_destruction.py +331 -0
  395. synkit/Graph/ITS/its_expand.py +1251 -0
  396. synkit/Graph/ITS/its_relabel.py +187 -0
  397. synkit/Graph/ITS/its_reverter.py +356 -0
  398. synkit/Graph/ITS/normalize_aam.py +145 -0
  399. synkit/Graph/ITS/partial_its.py +238 -0
  400. synkit/Graph/ITS/rc_extractor.py +656 -0
  401. synkit/Graph/ITS/stereo.py +74 -0
  402. synkit/Graph/MTG/__init__.py +107 -0
  403. synkit/Graph/MTG/gluing.py +451 -0
  404. synkit/Graph/MTG/history.py +928 -0
  405. synkit/Graph/MTG/inventory.py +118 -0
  406. synkit/Graph/MTG/local.py +447 -0
  407. synkit/Graph/MTG/mcs_matcher.py +246 -0
  408. synkit/Graph/MTG/mtg.py +611 -0
  409. synkit/Graph/MTG/mtg_explore.py +74 -0
  410. synkit/Graph/MTG/observation.py +209 -0
  411. synkit/Graph/MTG/process.py +577 -0
  412. synkit/Graph/MTG/queries.py +66 -0
  413. synkit/Graph/MTG/realization.py +95 -0
  414. synkit/Graph/MTG/series_parallel.py +107 -0
  415. synkit/Graph/MTG/utils.py +424 -0
  416. synkit/Graph/Matcher/__init__.py +10 -0
  417. synkit/Graph/Matcher/approx_mcs.py +1264 -0
  418. synkit/Graph/Matcher/auto_est.py +736 -0
  419. synkit/Graph/Matcher/automorphism.py +314 -0
  420. synkit/Graph/Matcher/batch_cluster.py +224 -0
  421. synkit/Graph/Matcher/dedup_matches.py +247 -0
  422. synkit/Graph/Matcher/graph_cluster.py +191 -0
  423. synkit/Graph/Matcher/graph_matcher.py +312 -0
  424. synkit/Graph/Matcher/graph_morphism.py +421 -0
  425. synkit/Graph/Matcher/mcs_matcher.py +804 -0
  426. synkit/Graph/Matcher/multi_turbo_iso.py +186 -0
  427. synkit/Graph/Matcher/orbit.py +284 -0
  428. synkit/Graph/Matcher/partial_matcher.py +694 -0
  429. synkit/Graph/Matcher/sing.py +544 -0
  430. synkit/Graph/Matcher/subgraph_matcher.py +812 -0
  431. synkit/Graph/Matcher/turbo_iso.py +272 -0
  432. synkit/Graph/Matcher/wl_sel.py +537 -0
  433. synkit/Graph/Mech/__init__.py +26 -0
  434. synkit/Graph/Mech/conversion.py +1466 -0
  435. synkit/Graph/Mech/conversion_debug.py +237 -0
  436. synkit/Graph/Mech/electron_accounting.py +200 -0
  437. synkit/Graph/Mech/lwg_editor.py +406 -0
  438. synkit/Graph/Mech/lwg_ops.py +313 -0
  439. synkit/Graph/Morphism/__init__.py +99 -0
  440. synkit/Graph/Morphism/constraints.py +460 -0
  441. synkit/Graph/Morphism/llg.py +999 -0
  442. synkit/Graph/Morphism/morphism.py +349 -0
  443. synkit/Graph/Morphism/stereo.py +258 -0
  444. synkit/Graph/Morphism/stereo_morphism.py +383 -0
  445. synkit/Graph/Morphism/stereo_morphism_helpers.py +957 -0
  446. synkit/Graph/Morphism/stereo_morphism_types.py +117 -0
  447. synkit/Graph/Stereo/__init__.py +376 -0
  448. synkit/Graph/Stereo/_descriptor_core.py +207 -0
  449. synkit/Graph/Stereo/_descriptor_serialization.py +138 -0
  450. synkit/Graph/Stereo/canonical.py +648 -0
  451. synkit/Graph/Stereo/changes.py +964 -0
  452. synkit/Graph/Stereo/composition.py +391 -0
  453. synkit/Graph/Stereo/configured.py +946 -0
  454. synkit/Graph/Stereo/couplings.py +245 -0
  455. synkit/Graph/Stereo/descriptors.py +1030 -0
  456. synkit/Graph/Stereo/enumeration.py +597 -0
  457. synkit/Graph/Stereo/extended_descriptors.py +406 -0
  458. synkit/Graph/Stereo/global_configured.py +152 -0
  459. synkit/Graph/Stereo/global_stereo.py +304 -0
  460. synkit/Graph/Stereo/identity.py +648 -0
  461. synkit/Graph/Stereo/interchange.py +496 -0
  462. synkit/Graph/Stereo/legacy.py +460 -0
  463. synkit/Graph/Stereo/matching.py +899 -0
  464. synkit/Graph/Stereo/native.py +154 -0
  465. synkit/Graph/Stereo/orbits.py +668 -0
  466. synkit/Graph/Stereo/outcomes.py +99 -0
  467. synkit/Graph/Stereo/pairwise.py +350 -0
  468. synkit/Graph/Stereo/rdkit_adapter.py +662 -0
  469. synkit/Graph/Stereo/rdkit_identity.py +118 -0
  470. synkit/Graph/Stereo/rdkit_resonance.py +140 -0
  471. synkit/Graph/Stereo/reaction_interchange.py +266 -0
  472. synkit/Graph/Stereo/semantics.py +296 -0
  473. synkit/Graph/Stereo/supports.py +257 -0
  474. synkit/Graph/Stereo/wire.py +339 -0
  475. synkit/Graph/Wildcard/__init__.py +0 -0
  476. synkit/Graph/Wildcard/fuse_graph.py +156 -0
  477. synkit/Graph/Wildcard/graph_wc.py +303 -0
  478. synkit/Graph/Wildcard/its_merge.py +857 -0
  479. synkit/Graph/Wildcard/radwc.py +114 -0
  480. synkit/Graph/Wildcard/wc_matcher.py +576 -0
  481. synkit/Graph/Wildcard/wildcard.py +225 -0
  482. synkit/Graph/__init__.py +17 -0
  483. synkit/Graph/canon_graph.py +14 -0
  484. synkit/Graph/syn_graph.py +199 -0
  485. synkit/Graph/utils.py +324 -0
  486. synkit/IO/__init__.py +4 -0
  487. synkit/IO/chem_converter.py +1059 -0
  488. synkit/IO/combinatorial/__init__.py +8 -0
  489. synkit/IO/combinatorial/gml_to_graph.py +223 -0
  490. synkit/IO/combinatorial/graph_to_gml.py +280 -0
  491. synkit/IO/combinatorial/graph_to_smarts.py +186 -0
  492. synkit/IO/combinatorial/smarts_expander.py +147 -0
  493. synkit/IO/combinatorial/smarts_generalizer.py +133 -0
  494. synkit/IO/combinatorial/smarts_to_graph.py +179 -0
  495. synkit/IO/conversion.py +42 -0
  496. synkit/IO/data_io.py +269 -0
  497. synkit/IO/data_process.py +143 -0
  498. synkit/IO/debug.py +73 -0
  499. synkit/IO/gml_to_nx.py +150 -0
  500. synkit/IO/graph_to_mol.py +199 -0
  501. synkit/IO/mol_to_graph.py +1105 -0
  502. synkit/IO/mol_to_graph_chemistry.py +545 -0
  503. synkit/IO/nx_to_gml.py +209 -0
  504. synkit/IO/smiles_to_id.py +123 -0
  505. synkit/Mechanism/__init__.py +151 -0
  506. synkit/Mechanism/adapters.py +136 -0
  507. synkit/Mechanism/audit.py +323 -0
  508. synkit/Mechanism/benchmark.py +638 -0
  509. synkit/Mechanism/compatibility.py +13 -0
  510. synkit/Mechanism/drawing.py +85 -0
  511. synkit/Mechanism/electron_models.py +725 -0
  512. synkit/Mechanism/equivalence.py +521 -0
  513. synkit/Mechanism/evidence.py +262 -0
  514. synkit/Mechanism/interchange.py +141 -0
  515. synkit/Mechanism/model.py +918 -0
  516. synkit/Mechanism/neighbor_stereo.py +312 -0
  517. synkit/Mechanism/radical_data.py +740 -0
  518. synkit/Mechanism/replay.py +986 -0
  519. synkit/Mechanism/schema.py +264 -0
  520. synkit/Mechanism/stereo_state.py +416 -0
  521. synkit/Mechanism/symbols.py +91 -0
  522. synkit/Rule/Apply/__init__.py +35 -0
  523. synkit/Rule/Apply/conditions.py +45 -0
  524. synkit/Rule/Apply/dpo.py +998 -0
  525. synkit/Rule/Apply/rule_matcher.py +218 -0
  526. synkit/Rule/Apply/validation.py +354 -0
  527. synkit/Rule/Compose/__init__.py +106 -0
  528. synkit/Rule/Compose/_identity.py +43 -0
  529. synkit/Rule/Compose/composition.py +976 -0
  530. synkit/Rule/Compose/laws.py +439 -0
  531. synkit/Rule/Compose/search.py +771 -0
  532. synkit/Rule/Compose/synrule.py +170 -0
  533. synkit/Rule/Modify/__init__.py +0 -0
  534. synkit/Rule/Modify/implict_rule.py +56 -0
  535. synkit/Rule/Modify/longest_path.py +92 -0
  536. synkit/Rule/Modify/molecule_rule.py +115 -0
  537. synkit/Rule/Modify/prune_templates.py +78 -0
  538. synkit/Rule/Modify/rule_utils.py +194 -0
  539. synkit/Rule/Modify/strip_rule.py +97 -0
  540. synkit/Rule/__init__.py +28 -0
  541. synkit/Rule/generic_stereo.py +884 -0
  542. synkit/Rule/stereo_identity.py +271 -0
  543. synkit/Rule/syn_rule.py +1090 -0
  544. synkit/Synthesis/MSR/__init__.py +0 -0
  545. synkit/Synthesis/MSR/path_finder.py +239 -0
  546. synkit/Synthesis/Metrics/__init__.py +0 -0
  547. synkit/Synthesis/Metrics/_base.py +52 -0
  548. synkit/Synthesis/Metrics/_plot.py +129 -0
  549. synkit/Synthesis/Metrics/_ranking.py +179 -0
  550. synkit/Synthesis/RBL/__init__.py +80 -0
  551. synkit/Synthesis/RBL/engine.py +1249 -0
  552. synkit/Synthesis/RBL/matching.py +652 -0
  553. synkit/Synthesis/RBL/overlap.py +336 -0
  554. synkit/Synthesis/RBL/pipeline.py +376 -0
  555. synkit/Synthesis/RBL/policy.py +139 -0
  556. synkit/Synthesis/RBL/proof.py +370 -0
  557. synkit/Synthesis/RBL/reaction.py +506 -0
  558. synkit/Synthesis/RBL/state.py +169 -0
  559. synkit/Synthesis/RBL/validation.py +1060 -0
  560. synkit/Synthesis/Reactor/__init__.py +60 -0
  561. synkit/Synthesis/Reactor/core/__init__.py +1 -0
  562. synkit/Synthesis/Reactor/core/engine.py +967 -0
  563. synkit/Synthesis/Reactor/core/product.py +621 -0
  564. synkit/Synthesis/Reactor/core/rewrite.py +561 -0
  565. synkit/Synthesis/Reactor/core/strategy.py +44 -0
  566. synkit/Synthesis/Reactor/matching/__init__.py +1 -0
  567. synkit/Synthesis/Reactor/matching/mixin.py +920 -0
  568. synkit/Synthesis/Reactor/matching/policy.py +345 -0
  569. synkit/Synthesis/Reactor/matching/symmetry.py +309 -0
  570. synkit/Synthesis/Reactor/output/__init__.py +1 -0
  571. synkit/Synthesis/Reactor/output/deduplication.py +703 -0
  572. synkit/Synthesis/Reactor/output/policy.py +16 -0
  573. synkit/Synthesis/Reactor/output/serialization.py +485 -0
  574. synkit/Synthesis/Reactor/output/structural.py +893 -0
  575. synkit/Synthesis/Reactor/stereo/__init__.py +1 -0
  576. synkit/Synthesis/Reactor/stereo/assignment.py +35 -0
  577. synkit/Synthesis/Reactor/stereo/mixin.py +780 -0
  578. synkit/Synthesis/Reactor/variants/__init__.py +1 -0
  579. synkit/Synthesis/Reactor/variants/imbalanced.py +180 -0
  580. synkit/Synthesis/Reactor/variants/partial.py +84 -0
  581. synkit/Synthesis/Reactor/workflow/__init__.py +1 -0
  582. synkit/Synthesis/Reactor/workflow/batch.py +550 -0
  583. synkit/Synthesis/Reactor/workflow/benchmark.py +143 -0
  584. synkit/Synthesis/Reactor/workflow/postprocess.py +267 -0
  585. synkit/Synthesis/Reactor/workflow/rule_filter.py +210 -0
  586. synkit/Synthesis/__init__.py +0 -0
  587. synkit/Synthesis/reactor_utils.py +316 -0
  588. synkit/Utils/__init__.py +0 -0
  589. synkit/Utils/utils.py +172 -0
  590. synkit/Vis/__init__.py +91 -0
  591. synkit/Vis/crn/__init__.py +40 -0
  592. synkit/Vis/epd/__init__.py +20 -0
  593. synkit/Vis/epd/arrows.py +425 -0
  594. synkit/Vis/epd/chem.py +197 -0
  595. synkit/Vis/epd/constants.py +83 -0
  596. synkit/Vis/epd/layout.py +283 -0
  597. synkit/Vis/epd/mapping.py +51 -0
  598. synkit/Vis/epd/models.py +136 -0
  599. synkit/Vis/epd/render.py +543 -0
  600. synkit/Vis/epd/utils.py +108 -0
  601. synkit/Vis/epd/visualizer.py +811 -0
  602. synkit/Vis/graph_visualizer.py +375 -0
  603. synkit/Vis/its/__init__.py +19 -0
  604. synkit/Vis/its/drawer.py +615 -0
  605. synkit/Vis/its_drawer.py +35 -0
  606. synkit/Vis/molecule/__init__.py +31 -0
  607. synkit/Vis/molecule/drawer.py +563 -0
  608. synkit/Vis/molecule/reaction.py +285 -0
  609. synkit/Vis/molecule_drawer.py +33 -0
  610. synkit/Vis/mtg/__init__.py +17 -0
  611. synkit/Vis/mtg/drawer.py +769 -0
  612. synkit/Vis/mtg_drawer.py +34 -0
  613. synkit/Vis/pdf_writer.py +146 -0
  614. synkit/Vis/reaction/__init__.py +19 -0
  615. synkit/Vis/reaction/rule.py +141 -0
  616. synkit/Vis/reaction/rxn.py +532 -0
  617. synkit/Vis/reaction_drawer.py +41 -0
  618. synkit/Vis/space/__init__.py +17 -0
  619. synkit/Vis/space/chemical.py +80 -0
  620. synkit/Vis/space/embedding.py +87 -0
  621. synkit/Vis/vis_synedu/Vis/__init__.py +7 -0
  622. synkit/Vis/vis_synedu/Vis/dpo.py +862 -0
  623. synkit/Vis/vis_synedu/rxn_vis.py +377 -0
  624. synkit/Vis/vis_synedu/vis.py +501 -0
  625. synkit/Vis/visual_drawer.py +215 -0
  626. synkit/Vis/visual_model.py +520 -0
  627. synkit/__init__.py +3 -0
  628. synkit/_native.py +91 -0
  629. synkit/examples.py +50 -0
  630. synkit/version.py +23 -0
  631. synkit-1.6.5.dist-info/METADATA +156 -0
  632. synkit-1.6.5.dist-info/RECORD +636 -0
  633. synkit-1.6.5.dist-info/WHEEL +4 -0
  634. synkit-1.6.5.dist-info/licenses/LICENSE +21 -0
  635. synkit-1.6.5.dist-info/licenses/synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/COPYRIGHT +44 -0
  636. synkit-1.6.5.dist-info/licenses/synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/LICENSE-2.0.txt +202 -0
@@ -0,0 +1,266 @@
1
+ """Thin prepared-graph adapter for deterministic weighted SLAP in C++."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import ctypes as ct
6
+ import math
7
+ import time
8
+ from collections import Counter
9
+ from dataclasses import dataclass
10
+ from functools import lru_cache
11
+ from numbers import Integral, Real
12
+ from pathlib import Path
13
+
14
+ import numpy as np
15
+
16
+ from ..slap.lap import _adjacency_and_elements
17
+
18
+
19
+ class _Statistics(ct.Structure):
20
+ _fields_ = (
21
+ [
22
+ (name, ct.c_int64)
23
+ for name in (
24
+ "states",
25
+ "lap_calls",
26
+ "fingerprints",
27
+ "candidates",
28
+ "best_proxy2",
29
+ )
30
+ ]
31
+ + [(name, ct.c_int32) for name in ("completed", "reason")]
32
+ + [(name, ct.c_double) for name in ("elapsed_seconds", "callback_seconds")]
33
+ )
34
+
35
+
36
+ _INT = ct.POINTER(ct.c_int32)
37
+ _LONG = ct.POINTER(ct.c_int64)
38
+ _CALLBACK = ct.CFUNCTYPE(ct.c_int, _INT, ct.c_int64, ct.c_void_p)
39
+
40
+
41
+ @lru_cache(maxsize=4)
42
+ def _load(path):
43
+ library = ct.CDLL(str(Path(path).resolve()))
44
+ if library.synkit_mapper_abi() != 1:
45
+ raise RuntimeError(
46
+ "Unsupported native mapper ABI; rebuild with build_mapper_native"
47
+ )
48
+ library.synkit_mapper_error.restype = ct.c_char_p
49
+ library.synkit_slap_solve.argtypes = [
50
+ ct.c_int,
51
+ _LONG,
52
+ _LONG,
53
+ _INT,
54
+ _INT,
55
+ _INT,
56
+ ct.c_int,
57
+ ct.c_double,
58
+ ct.c_int64,
59
+ ct.c_int64,
60
+ _CALLBACK,
61
+ ct.c_void_p,
62
+ ct.POINTER(_Statistics),
63
+ ]
64
+ library.synkit_slap_solve.restype = ct.c_int
65
+ return library
66
+
67
+
68
+ @dataclass(frozen=True)
69
+ class NativeSlapResult:
70
+ """Reached heuristic candidates; finished SLAP is not exact enumeration."""
71
+
72
+ mappings: list[list[int]]
73
+ distances: list[float]
74
+ selected_mapping_count: int
75
+ heuristic_finished: bool
76
+ truncation_reason: str | None
77
+ elapsed_seconds: float
78
+ backend_statistics: dict
79
+ backend: str = "slap_cpp"
80
+ scope: str = "heuristic_candidates"
81
+ minimum_cost: None = None
82
+ optimality_proven: bool = False
83
+ complete: bool = False
84
+
85
+ @property
86
+ def selected_labeled_mapping_count(self):
87
+ return self.selected_mapping_count
88
+
89
+
90
+ # Array ownership and output callbacks must span the complete native solve.
91
+ def solve_slap( # noqa: C901
92
+ lgp,
93
+ *,
94
+ library_path,
95
+ binary=False,
96
+ max_lap_fingerprints=10_000,
97
+ time_limit_seconds=None,
98
+ max_states=None,
99
+ max_mappings=None,
100
+ collect_mappings=True,
101
+ mapping_callback=None,
102
+ ):
103
+ """Run SLAP refinement, LAP/fingerprint exploration and splitting in C++.
104
+
105
+ This deterministic weighted variant preserves half-integer chemical weights.
106
+ It does not reproduce Python hash labels, LAP tie order, or historical
107
+ fractional-cost truncation. All algorithmic decisions and final rescoring
108
+ occur in C++; Python only prepares arrays and handles output callbacks.
109
+ The caller can use ordinary reaction parsing/classification via Mapper.
110
+ """
111
+ started = time.perf_counter()
112
+ if len(lgp) != 2:
113
+ raise ValueError("SLAP requires two endpoint graphs")
114
+ if not isinstance(binary, bool) or not isinstance(collect_mappings, bool):
115
+ raise TypeError("binary and collect_mappings must be boolean")
116
+ for name, value in (
117
+ ("max_lap_fingerprints", max_lap_fingerprints),
118
+ ("max_states", max_states),
119
+ ("max_mappings", max_mappings),
120
+ ):
121
+ if value is None and name != "max_lap_fingerprints":
122
+ continue
123
+ if (
124
+ isinstance(value, bool)
125
+ or not isinstance(value, Integral)
126
+ or not 1 <= value < 2**63
127
+ ):
128
+ raise ValueError(
129
+ f"{name} must be a positive integer"
130
+ + (" or None" if name != "max_lap_fingerprints" else "")
131
+ )
132
+ if max_lap_fingerprints >= 2**31:
133
+ raise ValueError("max_lap_fingerprints exceeds the C ABI integer range")
134
+ if time_limit_seconds is not None and (
135
+ isinstance(time_limit_seconds, bool)
136
+ or not isinstance(time_limit_seconds, Real)
137
+ or not math.isfinite(time_limit_seconds)
138
+ or time_limit_seconds < 0
139
+ ):
140
+ raise ValueError("time_limit_seconds must be finite and nonnegative")
141
+ if mapping_callback is not None and not callable(mapping_callback):
142
+ raise TypeError("mapping_callback must be callable")
143
+ matrices, elements = zip(*(_adjacency_and_elements(g, binary) for g in lgp))
144
+ if any(g.graph[i].get(i, 0) for g in lgp for i in range(len(g.labels))):
145
+ raise ValueError("Native SLAP requires loop-free graphs")
146
+ a, b = matrices
147
+ labels = [list(graph.labels) for graph in lgp]
148
+ n = len(labels[0])
149
+ if not 1 <= n <= 512 or a.shape != (n, n) or b.shape != (n, n):
150
+ raise ValueError(
151
+ "Native SLAP requires compatible endpoints with 1..512 vertices"
152
+ )
153
+ if Counter(labels[0]) != Counter(labels[1]) or Counter(elements[0]) != Counter(
154
+ elements[1]
155
+ ):
156
+ raise ValueError("SLAP endpoints must have equal atom-type inventories")
157
+ encoded_matrices = []
158
+ for matrix in matrices:
159
+ if (
160
+ not np.isfinite(matrix).all()
161
+ or np.any(matrix < 0)
162
+ or np.any(matrix > 500000)
163
+ or not np.array_equal(matrix, matrix.T)
164
+ or np.any(np.diag(matrix))
165
+ or not np.allclose(matrix * 2, np.rint(matrix * 2), atol=1e-9, rtol=0)
166
+ ):
167
+ raise ValueError(
168
+ "Native SLAP requires symmetric loop-free nonnegative half-integer weights"
169
+ )
170
+ encoded_matrices.append(
171
+ np.ascontiguousarray(np.rint(matrix * 2), dtype=np.int64)
172
+ )
173
+ registry = {}
174
+ encoded_labels = [
175
+ np.asarray(
176
+ [
177
+ registry.setdefault((x, element), len(registry))
178
+ for x, element in zip(side, atoms)
179
+ ],
180
+ dtype=np.int32,
181
+ )
182
+ for side, atoms in zip(labels, elements)
183
+ ]
184
+ if Counter(encoded_labels[0]) != Counter(encoded_labels[1]):
185
+ raise ValueError(
186
+ "Initial SLAP partitions have incompatible atom-type inventories"
187
+ )
188
+ # Preserve the Python matcher's special original-label rule. Reencoded
189
+ # numeric type 1 must not accidentally activate it for another atom type.
190
+ stop_flags = np.asarray([int(value == 1) for value in labels[0]], dtype=np.int32)
191
+ mappings, distances, errors = [], [], []
192
+
193
+ def receive(pointer, cost2, _userdata):
194
+ try:
195
+ mapping = list(pointer[:n])
196
+ if sorted(mapping) != list(range(n)) or any(
197
+ labels[0][i] != labels[1][j] or elements[0][i] != elements[1][j]
198
+ for i, j in enumerate(mapping)
199
+ ):
200
+ raise RuntimeError(
201
+ "Native SLAP returned an incompatible atom bijection"
202
+ )
203
+ cost = cost2 / 2
204
+ if collect_mappings:
205
+ mappings.append(mapping)
206
+ distances.append(cost)
207
+ if mapping_callback is not None:
208
+ mapping_callback(mapping, cost)
209
+ return 0
210
+ except BaseException as error: # noqa: BLE001 -- Never cross the C callback boundary.
211
+ errors.append(error)
212
+ return 1
213
+
214
+ callback = _CALLBACK(receive)
215
+ library = _load(str(Path(library_path).resolve()))
216
+ seconds = (
217
+ -1.0
218
+ if time_limit_seconds is None
219
+ else max(0, time_limit_seconds - (time.perf_counter() - started))
220
+ )
221
+ stats = _Statistics()
222
+ status = library.synkit_slap_solve(
223
+ n,
224
+ *(array.ctypes.data_as(_LONG) for array in encoded_matrices),
225
+ *(array.ctypes.data_as(_INT) for array in encoded_labels),
226
+ stop_flags.ctypes.data_as(_INT),
227
+ int(max_lap_fingerprints),
228
+ seconds,
229
+ -1 if max_states is None else int(max_states),
230
+ -1 if max_mappings is None else int(max_mappings),
231
+ callback,
232
+ None,
233
+ ct.byref(stats),
234
+ )
235
+ if errors:
236
+ raise errors[0]
237
+ if status:
238
+ raise RuntimeError(library.synkit_mapper_error().decode())
239
+ reasons = {
240
+ 0: None,
241
+ 1: "time_limit",
242
+ 2: "max_states",
243
+ 3: "max_mappings",
244
+ 4: "callback",
245
+ }
246
+ statistics = {name: getattr(stats, name) for name, _ in stats._fields_}
247
+ statistics.update(
248
+ variant="deterministic_weighted_slap_v1",
249
+ cost_scale=2,
250
+ implementation="cpp_sequential_lap_fingerprints_refinement",
251
+ library_path=str(Path(library_path).resolve()),
252
+ max_lap_fingerprints=int(max_lap_fingerprints),
253
+ symmetry_policy="heuristic_stable_wl_split_representatives",
254
+ )
255
+ return NativeSlapResult(
256
+ mappings,
257
+ distances,
258
+ stats.candidates,
259
+ bool(stats.completed),
260
+ reasons[stats.reason],
261
+ time.perf_counter() - started,
262
+ statistics,
263
+ )
264
+
265
+
266
+ __all__ = ["NativeSlapResult", "solve_slap"]
@@ -0,0 +1,67 @@
1
+ """Thin prepared-graph and reaction adapters for optional native solver engines.
2
+
3
+ The common core loads prebuilt libraries explicitly. No engine is compiled on
4
+ import, and an unavailable requested C++ backend never falls back to Python.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from .core import enumerate_core_mappings, map_reaction_core
10
+
11
+ SOLVERS = frozenset({"cp_sat", "scip", "maxsat", "kmilp"})
12
+
13
+
14
+ def _backend(solver):
15
+ if solver not in SOLVERS:
16
+ raise ValueError("solver must be 'cp_sat', 'scip', 'maxsat', or 'kmilp'")
17
+ return solver
18
+
19
+
20
+ def enumerate_solver_mappings(lgp, *, library_path, solver="cp_sat", **options):
21
+ """Run a full-space or explicit-kernel engine through the doubled-CD ABI.
22
+
23
+ CP-SAT enumerates the objective-free satisfaction model after minimum
24
+ proof. SCIP and Open-WBO enumerate projected assignments with no-goods.
25
+ Native class construction is requested separately from raw enumeration.
26
+ """
27
+ return enumerate_core_mappings(
28
+ lgp, library_path=library_path, backend=_backend(solver), **options
29
+ )
30
+
31
+
32
+ def map_reaction_solver(reaction, *, library_path, solver="cp_sat", **options):
33
+ """Use the common chemistry frontend with an explicitly selected engine."""
34
+ return map_reaction_core(
35
+ reaction, library_path=library_path, backend=_backend(solver), **options
36
+ )
37
+
38
+
39
+ def enumerate_kernel_milp_mappings(lgp, *, library_path, allowed_domains, **options):
40
+ """Enumerate only the explicitly supplied compatible assignment kernel."""
41
+ if allowed_domains is None:
42
+ raise ValueError("KMILP requires explicit allowed_domains")
43
+ return enumerate_core_mappings(
44
+ lgp,
45
+ library_path=library_path,
46
+ backend="kmilp",
47
+ allowed_domains=allowed_domains,
48
+ **options,
49
+ )
50
+
51
+
52
+ def map_reaction_kernel_milp(reaction, *, library_path, allowed_domains, **options):
53
+ """Map within explicit domains using native classification by default.
54
+
55
+ Set native_classification=False to select reference Python classification.
56
+ The proof and enumeration scope remains the supplied kernel.
57
+ """
58
+ if allowed_domains is None:
59
+ raise ValueError("KMILP requires explicit allowed_domains")
60
+ options.setdefault("native_classification", True)
61
+ return map_reaction_core(
62
+ reaction,
63
+ library_path=library_path,
64
+ backend="kmilp",
65
+ allowed_domains=allowed_domains,
66
+ **options,
67
+ )
@@ -0,0 +1,86 @@
1
+ """Preserve supplied geometry and assign complete modern CIP descriptors."""
2
+
3
+ import json
4
+
5
+ from rdkit import Chem
6
+ from rdkit.Chem import rdCIPLabeler
7
+
8
+
9
+ def assign_stereo(mol):
10
+ """Assign true CIP labels without legacy cleanup of supplied chiral tags.
11
+
12
+ Highly symmetric recursion is bounded and raises explicitly rather than
13
+ returning a silently incomplete stereo palette. No H atoms are created.
14
+ """
15
+ for obj in list(mol.GetAtoms()) + list(mol.GetBonds()):
16
+ if obj.HasProp("_CIPCode"):
17
+ obj.ClearProp("_CIPCode")
18
+ rdCIPLabeler.AssignCIPLabels(mol, maxRecursiveIterations=1000000)
19
+ return mol
20
+
21
+
22
+ def stereo_smiles(mol, *, canonical=True):
23
+ """Serialize existing stereo without RDKit's lossy legacy cleanup pass."""
24
+ parameters = Chem.SmilesWriteParams()
25
+ parameters.canonical = canonical
26
+ parameters.doIsomericSmiles = True
27
+ parameters.cleanStereo = False
28
+ return Chem.MolToSmiles(mol, parameters)
29
+
30
+
31
+ def endpoint_identity_key(mol):
32
+ """Canonical colored-graph identity, avoiding stereo-SMILES rank ambiguity.
33
+
34
+ Modern CIP is encoded as an ordinary node color. Bond state is encoded by
35
+ colored auxiliary vertices; these are identity-code gadgets, not H atoms or
36
+ chemical participants. The original palette accompanies the graph code.
37
+ """
38
+ assign_stereo(mol)
39
+ node_tokens = [
40
+ json.dumps(
41
+ (
42
+ "a",
43
+ a.GetAtomicNum(),
44
+ a.GetIsotope(),
45
+ a.GetFormalCharge(),
46
+ a.GetNumRadicalElectrons(),
47
+ a.GetTotalNumHs(),
48
+ a.GetIsAromatic(),
49
+ a.GetProp("_CIPCode") if a.HasProp("_CIPCode") else "",
50
+ )
51
+ )
52
+ for a in mol.GetAtoms()
53
+ ]
54
+ edge_tokens = [
55
+ json.dumps(("b", str(b.GetBondType()), str(b.GetStereo())))
56
+ for b in mol.GetBonds()
57
+ ]
58
+ directed = {Chem.BondType.DATIVE, Chem.BondType.DATIVEL, Chem.BondType.DATIVER}
59
+ tokens = sorted(set(node_tokens + edge_tokens + ['"tail"', '"head"']))
60
+ colors = {token: i + 1 for i, token in enumerate(tokens)}
61
+ graph = Chem.RWMol()
62
+
63
+ def add(token):
64
+ atom = Chem.Atom(0)
65
+ atom.SetNoImplicit(True)
66
+ atom.SetIsotope(colors[token])
67
+ return graph.AddAtom(atom)
68
+
69
+ for token in node_tokens:
70
+ add(token)
71
+ for bond, token in zip(mol.GetBonds(), edge_tokens):
72
+ i, j = bond.GetBeginAtomIdx(), bond.GetEndAtomIdx()
73
+ middle = add(token)
74
+ if bond.GetBondType() in directed:
75
+ tail, head = add('"tail"'), add('"head"')
76
+ graph.AddBond(i, tail, Chem.BondType.SINGLE)
77
+ graph.AddBond(tail, middle, Chem.BondType.SINGLE)
78
+ graph.AddBond(middle, head, Chem.BondType.SINGLE)
79
+ graph.AddBond(head, j, Chem.BondType.SINGLE)
80
+ else:
81
+ graph.AddBond(i, middle, Chem.BondType.SINGLE)
82
+ graph.AddBond(middle, j, Chem.BondType.SINGLE)
83
+ return json.dumps(
84
+ (tokens, Chem.MolToSmiles(graph, canonical=True, isomericSmiles=True)),
85
+ separators=(",", ":"),
86
+ )
@@ -0,0 +1,34 @@
1
+ """Native exhaustive DFS and binary edit-support enumeration adapters."""
2
+
3
+ from .core import enumerate_core_mappings, map_reaction_core
4
+
5
+
6
+ def enumerate_dfs_mappings(graphs, *, library_path, **options):
7
+ """Exhaustive compatible permutation traversal with no assignment bound."""
8
+ return enumerate_core_mappings(
9
+ graphs, library_path=library_path, backend="dfs", **options
10
+ )
11
+
12
+
13
+ def enumerate_edit_mappings(graphs, *, library_path, **options):
14
+ """Enumerate binary edge-flip supports then exact typed graph isomorphisms.
15
+
16
+ This backend supports only binary bond presence. Supplying ``binary=True``
17
+ explicitly converts a weighted input to that separate objective; requesting
18
+ weighted EDIT without conversion returns unsupported from the native core.
19
+ """
20
+ return enumerate_core_mappings(
21
+ graphs, library_path=library_path, backend="edit", **options
22
+ )
23
+
24
+
25
+ def map_reaction_dfs(reaction, *, library_path, **options):
26
+ return map_reaction_core(
27
+ reaction, library_path=library_path, backend="dfs", **options
28
+ )
29
+
30
+
31
+ def map_reaction_edit(reaction, *, library_path, **options):
32
+ return map_reaction_core(
33
+ reaction, library_path=library_path, backend="edit", **options
34
+ )
@@ -0,0 +1,91 @@
1
+ """Opt-in canonical construction traversal and its measured symmetry work."""
2
+
3
+ import ctypes as ct
4
+ from pathlib import Path
5
+
6
+
7
+ class _Profile(ct.Structure):
8
+ _fields_ = [
9
+ (name, ct.c_int64)
10
+ for name in (
11
+ "discovery_nodes",
12
+ "subgroup_order",
13
+ "canonical_calls",
14
+ "augmentations",
15
+ "canonical_rejections",
16
+ "bound_rejections",
17
+ )
18
+ ] + [
19
+ ("identity_fallback_r", ct.c_int32),
20
+ ("identity_fallback_p", ct.c_int32),
21
+ ("discovery_seconds", ct.c_double),
22
+ ("canonical_seconds", ct.c_double),
23
+ ]
24
+
25
+
26
+ class _ProfileV2(ct.Structure):
27
+ _fields_ = (
28
+ [("base", _Profile)]
29
+ + [
30
+ (name, ct.c_int64)
31
+ for name in (
32
+ "twin_blocks_r",
33
+ "twin_blocks_p",
34
+ "quotient_order_r",
35
+ "quotient_order_p",
36
+ "bound_calls",
37
+ "seed_cost2",
38
+ )
39
+ ]
40
+ + [("bound_seconds", ct.c_double), ("seed_seconds", ct.c_double)]
41
+ )
42
+
43
+
44
+ def cpabs_profile(library_path):
45
+ """Read same-thread diagnostics from the latest cPABS run in this library."""
46
+ library = ct.CDLL(str(Path(library_path).resolve()))
47
+ function = library.synkit_mapper_cpabs_profile
48
+ function.argtypes = [ct.POINTER(_Profile)]
49
+ function.restype = None
50
+ value = _Profile()
51
+ function(ct.byref(value))
52
+ result = {name: getattr(value, name) for name, _ in _Profile._fields_}
53
+ if hasattr(library, "synkit_mapper_cpabs_profile_v2"):
54
+ function = library.synkit_mapper_cpabs_profile_v2
55
+ function.argtypes = [ct.POINTER(_ProfileV2)]
56
+ function.restype = None
57
+ detail = _ProfileV2()
58
+ function(ct.byref(detail))
59
+ result.update(
60
+ {
61
+ name: getattr(detail, name)
62
+ for name, _ in _ProfileV2._fields_
63
+ if name != "base"
64
+ }
65
+ )
66
+ return result
67
+
68
+
69
+ def enumerate_cpabs_mappings(lgp, *, library_path, **kwargs):
70
+ """Run the complete canonical-parent traversal through the shared adapter.
71
+
72
+ Symmetry pruning is explicitly enabled with ``symmetry=True``. The method
73
+ changes the extension tree to unordered partial matchings; it does not add
74
+ a canonical deletion filter to fixed/adaptive source-row PABS. Exact twin
75
+ factors remain active even when quotient-group discovery is capped.
76
+ Raw output enumerates subgroup orbits and requires class deduplication.
77
+ """
78
+ from .core import enumerate_core_mappings
79
+
80
+ return enumerate_core_mappings(
81
+ lgp, library_path=library_path, backend="cpabs", **kwargs
82
+ )
83
+
84
+
85
+ def map_reaction_cpabs(reaction, *, library_path, **kwargs):
86
+ """Use the shared chemistry frontend with the explicit native variant."""
87
+ from .core import map_reaction_core
88
+
89
+ return map_reaction_core(
90
+ reaction, backend="cpabs", library_path=library_path, **kwargs
91
+ )
@@ -0,0 +1,29 @@
1
+ """
2
+ Sequential linear-assignment (SLAP) matching and LAP-based utilities.
3
+
4
+ LAP means linear assignment problem: match reactant atoms to product atoms
5
+ using a matrix of pair costs. SLAP combines successive LAP decisions with
6
+ WL graph-label refinement to construct heuristic graph mappings. It is the
7
+ default solver used by ``AAMapper.map_smiles``. The utility functions here
8
+ also serve exact solvers; importing a LAP helper does not select the SLAP
9
+ matching workflow.
10
+
11
+ Submodules
12
+ ----------
13
+ sequential
14
+ :class:`GraphMatcher`: iterative WL-label refinement with LAP branching.
15
+ lap
16
+ LAP utilities, :func:`chemical_distance`, :func:`dual_lap_lower_bound`,
17
+ and :func:`recover_mapping`.
18
+ """
19
+
20
+ from .sequential import GraphMatcher
21
+ from .lap import solve_lap, recover_mapping, chemical_distance, dual_lap_lower_bound
22
+
23
+ __all__ = [
24
+ "GraphMatcher",
25
+ "solve_lap",
26
+ "recover_mapping",
27
+ "chemical_distance",
28
+ "dual_lap_lower_bound",
29
+ ]