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,218 @@
1
+ """rule_matcher.py
2
+ =================
3
+ Immutable matcher for applying a reaction‑template rule to a reaction SMILES.
4
+
5
+ Key features
6
+ ------------
7
+ * **Standardization** – canonicalize the input RSMI.
8
+ * **Balanced vs. partial matching** – uses stoichiometric balance checks.
9
+ * **SMARTS extraction** – extracts SMARTS that reproduce the RSMI.
10
+ * **Introspective API** – stores the match on init; exposes `get_result()`, `help()`,
11
+ `__str__()`, and `__repr__()` for inspection.
12
+
13
+ Quick start
14
+ -----------
15
+ >>> from synkit.Graph.rule_matcher import RuleMatcher
16
+ >>> matcher = RuleMatcher('CCO>>CC=O', some_rule_graph)
17
+ >>> smarts, rule = matcher.get_result()
18
+ """
19
+
20
+ from typing import List, Optional, Tuple, Union
21
+
22
+ import networkx as nx
23
+ from synkit.IO import rsmi_to_graph, rsmi_to_its
24
+ from synkit.Chem.Reaction.standardize import Standardize
25
+ from synkit.Chem.Reaction.balance_check import BalanceReactionCheck
26
+ from synkit.Synthesis.Reactor import SynReactor
27
+
28
+ __all__ = ["RuleMatcher"]
29
+
30
+
31
+ class RuleMatcher:
32
+ """Match a reaction SMILES against a transformation‑rule graph and extract
33
+ the SMARTS pattern that reproduces the reaction.
34
+
35
+ On initialization, the matcher standardizes the RSMI, builds reactant/product
36
+ graphs, checks balance, and finds the matching SMARTS (stored in `self.result`).
37
+
38
+ :param rsmi: Reaction SMILES in 'reactant>>product' format.
39
+ :type rsmi: str
40
+ :param rule: A NetworkX graph encoding the reaction template.
41
+ :type rule: nx.Graph
42
+
43
+ :ivar std: SMILES standardizer instance.
44
+ :vartype std: Standardize
45
+ :ivar rsmi: Standardized reaction SMILES.
46
+ :vartype rsmi: str
47
+ :ivar r_graph: Reactant graph extracted from `rsmi`.
48
+ :vartype r_graph: nx.Graph
49
+ :ivar p_graph: Product graph extracted from `rsmi`.
50
+ :vartype p_graph: nx.Graph
51
+ :ivar balanced: True if reaction passes stoichiometric balance check.
52
+ :vartype balanced: bool
53
+ :ivar result: The matching SMARTS and rule graph tuple.
54
+ :vartype result: Tuple[str, nx.Graph]
55
+ """
56
+
57
+ def __init__(
58
+ self,
59
+ rsmi: str,
60
+ rule: Union[str, nx.Graph],
61
+ explicit_h: bool = True,
62
+ electron_diagnostics: bool = False,
63
+ ) -> None:
64
+ """Initialize the matcher by standardizing the RSMI, building graphs,
65
+ checking balance, and computing the match.
66
+
67
+ :param rsmi: Reaction SMILES in 'reactant>>product' format.
68
+ :type rsmi: str
69
+ :param rule: Transformation-rule graph.
70
+ :type rule: nx.Graph
71
+ :raises ValueError: If no SMARTS reproduces the RSMI under the
72
+ given rule.
73
+ """
74
+ self.std = Standardize()
75
+ self.rsmi = self.std.fit(rsmi)
76
+ self.r_graph, self.p_graph = rsmi_to_graph(self.rsmi, drop_non_aam=False)
77
+ if isinstance(rule, str):
78
+ rule = rsmi_to_its(rule, core=True)
79
+ self.rule = rule
80
+ self.explicit_h = explicit_h
81
+ self.electron_diagnostics = electron_diagnostics
82
+ self._diagnostics: list[dict] = []
83
+ self.balanced = BalanceReactionCheck(n_jobs=1).rsmi_balance_check(self.rsmi)
84
+
85
+ # Compute and store the match result
86
+ if self.balanced:
87
+ match = self._match_valid()
88
+ else:
89
+ match = self._match_reverse()
90
+
91
+ if match is None:
92
+ raise ValueError(
93
+ f"No matching SMARTS for RSMI '{self.rsmi}' with given rule"
94
+ )
95
+ self.result = match
96
+
97
+ def get_result(self) -> Tuple[str, nx.Graph]:
98
+ """Return the SMARTS and rule graph found during initialization.
99
+
100
+ :return: A tuple (smarts, rule_graph).
101
+ :rtype: tuple[str, nx.Graph]
102
+ """
103
+ return self.result
104
+
105
+ def _match_valid(self) -> Optional[Tuple[str, nx.Graph]]:
106
+ """Attempt a direct (balanced) match of the rule.
107
+
108
+ :return: (smarts, rule) if direct match succeeds; otherwise
109
+ None.
110
+ :rtype: Optional[tuple[str, nx.Graph]]
111
+ """
112
+ reactor = SynReactor(
113
+ substrate=self.r_graph,
114
+ template=self.rule,
115
+ electron_diagnostics=self.electron_diagnostics,
116
+ )
117
+ for smarts in reactor.smarts_list:
118
+ if self.std.fit(smarts) == self.rsmi:
119
+ self._diagnostics = reactor.diagnostics
120
+ return smarts, self.rule
121
+ return None
122
+
123
+ def _match_reverse(self) -> Optional[Tuple[str, nx.Graph]]:
124
+ """Attempt a reverse‑balance (partial) match for unbalanced reactions.
125
+
126
+ First tries matching on product fragments, then on reactant
127
+ fragments with the template inverted.
128
+
129
+ :return: (smarts, rule) if a partial match is found; otherwise
130
+ None.
131
+ :rtype: Optional[tuple[str, nx.Graph]]
132
+ """
133
+ # Product‑side fragments
134
+ reactor = SynReactor(
135
+ substrate=self.r_graph,
136
+ template=self.rule,
137
+ electron_diagnostics=self.electron_diagnostics,
138
+ )
139
+ for smarts in reactor.smarts_list:
140
+ std_r = self.std.fit(smarts)
141
+ if self.all_in(
142
+ self.rsmi.split(">>")[1].split("."), std_r.split(">>")[1].split(".")
143
+ ):
144
+ self._diagnostics = reactor.diagnostics
145
+ return smarts, self.rule
146
+
147
+ # Reactant‑side with inverted template
148
+ reactor = SynReactor(
149
+ substrate=self.p_graph,
150
+ template=self.rule,
151
+ invert=True,
152
+ explicit_h=self.explicit_h,
153
+ electron_diagnostics=self.electron_diagnostics,
154
+ )
155
+ for smarts in reactor.smarts_list:
156
+ std_r = self.std.fit(smarts)
157
+ if self.all_in(
158
+ self.rsmi.split(">>")[0].split("."), std_r.split(">>")[0].split(".")
159
+ ):
160
+ self._diagnostics = reactor.diagnostics
161
+ return smarts, self.rule
162
+
163
+ return None
164
+
165
+ @staticmethod
166
+ def all_in(a: List[str], b: List[str]) -> bool:
167
+ """Check if every element of list `a` appears in list `b`.
168
+
169
+ :param a: List of elements to test for membership.
170
+ :type a: list[str]
171
+ :param b: List in which to test membership.
172
+ :type b: list[str]
173
+ :return: True if set(a) is a subset of set(b); otherwise False.
174
+ :rtype: bool
175
+ """
176
+ return set(a).issubset(b)
177
+
178
+ @property
179
+ def diagnostics(self) -> list[dict]:
180
+ """Electron diagnostics from the reactor that produced the match."""
181
+ return list(self._diagnostics)
182
+
183
+ def help(self) -> None:
184
+ """Print internal state and candidate SMARTS patterns for debugging.
185
+
186
+ :return: None
187
+ :rtype: NoneType
188
+ """
189
+ print(f"RuleMatcher for RSMI: {self.rsmi!r}")
190
+ print(f"Balanced: {self.balanced}")
191
+ print("Candidate SMARTS patterns:")
192
+ reactor = SynReactor(substrate=self.r_graph, template=self.rule)
193
+ for smarts in reactor.smarts_list:
194
+ print(" ", smarts)
195
+
196
+ def __str__(self) -> str:
197
+ """Short string showing the RSMI and balance status.
198
+
199
+ :return: Human‑readable summary.
200
+ :rtype: str
201
+ """
202
+ status = "balanced" if self.balanced else "unbalanced"
203
+ return f"<RuleMatcher {self.rsmi!r} ({status})>"
204
+
205
+ def __repr__(self) -> str:
206
+ """Detailed representation including rule size and balance.
207
+
208
+ :return: repr string.
209
+ :rtype: str
210
+ """
211
+ try:
212
+ v, e = self.rule.number_of_nodes(), self.rule.number_of_edges()
213
+ except Exception:
214
+ v = e = 0
215
+ return (
216
+ f"RuleMatcher(rsmi={self.rsmi!r}, "
217
+ f"rule=(|V|={v},|E|={e}), balanced={self.balanced})"
218
+ )
@@ -0,0 +1,354 @@
1
+ """Independent finite checks for injective natural DPO squares.
2
+
3
+ The checker uses carrier coverage, exact intersection, coordinate unions and
4
+ coordinate agreement. It does not assume an adhesive ambient category.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from synkit.Graph.Morphism import (
10
+ LLGError,
11
+ derive_electron_labeled_graph,
12
+ is_electron_schema,
13
+ )
14
+
15
+
16
+ def _image_edges(graph, mapping):
17
+ return {frozenset(mapping[node] for node in edge) for edge in graph.edge_keys}
18
+
19
+
20
+ def _morphism(source, target, pairs, name, issues):
21
+ from .dpo import DPOIssue, DPOIssueCode
22
+
23
+ mapping = dict(pairs)
24
+ if (
25
+ len(mapping) != len(pairs)
26
+ or set(mapping) != set(source.node_ids)
27
+ or len(set(mapping.values())) != len(mapping)
28
+ or not set(mapping.values()) <= set(target.node_ids)
29
+ ):
30
+ issues.append(
31
+ DPOIssue(
32
+ DPOIssueCode.NONCOMMUTATIVE,
33
+ "A certificate map is not a total injective carrier map.",
34
+ {"map": name},
35
+ )
36
+ )
37
+ return None
38
+ for node, image in mapping.items():
39
+ labels = source.node_labels(node, semantic=True)
40
+ target_labels = target.node_labels(image, semantic=True)
41
+ if any(
42
+ key not in target_labels or target_labels[key] != value
43
+ for key, value in labels.items()
44
+ ):
45
+ issues.append(
46
+ DPOIssue(
47
+ DPOIssueCode.MATCH_LABEL,
48
+ "A certificate map does not preserve defined node labels.",
49
+ {"map": name},
50
+ )
51
+ )
52
+ for edge in source.edge_keys:
53
+ image = frozenset(mapping[node] for node in edge)
54
+ if image not in target.edge_keys:
55
+ issues.append(
56
+ DPOIssue(
57
+ DPOIssueCode.MATCH_INCIDENCE,
58
+ "A certificate map does not preserve incidence.",
59
+ {"map": name},
60
+ )
61
+ )
62
+ continue
63
+ labels = source.edge_labels(edge, semantic=True)
64
+ target_labels = target.edge_labels(image, semantic=True)
65
+ if any(
66
+ key not in target_labels or target_labels[key] != value
67
+ for key, value in labels.items()
68
+ ):
69
+ issues.append(
70
+ DPOIssue(
71
+ DPOIssueCode.MATCH_LABEL,
72
+ "A certificate map does not preserve defined edge labels.",
73
+ {"map": name},
74
+ )
75
+ )
76
+ return mapping
77
+
78
+
79
+ def _square(
80
+ interface,
81
+ first,
82
+ context,
83
+ target,
84
+ arm,
85
+ to_context,
86
+ first_target,
87
+ context_target,
88
+ issues,
89
+ ):
90
+ from .dpo import DPOIssue, DPOIssueCode
91
+
92
+ for edge_mode in (False, True):
93
+ if edge_mode:
94
+ first_image = _image_edges(first, first_target)
95
+ context_image = _image_edges(context, context_target)
96
+ interface_image = _image_edges(
97
+ interface, {n: first_target[arm[n]] for n in interface.node_ids}
98
+ )
99
+ target_carriers = set(target.edge_keys)
100
+ first_carriers = first.edge_keys
101
+ context_carriers = context.edge_keys
102
+ interface_carriers = interface.edge_keys
103
+ keys = target.schema.semantic_edge_keys
104
+
105
+ def labels(graph, item):
106
+ return graph.edge_labels(item, semantic=True)
107
+
108
+ def transport(mapping, item):
109
+ return frozenset(mapping[n] for n in item)
110
+
111
+ else:
112
+ first_image = set(first_target.values())
113
+ context_image = set(context_target.values())
114
+ interface_image = {first_target[arm[n]] for n in interface.node_ids}
115
+ target_carriers = set(target.node_ids)
116
+ first_carriers = first.node_ids
117
+ context_carriers = context.node_ids
118
+ interface_carriers = interface.node_ids
119
+ keys = target.schema.semantic_node_keys
120
+
121
+ def labels(graph, item):
122
+ return graph.node_labels(item, semantic=True)
123
+
124
+ def transport(mapping, item):
125
+ return mapping[item]
126
+
127
+ if (
128
+ first_image | context_image != target_carriers
129
+ or first_image & context_image != interface_image
130
+ ):
131
+ issues.append(
132
+ DPOIssue(
133
+ DPOIssueCode.NONCOMMUTATIVE,
134
+ "A square fails carrier coverage or exact interface intersection.",
135
+ {"edges": edge_mode},
136
+ )
137
+ )
138
+ continue
139
+ _label_square(
140
+ interface,
141
+ first,
142
+ context,
143
+ target,
144
+ arm,
145
+ to_context,
146
+ first_target,
147
+ context_target,
148
+ labels,
149
+ transport,
150
+ keys,
151
+ first_carriers,
152
+ context_carriers,
153
+ target_carriers,
154
+ interface_carriers,
155
+ issues,
156
+ )
157
+
158
+
159
+ def _label_square(
160
+ interface,
161
+ first,
162
+ context,
163
+ target,
164
+ arm,
165
+ to_context,
166
+ first_target,
167
+ context_target,
168
+ labels,
169
+ transport,
170
+ keys,
171
+ first_carriers,
172
+ context_carriers,
173
+ target_carriers,
174
+ interface_carriers,
175
+ issues,
176
+ ):
177
+ from .dpo import DPOIssue, DPOIssueCode
178
+
179
+ supplied = {}
180
+ for graph, carriers, mapping in (
181
+ (first, first_carriers, first_target),
182
+ (context, context_carriers, context_target),
183
+ ):
184
+ for item in carriers:
185
+ image = transport(mapping, item)
186
+ union = supplied.setdefault(image, {})
187
+ for key, value in labels(graph, item).items():
188
+ if key in union and union[key] != value:
189
+ issues.append(
190
+ DPOIssue(DPOIssueCode.RESULT_LABEL, "Pushout labels conflict.")
191
+ )
192
+ union[key] = value
193
+ for item in target_carriers:
194
+ if supplied[item] != labels(target, item):
195
+ issues.append(
196
+ DPOIssue(
197
+ DPOIssueCode.RESULT_LABEL,
198
+ "Target labels are not the union of the two arms.",
199
+ )
200
+ )
201
+ for item in interface_carriers:
202
+ first_labels = labels(first, transport(arm, item))
203
+ context_labels = labels(context, transport(to_context, item))
204
+ agreement = {
205
+ key: first_labels[key]
206
+ for key in keys
207
+ if key in first_labels
208
+ and key in context_labels
209
+ and first_labels[key] == context_labels[key]
210
+ }
211
+ if labels(interface, item) != agreement:
212
+ issues.append(
213
+ DPOIssue(
214
+ DPOIssueCode.RESULT_LABEL,
215
+ "The interface is not the coordinate agreement pullback.",
216
+ )
217
+ )
218
+
219
+
220
+ def validate_certificate(certificate):
221
+ """Check map shape, labels, naturality, resources, policy and edit metadata."""
222
+ from .dpo import DPOError, DPOIssue, DPOIssueCode, RuleEmbedding
223
+
224
+ c = certificate
225
+ issues = []
226
+ schema = c.rule.left.schema
227
+ if any(
228
+ graph.schema != schema
229
+ for graph in (c.rule.interface, c.rule.right, c.host, c.context, c.result)
230
+ ):
231
+ return [
232
+ DPOIssue(
233
+ DPOIssueCode.SCHEMA_MISMATCH, "All square objects must use one schema."
234
+ )
235
+ ]
236
+ if c.host.partial or c.result.partial or not c.context.partial:
237
+ return [
238
+ DPOIssue(
239
+ DPOIssueCode.INTERFACE_PARTIAL,
240
+ "Host and result are total; context is partial.",
241
+ )
242
+ ]
243
+ try:
244
+ RuleEmbedding(c.rule.interface, c.rule.left, c.rule.left_arm.f)
245
+ RuleEmbedding(c.rule.interface, c.rule.right, c.rule.right_arm.f)
246
+ c.rule.__post_init__()
247
+ except DPOError as error:
248
+ return list(error.issues)
249
+ maps = [
250
+ _morphism(source, target, pairs, name, issues)
251
+ for source, target, pairs, name in (
252
+ (c.rule.left, c.host, c.match, "match"),
253
+ (
254
+ c.rule.interface,
255
+ c.context,
256
+ c.interface_to_context,
257
+ "interface_to_context",
258
+ ),
259
+ (c.context, c.host, c.context_to_host, "context_to_host"),
260
+ (c.context, c.result, c.context_to_result, "context_to_result"),
261
+ (c.rule.right, c.result, c.right_to_result, "right_to_result"),
262
+ )
263
+ ]
264
+ if issues:
265
+ return issues
266
+ match, to_context, context_host, context_result, right_result = maps
267
+ for arm, first_target, context_target in (
268
+ (c.rule.left_arm.mapping, match, context_host),
269
+ (c.rule.right_arm.mapping, right_result, context_result),
270
+ ):
271
+ if any(
272
+ first_target[arm[n]] != context_target[to_context[n]]
273
+ for n in c.rule.interface.node_ids
274
+ ):
275
+ return [
276
+ DPOIssue(
277
+ DPOIssueCode.NONCOMMUTATIVE,
278
+ "A certificate square does not commute.",
279
+ )
280
+ ]
281
+ _square(
282
+ c.rule.interface,
283
+ c.rule.left,
284
+ c.context,
285
+ c.host,
286
+ c.rule.left_arm.mapping,
287
+ to_context,
288
+ match,
289
+ context_host,
290
+ issues,
291
+ )
292
+ _square(
293
+ c.rule.interface,
294
+ c.rule.right,
295
+ c.context,
296
+ c.result,
297
+ c.rule.right_arm.mapping,
298
+ to_context,
299
+ right_result,
300
+ context_result,
301
+ issues,
302
+ )
303
+ _validate_edits_and_condition(c, match, context_result, issues)
304
+ if c.resource_delta != c.rule.resource_delta:
305
+ issues.append(
306
+ DPOIssue(
307
+ DPOIssueCode.OPEN_TOKEN_MISMATCH,
308
+ "Recorded resource delta is incorrect.",
309
+ )
310
+ )
311
+ if is_electron_schema(schema):
312
+ for graph in (c.host, c.result):
313
+ try:
314
+ derive_electron_labeled_graph(graph.to_networkx())
315
+ except LLGError:
316
+ issues.append(
317
+ DPOIssue(
318
+ DPOIssueCode.RESULT_LABEL,
319
+ "A total electron host has incoherent derived labels.",
320
+ )
321
+ )
322
+ return issues
323
+
324
+
325
+ def _validate_edits_and_condition(c, match, context_result, issues):
326
+ from .dpo import DPOError, DPOIssue, DPOIssueCode, _deletion_plan
327
+
328
+ try:
329
+ deletion = _deletion_plan(c.rule, c.host, match)
330
+ if c.rule.condition is not None:
331
+ c.rule.condition.validate(c.host, match)
332
+ except DPOError as error:
333
+ issues.extend(error.issues)
334
+ else:
335
+ expected_added_nodes = set(c.result.node_ids) - set(context_result.values())
336
+ expected_added_edges = set(c.result.edge_keys) - _image_edges(
337
+ c.context, context_result
338
+ )
339
+ metadata = (
340
+ (c.deleted_nodes, deletion.nodes),
341
+ (c.deleted_edges, deletion.edges),
342
+ (c.added_nodes, expected_added_nodes),
343
+ (c.added_edges, expected_added_edges),
344
+ )
345
+ if any(
346
+ len(items) != len(set(items)) or set(items) != set(expected)
347
+ for items, expected in metadata
348
+ ):
349
+ issues.append(
350
+ DPOIssue(
351
+ DPOIssueCode.NONCOMMUTATIVE,
352
+ "Edit provenance does not match the squares.",
353
+ )
354
+ )
@@ -0,0 +1,106 @@
1
+ """Native proof-bearing rule identity and composition."""
2
+
3
+ from ._identity import cluster_rule_objects, rule_objects_isomorphic
4
+ from .composition import (
5
+ CompositionCertificate,
6
+ CompositionError,
7
+ CompositionIssue,
8
+ CompositionIssueCode,
9
+ CompositionProvenance,
10
+ CompositionReplay,
11
+ CompositionResult,
12
+ ProvenanceRef,
13
+ RuleOverlap,
14
+ compose_rules,
15
+ )
16
+ from .search import (
17
+ CompositionClass,
18
+ CompositionSearchResult,
19
+ CompositionWitness,
20
+ ExtendedMatchMatrix,
21
+ OverlapSearchError,
22
+ OverlapSearchIssue,
23
+ OverlapSearchIssueCode,
24
+ OverlapSearchLimits,
25
+ RejectedOverlap,
26
+ RuleSpanIsomorphism,
27
+ canonical_overlap_digest,
28
+ canonical_rule_identity,
29
+ enumerate_overlaps,
30
+ extended_component_match_matrix,
31
+ find_rule_span_isomorphism,
32
+ quotient_composition_witnesses,
33
+ rule_spans_isomorphic,
34
+ search_compositions,
35
+ )
36
+ from .laws import (
37
+ CommutationCertificate,
38
+ LawError,
39
+ LawIssue,
40
+ LawIssueCode,
41
+ ParallelIndependenceCertificate,
42
+ RuleAccess,
43
+ check_parallel_independence,
44
+ commute_independent,
45
+ find_llg_isomorphism,
46
+ identity_rule,
47
+ reverse_rule,
48
+ )
49
+ from .synrule import (
50
+ SynRuleCompositionError,
51
+ SynRuleCompositionIssue,
52
+ SynRuleCompositionIssueCode,
53
+ compose_synrules,
54
+ search_synrule_compositions,
55
+ synrule_to_span,
56
+ )
57
+
58
+ __all__ = [
59
+ "CompositionCertificate",
60
+ "CompositionClass",
61
+ "CompositionError",
62
+ "CompositionIssue",
63
+ "CompositionIssueCode",
64
+ "CompositionProvenance",
65
+ "CompositionReplay",
66
+ "CompositionResult",
67
+ "CompositionSearchResult",
68
+ "CompositionWitness",
69
+ "ExtendedMatchMatrix",
70
+ "CommutationCertificate",
71
+ "LawError",
72
+ "LawIssue",
73
+ "LawIssueCode",
74
+ "OverlapSearchError",
75
+ "OverlapSearchIssue",
76
+ "OverlapSearchIssueCode",
77
+ "OverlapSearchLimits",
78
+ "ParallelIndependenceCertificate",
79
+ "ProvenanceRef",
80
+ "RuleOverlap",
81
+ "RuleAccess",
82
+ "RejectedOverlap",
83
+ "RuleSpanIsomorphism",
84
+ "SynRuleCompositionError",
85
+ "SynRuleCompositionIssue",
86
+ "SynRuleCompositionIssueCode",
87
+ "canonical_overlap_digest",
88
+ "canonical_rule_identity",
89
+ "check_parallel_independence",
90
+ "cluster_rule_objects",
91
+ "compose_rules",
92
+ "compose_synrules",
93
+ "commute_independent",
94
+ "enumerate_overlaps",
95
+ "extended_component_match_matrix",
96
+ "find_rule_span_isomorphism",
97
+ "quotient_composition_witnesses",
98
+ "find_llg_isomorphism",
99
+ "identity_rule",
100
+ "rule_objects_isomorphic",
101
+ "rule_spans_isomorphic",
102
+ "reverse_rule",
103
+ "search_compositions",
104
+ "search_synrule_compositions",
105
+ "synrule_to_span",
106
+ ]