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,593 @@
1
+ """Optional C++ exact candidate search; compilation is explicit."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import ctypes
6
+ import math
7
+ import time
8
+ from collections import Counter
9
+ from itertools import pairwise
10
+ from numbers import Real
11
+ from pathlib import Path
12
+
13
+ import numpy as np
14
+
15
+ from ....graph.automorphism import bounded_automorphism_permutations
16
+ from ...slap.lap import _adjacency_and_elements
17
+ from ..distance_search.bounds import reaction_center_order
18
+ from ..symmetry import permutation_group_order
19
+
20
+
21
+ class NativeEnumerationStop(RuntimeError):
22
+ """Stop a callback on a shared budget while retaining native counters."""
23
+
24
+
25
+ class _PreparedNativeCandidates(tuple):
26
+ """Retain legacy tuple unpacking and side-group discovery metadata."""
27
+
28
+
29
+ def _validate_native_atom_types(reactant_elements, product_elements):
30
+ """Require mapping compatibility to agree with typed ITS atom colors.
31
+
32
+ Python considers True, 1 and 1.0 equal. Full ITS certificates distinguish
33
+ their types, while compatibility and type blocks use ordinary equality.
34
+ Mixing those meanings invalidates the double-orbit identification.
35
+ Reject ambiguity instead of changing the caller's mapping problem.
36
+ """
37
+ from ....reporting.spectrum import _typed
38
+
39
+ tokens = {}
40
+ for value in (*reactant_elements, *product_elements):
41
+ token = _typed(value)
42
+ if tokens.setdefault(value, token) != token:
43
+ raise ValueError(
44
+ "native atom-label equality must agree with exact typed colors; "
45
+ "normalize equal labels to one type and representation"
46
+ )
47
+
48
+
49
+ def prepare_native_candidates(
50
+ lgp,
51
+ target,
52
+ *,
53
+ library_path,
54
+ initial_mapping=None,
55
+ node_properties=("hcounts", "charges"),
56
+ binary=False,
57
+ symmetry=True,
58
+ allow_partial_symmetry=False,
59
+ ):
60
+ a, at = _adjacency_and_elements(lgp[0], binary)
61
+ b, bt = _adjacency_and_elements(lgp[1], binary)
62
+ n = len(at)
63
+ if not 1 <= n <= 256 or a.shape != b.shape or Counter(at) != Counter(bt):
64
+ raise ValueError(
65
+ "native candidates require compatible graphs with 1..256 atoms"
66
+ )
67
+ _validate_native_atom_types(at, bt)
68
+ if any(
69
+ not np.isfinite(x).all()
70
+ or not np.array_equal(x, x.T)
71
+ or np.any(np.diag(x))
72
+ or np.max(np.abs(x), initial=0) > 512
73
+ or not np.equal(x * 2, np.rint(x * 2)).all()
74
+ for x in (a, b)
75
+ ):
76
+ raise ValueError(
77
+ "native candidates require symmetric half-integer matrices with zero diagonal"
78
+ )
79
+ if (
80
+ not math.isfinite(target)
81
+ or target < 0
82
+ or target > 250000
83
+ or target * 4 != round(target * 4)
84
+ ):
85
+ raise ValueError("native candidates require an exact quarter-unit target")
86
+ if initial_mapping is not None and (
87
+ sorted(initial_mapping) != list(range(n))
88
+ or any(at[i] != bt[j] for i, j in enumerate(initial_mapping))
89
+ ):
90
+ raise ValueError("seed must be an atom-compatible permutation")
91
+ if symmetry:
92
+ rg, rc = bounded_automorphism_permutations(
93
+ lgp[0],
94
+ binary=binary,
95
+ node_properties=node_properties,
96
+ limit=256,
97
+ timeout_seconds=0.25,
98
+ max_search_nodes=10000,
99
+ )
100
+ pg, pc = bounded_automorphism_permutations(
101
+ lgp[1],
102
+ binary=binary,
103
+ node_properties=node_properties,
104
+ limit=256,
105
+ timeout_seconds=0.25,
106
+ max_search_nodes=10000,
107
+ )
108
+ if allow_partial_symmetry:
109
+ # Representative search needs verified generators, not their exact
110
+ # orders. Schreier cardinality calculations can dominate a whole
111
+ # deadline for large interchangeable dummy/H groups. Unknown
112
+ # cardinalities remain explicit instead of delaying safe pruning.
113
+ ro = 1 if len(rg) == 1 else None
114
+ po = 1 if len(pg) == 1 else None
115
+ else:
116
+ ro, po = permutation_group_order(rg[1:]), permutation_group_order(pg[1:])
117
+ if not allow_partial_symmetry and (
118
+ not rc or not pc or ro is None or po is None
119
+ ):
120
+ raise ValueError("native weighted candidates require complete side groups")
121
+ else:
122
+ rg = pg = [tuple(range(n))]
123
+ ro = po = 1
124
+ rc = pc = True
125
+ order = reaction_center_order(a, b, at, dict(Counter(at)), initial_mapping)
126
+ pred = np.zeros((n, n), dtype=np.int32)
127
+ types = {value: i for i, value in enumerate(dict.fromkeys(at))}
128
+ arrays = [
129
+ np.ascontiguousarray(x, dtype=np.int32)
130
+ for x in (
131
+ a * 2,
132
+ b * 2,
133
+ [types[x] for x in at],
134
+ [types[x] for x in bt],
135
+ order,
136
+ pred,
137
+ pg[1:],
138
+ rg[1:],
139
+ )
140
+ ]
141
+ levels = len(np.unique(np.concatenate((arrays[0].ravel(), arrays[1].ravel())))) - 1
142
+ if levels > 15:
143
+ raise ValueError("native candidates support at most 16 bond levels")
144
+ library = ctypes.CDLL(str(Path(library_path).resolve()))
145
+ if library.synkit_distance_abi() != 3:
146
+ raise ValueError("unsupported native distance ABI")
147
+ prepared = _PreparedNativeCandidates(
148
+ (n, len(types), levels, arrays, rg, pg, ro, po, library)
149
+ )
150
+ prepared.symmetry_search_complete = rc and pc
151
+ return prepared
152
+
153
+
154
+ def enumerate_native_candidates( # noqa: C901
155
+ lgp,
156
+ target,
157
+ *,
158
+ library_path,
159
+ time_limit_seconds=60.0,
160
+ max_mappings=100000,
161
+ initial_mapping=None,
162
+ node_properties=("hcounts", "charges"),
163
+ callback=None,
164
+ shard_index=0,
165
+ shards=1,
166
+ prefix=(),
167
+ prefixes=None,
168
+ slice_nodes=None,
169
+ _prepared=None,
170
+ ):
171
+ if (
172
+ not isinstance(shards, int)
173
+ or not isinstance(shard_index, int)
174
+ or not 0 <= shard_index < shards
175
+ ):
176
+ raise ValueError("invalid native shard")
177
+ if slice_nodes is not None and (
178
+ isinstance(slice_nodes, bool)
179
+ or not isinstance(slice_nodes, int)
180
+ or not 0 < slice_nodes < (1 << 63)
181
+ or shards != 1
182
+ ):
183
+ raise ValueError(
184
+ "frontier slices require a positive int64 node budget and one shard"
185
+ )
186
+ if prefix and slice_nodes is None:
187
+ raise ValueError("a prefix requires frontier mode")
188
+ started = time.perf_counter()
189
+ if not math.isfinite(time_limit_seconds) or time_limit_seconds < 0:
190
+ raise ValueError("time limit must be finite and nonnegative")
191
+ if max_mappings is not None and (
192
+ isinstance(max_mappings, bool)
193
+ or not isinstance(max_mappings, int)
194
+ or max_mappings < 1
195
+ ):
196
+ raise ValueError("mapping limit must be positive or None")
197
+ if _prepared is None:
198
+ _prepared = prepare_native_candidates(
199
+ lgp,
200
+ target,
201
+ library_path=library_path,
202
+ initial_mapping=initial_mapping,
203
+ node_properties=node_properties,
204
+ )
205
+ n, type_count, levels, arrays, rg, pg, ro, po, library = _prepared
206
+ if (
207
+ len(prefix) > n
208
+ or len(set(prefix)) != len(prefix)
209
+ or any(
210
+ isinstance(v, bool) or not isinstance(v, int) or not 0 <= v < n
211
+ for v in prefix
212
+ )
213
+ ):
214
+ raise ValueError("invalid frontier prefix")
215
+ if prefixes is not None:
216
+ if prefix or slice_nodes is None or not 1 <= len(prefixes) <= 16384:
217
+ raise ValueError(
218
+ "batched prefixes require frontier mode and no single prefix"
219
+ )
220
+ if any(
221
+ len(path) > n
222
+ or len(set(path)) != len(path)
223
+ or any(
224
+ isinstance(v, bool) or not isinstance(v, int) or not 0 <= v < n
225
+ for v in path
226
+ )
227
+ for path in prefixes
228
+ ):
229
+ raise ValueError("invalid batched frontier prefix")
230
+ ordered = sorted(tuple(path) for path in prefixes)
231
+ if any(right[: len(left)] == left for left, right in pairwise(ordered)):
232
+ raise ValueError("frontier prefixes must be disjoint")
233
+ pointer = ctypes.POINTER(ctypes.c_int32)
234
+ callback_type = ctypes.CFUNCTYPE(ctypes.c_int, pointer, ctypes.c_void_p)
235
+ errors = []
236
+ collected = []
237
+
238
+ def receive(mapping, userdata):
239
+ try:
240
+ value = tuple(mapping[:n])
241
+ if callback is None:
242
+ collected.append(value)
243
+ else:
244
+ callback(value, float(target))
245
+ return 0
246
+ except (
247
+ BaseException
248
+ ) as error: # noqa: BLE001 -- exceptions cannot cross the C callback ABI
249
+ errors.append(error)
250
+ return 1
251
+
252
+ bridge = callback_type(receive)
253
+ pending = []
254
+ frontier_type = ctypes.CFUNCTYPE(
255
+ ctypes.c_int, pointer, ctypes.c_int, ctypes.c_void_p
256
+ )
257
+
258
+ def emit_frontier(values, length, userdata):
259
+ try:
260
+ pending.append(tuple(values[i] for i in range(length)))
261
+ return 0
262
+ except BaseException as error: # noqa: BLE001 -- protect the C callback ABI
263
+ errors.append(error)
264
+ return 1
265
+
266
+ frontier_bridge = frontier_type(emit_frontier)
267
+ prefix_array = np.ascontiguousarray(prefix, dtype=np.int32)
268
+ function = (
269
+ library.synkit_distance_frontier_batch
270
+ if prefixes is not None
271
+ else (
272
+ library.synkit_distance_candidates
273
+ if slice_nodes is None
274
+ else library.synkit_distance_frontier
275
+ )
276
+ )
277
+ function.argtypes = (
278
+ [ctypes.c_int] * 4
279
+ + [ctypes.c_double, ctypes.c_int64]
280
+ + [pointer] * 7
281
+ + [
282
+ ctypes.c_int,
283
+ pointer,
284
+ ctypes.c_int,
285
+ ctypes.c_int,
286
+ ctypes.c_int,
287
+ callback_type,
288
+ ctypes.c_void_p,
289
+ ctypes.POINTER(ctypes.c_int64),
290
+ ]
291
+ )
292
+ extra = []
293
+ if prefixes is not None:
294
+ prefix_array = np.ascontiguousarray(
295
+ [v for path in prefixes for v in path], dtype=np.int32
296
+ )
297
+ offsets = np.ascontiguousarray(
298
+ [0, *np.cumsum([len(path) for path in prefixes])], dtype=np.int32
299
+ )
300
+ function.argtypes += [
301
+ pointer,
302
+ pointer,
303
+ ctypes.c_int,
304
+ ctypes.c_int64,
305
+ frontier_type,
306
+ ]
307
+ extra = [
308
+ prefix_array.ctypes.data_as(pointer),
309
+ offsets.ctypes.data_as(pointer),
310
+ len(prefixes),
311
+ slice_nodes,
312
+ frontier_bridge,
313
+ ]
314
+ elif slice_nodes is not None:
315
+ function.argtypes += [pointer, ctypes.c_int, ctypes.c_int64, frontier_type]
316
+ extra = [
317
+ prefix_array.ctypes.data_as(pointer),
318
+ len(prefix),
319
+ slice_nodes,
320
+ frontier_bridge,
321
+ ]
322
+ function.restype = ctypes.c_int
323
+ stats = (ctypes.c_int64 * 6)()
324
+ status = function(
325
+ n,
326
+ type_count,
327
+ levels,
328
+ round(target * 4),
329
+ max(0, time_limit_seconds - (time.perf_counter() - started)),
330
+ -1 if max_mappings is None else max_mappings,
331
+ *[x.ctypes.data_as(pointer) for x in arrays[:7]],
332
+ len(pg) - 1,
333
+ arrays[7].ctypes.data_as(pointer),
334
+ len(rg) - 1,
335
+ shard_index,
336
+ shards,
337
+ bridge,
338
+ None,
339
+ stats,
340
+ *extra,
341
+ )
342
+ if errors and not isinstance(errors[0], NativeEnumerationStop):
343
+ raise errors[0]
344
+ if status < 0:
345
+ raise RuntimeError(f"native distance kernel failed ({status})")
346
+ return {
347
+ "complete": status == 0 and not pending,
348
+ "frontier": pending,
349
+ "reason": (
350
+ str(errors[0])
351
+ if errors
352
+ else {
353
+ 0: "work_slice" if pending else None,
354
+ 1: "time_limit",
355
+ 2: "mapping_limit",
356
+ 3: "callback_abort",
357
+ }[status]
358
+ ),
359
+ "candidate_count": stats[2],
360
+ "visited_nodes": stats[0],
361
+ "visited_leaves": stats[1],
362
+ "prefix_replay_nodes": stats[4] if prefixes is not None else None,
363
+ "new_search_nodes": stats[5] if prefixes is not None else None,
364
+ "pruned": stats[3],
365
+ "mappings": collected,
366
+ "reactant_generators": rg[1:],
367
+ "reactant_group_order": ro,
368
+ "product_group_order": po,
369
+ "elapsed_seconds": time.perf_counter() - started,
370
+ }
371
+
372
+
373
+ def _objective_search_function(library, name):
374
+ """Require an explicitly rebuilt library for additive search entry points."""
375
+ try:
376
+ return getattr(library, name)
377
+ except AttributeError as error:
378
+ raise ValueError(
379
+ "Native library lacks minimum/range search; rebuild it with build_native"
380
+ ) from error
381
+
382
+
383
+ def _validate_search_seconds(seconds):
384
+ if (
385
+ isinstance(seconds, bool)
386
+ or not isinstance(seconds, Real)
387
+ or not math.isfinite(seconds)
388
+ or seconds < 0
389
+ ):
390
+ raise ValueError("time limit must be finite and nonnegative")
391
+
392
+
393
+ def minimize_native_candidates(
394
+ lgp,
395
+ *,
396
+ library_path,
397
+ initial_mapping,
398
+ time_limit_seconds=60.0,
399
+ binary=False,
400
+ symmetry=True,
401
+ node_properties=("hcounts", "charges"),
402
+ _prepared=None,
403
+ ):
404
+ """Prove one exact native minimum without probing successive cost shells.
405
+
406
+ An interrupted run exposes its feasible incumbent separately and never
407
+ publishes it as ``minimum_cost``. Enumeration of the proved minimum is a
408
+ separate pass so that all optimal classes remain searchable.
409
+ """
410
+ started = time.perf_counter()
411
+ _validate_search_seconds(time_limit_seconds)
412
+ if _prepared is None:
413
+ _prepared = prepare_native_candidates(
414
+ lgp,
415
+ 0,
416
+ library_path=library_path,
417
+ initial_mapping=initial_mapping,
418
+ binary=binary,
419
+ symmetry=symmetry,
420
+ node_properties=node_properties,
421
+ )
422
+ n, type_count, levels, arrays, rg, pg, ro, po, library = _prepared
423
+ if (
424
+ len(initial_mapping) != n
425
+ or sorted(initial_mapping) != list(range(n))
426
+ or any(arrays[2][i] != arrays[3][j] for i, j in enumerate(initial_mapping))
427
+ ):
428
+ raise ValueError("seed must be an atom-compatible permutation")
429
+ pointer = ctypes.POINTER(ctypes.c_int32)
430
+ function = _objective_search_function(library, "synkit_distance_minimum")
431
+ function.argtypes = (
432
+ [ctypes.c_int] * 3
433
+ + [ctypes.c_double]
434
+ + [pointer] * 7
435
+ + [ctypes.c_int, pointer, ctypes.c_int]
436
+ + [pointer] * 3
437
+ + [ctypes.POINTER(ctypes.c_int64)]
438
+ )
439
+ function.restype = ctypes.c_int
440
+ seed = np.ascontiguousarray(initial_mapping, dtype=np.int32)
441
+ witness = np.empty(n, dtype=np.int32)
442
+ cost = ctypes.c_int32()
443
+ stats = (ctypes.c_int64 * 6)()
444
+ status = function(
445
+ n,
446
+ type_count,
447
+ levels,
448
+ max(0, time_limit_seconds - (time.perf_counter() - started)),
449
+ *[array.ctypes.data_as(pointer) for array in arrays[:7]],
450
+ len(pg) - 1,
451
+ arrays[7].ctypes.data_as(pointer),
452
+ len(rg) - 1,
453
+ seed.ctypes.data_as(pointer),
454
+ witness.ctypes.data_as(pointer),
455
+ ctypes.byref(cost),
456
+ stats,
457
+ )
458
+ if status < 0:
459
+ raise RuntimeError(f"native minimum kernel failed ({status})")
460
+ if status not in (0, 1):
461
+ raise RuntimeError(f"unexpected native minimum status ({status})")
462
+ return {
463
+ "complete": status == 0,
464
+ "reason": None if status == 0 else "time_limit",
465
+ "minimum_cost": cost.value / 4 if status == 0 else None,
466
+ "incumbent_cost": cost.value / 4,
467
+ "mapping": tuple(int(image) for image in witness),
468
+ "visited_nodes": stats[0],
469
+ "visited_leaves": stats[1],
470
+ "improvements": stats[2],
471
+ "pruned": stats[3],
472
+ "reactant_group_order": ro,
473
+ "product_group_order": po,
474
+ "elapsed_seconds": time.perf_counter() - started,
475
+ }
476
+
477
+
478
+ def enumerate_native_range(
479
+ lgp,
480
+ lower,
481
+ upper,
482
+ *,
483
+ library_path,
484
+ time_limit_seconds=60.0,
485
+ max_mappings=100000,
486
+ initial_mapping=None,
487
+ binary=False,
488
+ symmetry=True,
489
+ node_properties=("hcounts", "charges"),
490
+ callback=None,
491
+ _prepared=None,
492
+ ):
493
+ """Enumerate one closed native cost interval with actual per-mapping costs."""
494
+ started = time.perf_counter()
495
+ _validate_search_seconds(time_limit_seconds)
496
+ if any(
497
+ isinstance(value, bool)
498
+ or not isinstance(value, Real)
499
+ or not math.isfinite(value)
500
+ or value < 0
501
+ or value > 250000
502
+ or value * 4 != round(value * 4)
503
+ for value in (lower, upper)
504
+ ) or lower > upper:
505
+ raise ValueError("native range requires ordered nonnegative quarter-unit limits")
506
+ if max_mappings is not None and (
507
+ isinstance(max_mappings, bool)
508
+ or not isinstance(max_mappings, int)
509
+ or max_mappings < 1
510
+ ):
511
+ raise ValueError("mapping limit must be positive or None")
512
+ if callback is not None and not callable(callback):
513
+ raise TypeError("callback must be callable")
514
+ if _prepared is None:
515
+ _prepared = prepare_native_candidates(
516
+ lgp,
517
+ upper,
518
+ library_path=library_path,
519
+ initial_mapping=initial_mapping,
520
+ binary=binary,
521
+ symmetry=symmetry,
522
+ node_properties=node_properties,
523
+ )
524
+ n, type_count, levels, arrays, rg, pg, ro, po, library = _prepared
525
+ pointer = ctypes.POINTER(ctypes.c_int32)
526
+ callback_type = ctypes.CFUNCTYPE(
527
+ ctypes.c_int, pointer, ctypes.c_int, ctypes.c_void_p
528
+ )
529
+ errors, mappings, distances = [], [], []
530
+
531
+ def receive(mapping, cost, userdata):
532
+ try:
533
+ value = tuple(mapping[:n])
534
+ distance = cost / 4
535
+ if callback is None:
536
+ mappings.append(value)
537
+ distances.append(distance)
538
+ else:
539
+ callback(value, distance)
540
+ return 0
541
+ except BaseException as error: # noqa: BLE001 -- protect the C callback ABI
542
+ errors.append(error)
543
+ return 1
544
+
545
+ bridge = callback_type(receive)
546
+ function = _objective_search_function(library, "synkit_distance_range")
547
+ function.argtypes = (
548
+ [ctypes.c_int] * 5
549
+ + [ctypes.c_double, ctypes.c_int64]
550
+ + [pointer] * 7
551
+ + [ctypes.c_int, pointer, ctypes.c_int]
552
+ + [callback_type, ctypes.c_void_p, ctypes.POINTER(ctypes.c_int64)]
553
+ )
554
+ function.restype = ctypes.c_int
555
+ stats = (ctypes.c_int64 * 6)()
556
+ status = function(
557
+ n,
558
+ type_count,
559
+ levels,
560
+ round(lower * 4),
561
+ round(upper * 4),
562
+ max(0, time_limit_seconds - (time.perf_counter() - started)),
563
+ -1 if max_mappings is None else max_mappings,
564
+ *[array.ctypes.data_as(pointer) for array in arrays[:7]],
565
+ len(pg) - 1,
566
+ arrays[7].ctypes.data_as(pointer),
567
+ len(rg) - 1,
568
+ bridge,
569
+ None,
570
+ stats,
571
+ )
572
+ if errors and not isinstance(errors[0], NativeEnumerationStop):
573
+ raise errors[0]
574
+ if status < 0:
575
+ raise RuntimeError(f"native range kernel failed ({status})")
576
+ return {
577
+ "complete": status == 0,
578
+ "reason": (
579
+ str(errors[0])
580
+ if errors
581
+ else {0: None, 1: "time_limit", 2: "mapping_limit", 3: "callback_abort"}[status]
582
+ ),
583
+ "candidate_count": stats[2],
584
+ "visited_nodes": stats[0],
585
+ "visited_leaves": stats[1],
586
+ "pruned": stats[3],
587
+ "mappings": mappings,
588
+ "distances": distances,
589
+ "reactant_generators": rg[1:],
590
+ "reactant_group_order": ro,
591
+ "product_group_order": po,
592
+ "elapsed_seconds": time.perf_counter() - started,
593
+ }