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,88 @@
1
+ """Dense and sparse matrix construction for :class:`SynCRN` matrix views.
2
+
3
+ Reaction networks are sparse, so both builders take ``(row, col, value)``
4
+ triples and only the sparse one ever needs the nonzeros; neither materializes an
5
+ ``n_species x n_reactions`` Python structure.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import Any, List, Tuple
11
+
12
+ import numpy as np
13
+
14
+
15
+ def _dense_from_entries(
16
+ entries: List[Tuple[int, int, Any]],
17
+ *,
18
+ shape: Tuple[int, int],
19
+ dtype: Any,
20
+ ) -> np.ndarray:
21
+ """Build a dense incidence matrix from ``(row, col, value)`` triples.
22
+
23
+ Repeated coordinates are summed, matching the sparse path.
24
+
25
+ :param entries:
26
+ Nonzero entries as ``(row, col, value)`` triples.
27
+ :type entries: List[Tuple[int, int, Any]]
28
+
29
+ :param shape:
30
+ Matrix shape as ``(n_rows, n_cols)``.
31
+ :type shape: Tuple[int, int]
32
+
33
+ :param dtype:
34
+ Element dtype.
35
+ :type dtype: Any
36
+
37
+ :return:
38
+ Dense matrix.
39
+ :rtype: numpy.ndarray
40
+ """
41
+ mat = np.zeros(shape, dtype=dtype)
42
+ for i, j, value in entries:
43
+ mat[i, j] += value
44
+ return mat
45
+
46
+
47
+ def _sparse_from_entries(
48
+ entries: List[Tuple[int, int, Any]],
49
+ *,
50
+ shape: Tuple[int, int],
51
+ dtype: Any,
52
+ ) -> Any:
53
+ """Build a CSR incidence matrix from ``(row, col, value)`` triples.
54
+
55
+ :param entries:
56
+ Nonzero entries as ``(row, col, value)`` triples.
57
+ :type entries: List[Tuple[int, int, Any]]
58
+
59
+ :param shape:
60
+ Matrix shape as ``(n_rows, n_cols)``.
61
+ :type shape: Tuple[int, int]
62
+
63
+ :param dtype:
64
+ Element dtype.
65
+ :type dtype: Any
66
+
67
+ :return:
68
+ Sparse matrix in CSR format.
69
+ :rtype: scipy.sparse.csr_array
70
+
71
+ :raises ImportError:
72
+ If SciPy is not installed.
73
+ """
74
+ try:
75
+ from scipy import sparse as sp
76
+ except ImportError as exc: # pragma: no cover - scipy is a core dependency
77
+ raise ImportError(
78
+ "sparse=True requires SciPy; install it or use sparse=False"
79
+ ) from exc
80
+
81
+ rows = [i for i, _, _ in entries]
82
+ cols = [j for _, j, _ in entries]
83
+ vals = [v for _, _, v in entries]
84
+ return sp.csr_array(
85
+ (np.asarray(vals, dtype=dtype), (rows, cols)),
86
+ shape=shape,
87
+ dtype=dtype,
88
+ )
@@ -0,0 +1,544 @@
1
+ """Reaction-string parsing and internal-id minting for :class:`SynCRN`.
2
+
3
+ These helpers back :meth:`SynCRN.from_reaction_strings`: they parse one side of
4
+ a reaction (``"2A + B"``) into a coefficient mapping, normalize whatever a
5
+ custom parser returns, and mint the internal ids under the policy named by
6
+ ``id_style``.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import Any, Callable, Dict, List, Mapping, Optional
12
+ import re
13
+
14
+ from .reaction import RXNSide, Reaction
15
+ from .rule import Rule
16
+ from .species import Species
17
+
18
+ _REACTION_SPLIT_RE = re.compile(r"\s*>>\s*")
19
+
20
+
21
+ #: Recognised internal-id policies shared by every :class:`SynCRN` constructor.
22
+ #:
23
+ #: ``"prefixed"`` keeps species, reactions and rules in three disjoint
24
+ #: namespaces (``s_1`` / ``r_1`` / ``rule_1``); ``"numeric"`` is the legacy
25
+ #: single-namespace scheme where species are ``1..n`` and reactions continue at
26
+ #: ``n+1``.
27
+ ID_STYLES = ("prefixed", "numeric")
28
+
29
+
30
+ def _default_parse_side_text(side_text: str) -> Dict[str, int]:
31
+ """Parse one reaction side into a ``species -> coefficient`` mapping.
32
+
33
+ Supported examples include plain species lists, integer stoichiometric
34
+ prefixes, and dot-separated species tokens.
35
+
36
+ Supported examples
37
+ ------------------
38
+ - ``A + B``
39
+ - ``2A + B``
40
+ - ``A.A``
41
+ - ``B.3C``
42
+ - ``∅``
43
+
44
+ :param side_text:
45
+ One side of a reaction string.
46
+ :type side_text: str
47
+
48
+ :return:
49
+ Mapping from species label to stoichiometric coefficient.
50
+ :rtype: Dict[str, int]
51
+
52
+ .. rubric:: Example
53
+
54
+ .. code-block:: python
55
+
56
+ _default_parse_side_text("2A + B")
57
+ # {"A": 2, "B": 1}
58
+ """
59
+ text = str(side_text).strip()
60
+ if text in {"", "∅", "0", "None", "null"}:
61
+ return {}
62
+
63
+ parts = re.split(r"\s*(?:\+|\.)\s*", text)
64
+ out: Dict[str, int] = {}
65
+
66
+ for part in parts:
67
+ token = part.strip()
68
+ if not token:
69
+ continue
70
+
71
+ m = re.match(r"^\s*(\d+)\s*\*?\s*(.+?)\s*$", token)
72
+ if m:
73
+ coeff = int(m.group(1))
74
+ species = m.group(2).strip()
75
+ else:
76
+ m2 = re.match(r"^\s*(\d+)([A-Za-z].*?)\s*$", token)
77
+ if m2:
78
+ coeff = int(m2.group(1))
79
+ species = m2.group(2).strip()
80
+ else:
81
+ coeff = 1
82
+ species = token
83
+
84
+ if species and coeff > 0:
85
+ out[species] = out.get(species, 0) + coeff
86
+
87
+ return out
88
+
89
+
90
+ def _coerce_side_counts(obj: Any) -> Dict[str, int]:
91
+ """Coerce a parsed side object into a plain dictionary.
92
+
93
+ This helper accepts plain mappings, objects exposing ``to_dict()``, and
94
+ RXNSide-like objects exposing ``items()``.
95
+
96
+ :param obj:
97
+ Parsed side object.
98
+ :type obj: Any
99
+
100
+ :return:
101
+ Mapping from species label to stoichiometric coefficient.
102
+ :rtype: Dict[str, int]
103
+
104
+ :raises TypeError:
105
+ If the object cannot be interpreted as a side-count mapping.
106
+
107
+ .. rubric:: Example
108
+
109
+ .. code-block:: python
110
+
111
+ _coerce_side_counts({"A": 2, "B": 1})
112
+ # {"A": 2, "B": 1}
113
+ """
114
+ if obj is None:
115
+ return {}
116
+
117
+ if isinstance(obj, Mapping):
118
+ return {str(k): int(v) for k, v in obj.items()}
119
+
120
+ if hasattr(obj, "to_dict"):
121
+ d = obj.to_dict()
122
+ return {str(k): int(v) for k, v in d.items()}
123
+
124
+ if hasattr(obj, "items"):
125
+ return {str(k): int(v) for k, v in obj.items()}
126
+
127
+ raise TypeError(
128
+ "Parsed side must be a mapping, or expose to_dict(), or expose items()."
129
+ )
130
+
131
+
132
+ def _normalize_side_counts(
133
+ counts: Any,
134
+ *,
135
+ rxn_index: int,
136
+ side_name: str,
137
+ strict: bool,
138
+ ) -> Dict[str, int]:
139
+ """Normalize a parsed reaction side into a validated label-to-coefficient mapping.
140
+
141
+ :param counts:
142
+ Parsed side object.
143
+ :type counts: Any
144
+
145
+ :param rxn_index:
146
+ Reaction index in the input list.
147
+ :type rxn_index: int
148
+
149
+ :param side_name:
150
+ Name of the side, typically ``"lhs"`` or ``"rhs"``.
151
+ :type side_name: str
152
+
153
+ :param strict:
154
+ Whether invalid labels or coefficients should raise an error.
155
+ :type strict: bool
156
+
157
+ :return:
158
+ Cleaned mapping from species label to coefficient.
159
+ :rtype: Dict[str, int]
160
+ """
161
+ raw = _coerce_side_counts(counts)
162
+ out: Dict[str, int] = {}
163
+
164
+ for sp, coeff in raw.items():
165
+ label = str(sp).strip()
166
+ try:
167
+ n = int(coeff)
168
+ except Exception as exc:
169
+ raise TypeError(
170
+ f"Reaction at index {rxn_index} has non-integer coefficient on "
171
+ f"{side_name}: {sp!r} -> {coeff!r}"
172
+ ) from exc
173
+
174
+ if not label:
175
+ if strict:
176
+ raise ValueError(
177
+ f"Reaction at index {rxn_index} has blank species label on {side_name}"
178
+ )
179
+ continue
180
+
181
+ if n <= 0:
182
+ if strict:
183
+ raise ValueError(
184
+ f"Reaction at index {rxn_index} has non-positive coefficient on "
185
+ f"{side_name}: {sp!r} -> {n}"
186
+ )
187
+ continue
188
+
189
+ out[label] = out.get(label, 0) + n
190
+
191
+ return out
192
+
193
+
194
+ def _parse_reaction_string_entry(
195
+ rxn_text: str,
196
+ *,
197
+ rxn_index: int,
198
+ rule_repr: Optional[str],
199
+ has_rules: bool,
200
+ parse_side: Callable[[str], Any],
201
+ strict: bool,
202
+ ) -> Dict[str, Any]:
203
+ """Parse one reaction string into normalized lhs/rhs count dictionaries.
204
+
205
+ :param rxn_text:
206
+ Raw reaction string such as ``"2A>>B+3C"``.
207
+ :type rxn_text: str
208
+
209
+ :param rxn_index:
210
+ Index of the reaction in the input list.
211
+ :type rxn_index: int
212
+
213
+ :param rule_repr:
214
+ Optional rule string paired with the reaction.
215
+ :type rule_repr: Optional[str]
216
+
217
+ :param has_rules:
218
+ Whether pairwise rules are being used.
219
+ :type has_rules: bool
220
+
221
+ :param parse_side:
222
+ Side parser function.
223
+ :type parse_side: Callable[[str], Any]
224
+
225
+ :param strict:
226
+ Whether malformed input should raise an error.
227
+ :type strict: bool
228
+
229
+ :return:
230
+ Parsed reaction record.
231
+ :rtype: Dict[str, Any]
232
+ """
233
+ text = str(rxn_text).strip()
234
+ pieces = _REACTION_SPLIT_RE.split(text, maxsplit=1)
235
+
236
+ if len(pieces) != 2:
237
+ raise ValueError(
238
+ f"Reaction string at index {rxn_index} must contain exactly one '>>': {rxn_text!r}"
239
+ )
240
+
241
+ lhs_text, rhs_text = pieces[0].strip(), pieces[1].strip()
242
+
243
+ lhs_counts = _normalize_side_counts(
244
+ parse_side(lhs_text),
245
+ rxn_index=rxn_index,
246
+ side_name="lhs",
247
+ strict=strict,
248
+ )
249
+ rhs_counts = _normalize_side_counts(
250
+ parse_side(rhs_text),
251
+ rxn_index=rxn_index,
252
+ side_name="rhs",
253
+ strict=strict,
254
+ )
255
+
256
+ if strict and not lhs_counts:
257
+ raise ValueError(f"Reaction at index {rxn_index} has empty lhs: {rxn_text!r}")
258
+ if strict and not rhs_counts:
259
+ raise ValueError(f"Reaction at index {rxn_index} has empty rhs: {rxn_text!r}")
260
+
261
+ return {
262
+ "rxn_text": text,
263
+ "lhs_counts": lhs_counts,
264
+ "rhs_counts": rhs_counts,
265
+ "rule_repr": rule_repr,
266
+ "rule_index": rxn_index if has_rules else None,
267
+ }
268
+
269
+
270
+ def _species_order_from_parsed_reactions(
271
+ parsed_rxns: List[Dict[str, Any]],
272
+ ) -> List[str]:
273
+ """Derive species order by first appearance in parsed reactions.
274
+
275
+ :param parsed_rxns:
276
+ Parsed reaction entries.
277
+ :type parsed_rxns: List[Dict[str, Any]]
278
+
279
+ :return:
280
+ Ordered species labels.
281
+ :rtype: List[str]
282
+ """
283
+ order: List[str] = []
284
+ seen = set()
285
+
286
+ for item in parsed_rxns:
287
+ for sp in list(item["lhs_counts"].keys()) + list(item["rhs_counts"].keys()):
288
+ if sp not in seen:
289
+ seen.add(sp)
290
+ order.append(sp)
291
+
292
+ return order
293
+
294
+
295
+ def _mint_reaction_string_ids(
296
+ *,
297
+ n_species: int,
298
+ n_reactions: int,
299
+ id_style: str,
300
+ species_prefix: str,
301
+ reaction_prefix: str,
302
+ rule_prefix: str,
303
+ ) -> Dict[str, List[Any]]:
304
+ """Mint internal ids and source node ids for reaction-string input.
305
+
306
+ Two policies are supported. ``"prefixed"`` matches
307
+ :meth:`SynCRN.from_digraph` — species, reactions and rules live in three
308
+ disjoint namespaces (``s_1``, ``r_1``, ``rule_1``), so a species id can
309
+ never be mistaken for a reaction id. ``"numeric"`` reproduces the legacy
310
+ scheme where species are ``1..n`` and reactions continue at ``n+1`` in one
311
+ shared numeric namespace.
312
+
313
+ :param n_species:
314
+ Number of species.
315
+ :type n_species: int
316
+
317
+ :param n_reactions:
318
+ Number of reactions.
319
+ :type n_reactions: int
320
+
321
+ :param id_style:
322
+ Either ``"prefixed"`` or ``"numeric"``.
323
+ :type id_style: str
324
+
325
+ :param species_prefix:
326
+ Prefix for generated species ids under ``"prefixed"``.
327
+ :type species_prefix: str
328
+
329
+ :param reaction_prefix:
330
+ Prefix for generated reaction ids under ``"prefixed"``.
331
+ :type reaction_prefix: str
332
+
333
+ :param rule_prefix:
334
+ Prefix for generated rule ids under ``"prefixed"``.
335
+ :type rule_prefix: str
336
+
337
+ :return:
338
+ Mapping with ``species_ids``, ``species_source_ids``, ``reaction_ids``,
339
+ ``reaction_source_ids`` and ``rule_ids``.
340
+ :rtype: Dict[str, List[Any]]
341
+
342
+ :raises ValueError:
343
+ If ``id_style`` is not a recognised policy.
344
+ """
345
+ if id_style not in ID_STYLES:
346
+ raise ValueError(f"id_style must be one of {sorted(ID_STYLES)}, got {id_style!r}")
347
+
348
+ if id_style == "numeric":
349
+ species_ids = [str(i) for i in range(1, n_species + 1)]
350
+ reaction_ids = [
351
+ str(i) for i in range(n_species + 1, n_species + n_reactions + 1)
352
+ ]
353
+ rule_ids = [str(i) for i in range(1, n_reactions + 1)]
354
+ return {
355
+ "species_ids": species_ids,
356
+ "species_source_ids": [int(s) for s in species_ids],
357
+ "reaction_ids": reaction_ids,
358
+ "reaction_source_ids": [int(r) for r in reaction_ids],
359
+ "rule_ids": rule_ids,
360
+ }
361
+
362
+ species_ids = [f"{species_prefix}{i}" for i in range(1, n_species + 1)]
363
+ reaction_ids = [f"{reaction_prefix}{i}" for i in range(1, n_reactions + 1)]
364
+ rule_ids = [f"{rule_prefix}{i}" for i in range(1, n_reactions + 1)]
365
+ return {
366
+ "species_ids": species_ids,
367
+ "species_source_ids": list(species_ids),
368
+ "reaction_ids": reaction_ids,
369
+ "reaction_source_ids": list(reaction_ids),
370
+ "rule_ids": rule_ids,
371
+ }
372
+
373
+
374
+ def _build_species_table_from_labels(
375
+ species_order: List[str],
376
+ *,
377
+ species_ids: List[str],
378
+ species_source_ids: List[Any],
379
+ ) -> Dict[str, Species]:
380
+ """Build the canonical species table from an ordered list of species labels.
381
+
382
+ :param species_order:
383
+ Species labels in canonical order.
384
+ :type species_order: List[str]
385
+
386
+ :param species_ids:
387
+ Internal species ids, aligned with ``species_order``.
388
+ :type species_ids: List[str]
389
+
390
+ :param species_source_ids:
391
+ Source node ids, aligned with ``species_order``.
392
+ :type species_source_ids: List[Any]
393
+
394
+ :return:
395
+ Species table keyed by canonical string ids.
396
+ :rtype: Dict[str, Species]
397
+ """
398
+ species: Dict[str, Species] = {}
399
+ for label, sid, source_id in zip(species_order, species_ids, species_source_ids):
400
+ species[sid] = Species(
401
+ id=sid,
402
+ source_node_id=source_id,
403
+ label=label,
404
+ smiles=None,
405
+ source_attrs={
406
+ "kind": "species",
407
+ "label": label,
408
+ },
409
+ metadata={},
410
+ )
411
+ return species
412
+
413
+
414
+ def _build_rules_table_from_reaction_strings(
415
+ parsed_rxns: List[Dict[str, Any]],
416
+ *,
417
+ rule_ids: List[str],
418
+ has_rules: bool,
419
+ ) -> Dict[str, Rule]:
420
+ """Build the abstract rules table for reaction-string input.
421
+
422
+ :param parsed_rxns:
423
+ Parsed reaction entries.
424
+ :type parsed_rxns: List[Dict[str, Any]]
425
+
426
+ :param rule_ids:
427
+ Internal rule ids, aligned with ``parsed_rxns``.
428
+ :type rule_ids: List[str]
429
+
430
+ :param has_rules:
431
+ Whether rules were supplied pairwise.
432
+ :type has_rules: bool
433
+
434
+ :return:
435
+ Rule table keyed by canonical rule ids.
436
+ :rtype: Dict[str, Rule]
437
+ """
438
+ if not has_rules:
439
+ return {}
440
+
441
+ rules_table: Dict[str, Rule] = {}
442
+ for item, rule_id in zip(parsed_rxns, rule_ids):
443
+ rule_index = item["rule_index"]
444
+ rule_repr = item["rule_repr"]
445
+ rules_table[rule_id] = Rule(
446
+ id=rule_id,
447
+ rule_index=rule_index,
448
+ rule_repr=rule_repr,
449
+ label=f"r{rule_index}",
450
+ metadata={},
451
+ )
452
+ return rules_table
453
+
454
+
455
+ def _build_reactions_from_parsed_strings(
456
+ parsed_rxns: List[Dict[str, Any]],
457
+ *,
458
+ label_to_sid: Dict[str, str],
459
+ reaction_ids: List[str],
460
+ reaction_source_ids: List[Any],
461
+ rule_ids: List[str],
462
+ has_rules: bool,
463
+ ) -> Dict[str, Reaction]:
464
+ """Build canonical Reaction objects from parsed reaction-string entries.
465
+
466
+ :param parsed_rxns:
467
+ Parsed reaction entries.
468
+ :type parsed_rxns: List[Dict[str, Any]]
469
+
470
+ :param label_to_sid:
471
+ Mapping from species label to canonical species id.
472
+ :type label_to_sid: Dict[str, str]
473
+
474
+ :param reaction_ids:
475
+ Internal reaction ids, aligned with ``parsed_rxns``.
476
+ :type reaction_ids: List[str]
477
+
478
+ :param reaction_source_ids:
479
+ Source node ids, aligned with ``parsed_rxns``.
480
+ :type reaction_source_ids: List[Any]
481
+
482
+ :param rule_ids:
483
+ Internal rule ids, aligned with ``parsed_rxns``.
484
+ :type rule_ids: List[str]
485
+
486
+ :param has_rules:
487
+ Whether rules were supplied pairwise.
488
+ :type has_rules: bool
489
+
490
+ :return:
491
+ Reaction table keyed by canonical reaction ids.
492
+ :rtype: Dict[str, Reaction]
493
+ """
494
+ reactions: Dict[str, Reaction] = {}
495
+
496
+ for i, item in enumerate(parsed_rxns):
497
+ rid = reaction_ids[i]
498
+ rid_source = reaction_source_ids[i]
499
+
500
+ rule_id: Optional[str] = None
501
+ rule_index = item["rule_index"]
502
+ rule_repr = item["rule_repr"]
503
+
504
+ if has_rules:
505
+ rule_id = rule_ids[i]
506
+
507
+ lhs = RXNSide(
508
+ {label_to_sid[sp]: coeff for sp, coeff in item["lhs_counts"].items()}
509
+ )
510
+ rhs = RXNSide(
511
+ {label_to_sid[sp]: coeff for sp, coeff in item["rhs_counts"].items()}
512
+ )
513
+
514
+ reactions[rid] = Reaction(
515
+ id=rid,
516
+ source_node_id=rid_source,
517
+ source_kind="rule",
518
+ lhs=lhs,
519
+ rhs=rhs,
520
+ label=rule_repr if has_rules and rule_repr is not None else rid,
521
+ step=None,
522
+ rule_index=rule_index,
523
+ app_index=None,
524
+ rule_repr=rule_repr,
525
+ rule_id=rule_id,
526
+ source_attrs={
527
+ "kind": "rule",
528
+ "label": rid,
529
+ "rxn_repr": item["rxn_text"],
530
+ "rule_index": rule_index,
531
+ "rule_repr": rule_repr,
532
+ },
533
+ metadata={},
534
+ reactant_edge_attrs={
535
+ label_to_sid[sp]: {"role": "reactant", "stoich": coeff}
536
+ for sp, coeff in item["lhs_counts"].items()
537
+ },
538
+ product_edge_attrs={
539
+ label_to_sid[sp]: {"role": "product", "stoich": coeff}
540
+ for sp, coeff in item["rhs_counts"].items()
541
+ },
542
+ )
543
+
544
+ return reactions