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,378 @@
1
+ """Prepared-graph conversion and result records for the shared native core."""
2
+
3
+ import ctypes as ct
4
+ import json
5
+ import math
6
+ import time
7
+ from collections import Counter
8
+ from numbers import Integral, Real
9
+ from pathlib import Path
10
+
11
+ import numpy as np
12
+
13
+ from ..exact.distance_search.records import (
14
+ DistanceEnumerationResult,
15
+ ExactEnumerationLimitError,
16
+ normalize_distance_target,
17
+ )
18
+ from ..slap.lap import _adjacency_and_elements
19
+ from .runtime import (
20
+ BACKENDS,
21
+ CALLBACK,
22
+ INT,
23
+ LONG,
24
+ REASONS,
25
+ Problem,
26
+ Request,
27
+ Statistics,
28
+ load_core,
29
+ resolve_library_path,
30
+ )
31
+
32
+
33
+ def _ids(values, registry):
34
+ return np.asarray([registry.setdefault(value, len(registry)) for value in values], dtype=np.int32)
35
+
36
+
37
+ # Validation, native buffers and callbacks belong to the same solve lifetime.
38
+ def enumerate_core_mappings( # noqa: C901
39
+ lgp,
40
+ *,
41
+ library_path=None,
42
+ backend="pabs",
43
+ CD="minimal",
44
+ CD_mode="exact",
45
+ binary=False,
46
+ symmetry=False,
47
+ node_properties=(),
48
+ time_limit_seconds=None,
49
+ max_states=None,
50
+ max_mappings=None,
51
+ max_classes=None,
52
+ max_frontier=None,
53
+ memory_limit_bytes=None,
54
+ collect_mappings=True,
55
+ mapping_callback=None,
56
+ compute_minimum_cost=None,
57
+ max_bijections=None,
58
+ tolerance=1e-9,
59
+ proof_only=False,
60
+ cancel_token=None,
61
+ initial_mapping=None,
62
+ allowed_domains=None,
63
+ _native_classifier=None,
64
+ _native_class_registry=None,
65
+ ):
66
+ started = time.perf_counter()
67
+ library_path = resolve_library_path(library_path)
68
+ target = normalize_distance_target(CD)
69
+ if backend not in BACKENDS:
70
+ raise ValueError(f"Unknown native backend: {backend}")
71
+ if allowed_domains is not None and backend not in {"kbb", "kmilp"}:
72
+ raise ValueError("allowed_domains requires a kernel backend: kbb or kmilp")
73
+ if CD_mode not in {"exact", "at_most"} or (CD_mode == "at_most" and target == "minimal"):
74
+ raise ValueError("at_most requires numeric CD; otherwise use exact")
75
+ for name, value in (
76
+ ("binary", binary),
77
+ ("symmetry", symmetry),
78
+ ("collect_mappings", collect_mappings),
79
+ ("proof_only", proof_only),
80
+ ):
81
+ if not isinstance(value, bool):
82
+ raise TypeError(f"{name} must be boolean")
83
+ if proof_only and target != "minimal":
84
+ raise ValueError("proof_only requires minimal CD")
85
+ if initial_mapping is not None:
86
+ raise ValueError("Shared-core explicit warm starts are not qualified yet")
87
+ if compute_minimum_cost and target != "minimal":
88
+ raise ValueError("Numeric core queries do not run a separate minimum proof")
89
+ if mapping_callback is not None and not callable(mapping_callback):
90
+ raise TypeError("mapping_callback must be callable")
91
+ for name, value in (
92
+ ("max_states", max_states),
93
+ ("max_mappings", max_mappings),
94
+ ("max_classes", max_classes),
95
+ ("max_frontier", max_frontier),
96
+ ("memory_limit_bytes", memory_limit_bytes),
97
+ ("max_bijections", max_bijections),
98
+ ):
99
+ if value is not None and (isinstance(value, bool) or not isinstance(value, Integral) or not 1 <= value < 2**63):
100
+ raise ValueError(f"{name} must be a positive integer or None")
101
+ if time_limit_seconds is not None and (
102
+ isinstance(time_limit_seconds, bool)
103
+ or not isinstance(time_limit_seconds, Real)
104
+ or not math.isfinite(time_limit_seconds)
105
+ or time_limit_seconds < 0
106
+ ):
107
+ raise ValueError("time_limit_seconds must be finite and nonnegative")
108
+ if (
109
+ isinstance(tolerance, bool)
110
+ or not isinstance(tolerance, Real)
111
+ or not math.isfinite(tolerance)
112
+ or not 0 <= tolerance < 0.25
113
+ ):
114
+ raise ValueError("tolerance must be finite and in [0,0.25)")
115
+ if len(lgp) != 2:
116
+ raise ValueError("Expected two endpoint graphs")
117
+ matrices, elements = zip(*[_adjacency_and_elements(graph, binary) for graph in lgp])
118
+ n = len(elements[0])
119
+ if not 1 <= n <= 1024 or any(matrix.shape != (n, n) for matrix in matrices):
120
+ raise ValueError("Core requires compatible 1..1024 vertex graphs")
121
+ if Counter(elements[0]) != Counter(elements[1]):
122
+ raise ValueError("Unequal atom-type inventories")
123
+ encoded = []
124
+ for graph, matrix in zip(lgp, matrices):
125
+ if (
126
+ any(graph.graph[i].get(i, 0) for i in range(n))
127
+ or not np.isfinite(matrix).all()
128
+ or np.any(matrix < 0)
129
+ or np.any(matrix > 500000)
130
+ or not np.array_equal(matrix, matrix.T)
131
+ or not np.allclose(matrix * 2, np.rint(matrix * 2), atol=tolerance, rtol=0)
132
+ ):
133
+ raise ValueError("Core requires symmetric loop-free nonnegative half-integer weights")
134
+ encoded.append(np.ascontiguousarray(np.rint(matrix * 2), dtype=np.int64))
135
+ total = math.prod(math.factorial(count) for count in Counter(elements[0]).values())
136
+ if max_bijections is not None and total > max_bijections:
137
+ raise ExactEnumerationLimitError("Bijections exceed max_bijections")
138
+ registry = {}
139
+ types = [_ids(side, registry) for side in elements]
140
+ colors = {}
141
+ nodes = []
142
+ for graph, side in zip(lgp, elements):
143
+ if set(node_properties) - graph.props.keys():
144
+ raise ValueError("Missing symmetry node properties")
145
+ nodes.append(
146
+ _ids(
147
+ [(element, *(graph.props[name][i] for name in node_properties)) for i, element in enumerate(side)],
148
+ colors,
149
+ )
150
+ )
151
+ edges = [np.zeros((n, n), dtype=np.int32) for _ in lgp]
152
+ # Extra native edge class tokens may be supplied by a frontend; absent
153
+ # matrices mean no extra edge attributes beyond the weighted objective.
154
+ for i, graph in enumerate(lgp):
155
+ if "_native_edge_colors" in graph.props:
156
+ values = np.asarray(graph.props["_native_edge_colors"])
157
+ if values.shape != (n, n) or not np.array_equal(values, values.T):
158
+ raise ValueError("Invalid native edge class attributes")
159
+ edges[i] = np.ascontiguousarray(values, dtype=np.int32)
160
+ maximum = float((matrices[0].sum() + matrices[1].sum()) / 2)
161
+ query = 3 if proof_only else 0 if target == "minimal" else 2 if CD_mode == "at_most" else 1
162
+ impossible = False
163
+ if target == "minimal":
164
+ target2 = 0
165
+ elif query == 2:
166
+ target2 = math.floor((min(target, maximum) + tolerance) * 2)
167
+ elif target > maximum + tolerance:
168
+ target2 = 0
169
+ impossible = True
170
+ else:
171
+ target2 = round(target * 2)
172
+ impossible = abs(target - target2 / 2) > tolerance
173
+ problem = Problem(
174
+ 1,
175
+ n,
176
+ *[array.ctypes.data_as(LONG) for array in encoded],
177
+ *[array.ctypes.data_as(INT) for array in [*types, *nodes, *edges]],
178
+ )
179
+ domain_mask = None
180
+ if allowed_domains is not None:
181
+ values = np.asarray(allowed_domains)
182
+ if values.shape != (n, n) or not np.isin(values, [0, 1]).all():
183
+ raise ValueError("allowed_domains must be an n-by-n zero/one mask")
184
+ domain_mask = np.ascontiguousarray(values, dtype=np.uint8)
185
+ request = Request()
186
+ request.abi_version = 1
187
+ request.backend = BACKENDS[backend]
188
+ request.query = query
189
+ request.symmetry = int(symmetry)
190
+ request.workers = 1
191
+ request.target2 = target2
192
+ request.seconds = -1 if time_limit_seconds is None else max(0, time_limit_seconds - (time.perf_counter() - started))
193
+ for name, value in (
194
+ ("max_states", max_states),
195
+ ("max_candidates", max_mappings),
196
+ ("max_classes", max_classes),
197
+ ("max_frontier", max_frontier),
198
+ ("memory_limit_bytes", memory_limit_bytes),
199
+ ):
200
+ setattr(request, name, -1 if value is None else int(value))
201
+ request.slap_max_fingerprints = 10000
202
+ stop_flags = np.asarray([int(value == 1) for value in lgp[0].labels], dtype=np.int32)
203
+ request.slap_stop_flags = stop_flags.ctypes.data_as(INT)
204
+ request.cancel_token = None if cancel_token is None else cancel_token.pointer
205
+ mappings = []
206
+ distances = []
207
+ observed = set()
208
+ errors = []
209
+ classification = None
210
+
211
+ def receive(pointer, cost2, _userdata):
212
+ try:
213
+ mapping = list(pointer[:n])
214
+ cost = cost2 / 2
215
+ if sorted(mapping) != list(range(n)) or any(
216
+ elements[0][i] != elements[1][j] for i, j in enumerate(mapping)
217
+ ):
218
+ raise RuntimeError("Native core returned incompatible bijection")
219
+ observed.add(cost)
220
+ if collect_mappings:
221
+ mappings.append(mapping)
222
+ distances.append(cost)
223
+ if mapping_callback is not None:
224
+ mapping_callback(mapping, cost)
225
+ return 0
226
+ except BaseException as error: # noqa: BLE001
227
+ errors.append(error)
228
+ return 1
229
+
230
+ callback = CALLBACK(receive)
231
+ stats = Statistics()
232
+ library = load_core(str(Path(library_path).resolve()))
233
+ request.seconds = -1 if time_limit_seconds is None else max(0, time_limit_seconds - (time.perf_counter() - started))
234
+ if impossible:
235
+ stats.search_complete = stats.classification_complete = stats.hydrogen_complete = 1
236
+ stats.minimum2 = stats.incumbent2 = stats.lower_bound2 = -1
237
+ stats.labeled_count = 0
238
+ elif _native_classifier is not None:
239
+ if _native_class_registry is None:
240
+ raise ValueError("Native class registry is required")
241
+
242
+ def receive_class(record):
243
+ _native_class_registry[record.representative] = record
244
+ array = (ct.c_int32 * n)(*record.representative)
245
+ return receive(array, record.cost2, None)
246
+
247
+ classification, stats = _native_classifier.solve_prepared(
248
+ problem,
249
+ request,
250
+ class_callback=receive_class,
251
+ max_canonical_nodes=getattr(_native_classifier, "frontend_max_canonical_nodes", None),
252
+ allowed_domains=domain_mask,
253
+ stream=True,
254
+ )
255
+ if errors:
256
+ raise errors[0]
257
+ else:
258
+ if domain_mask is not None:
259
+ if not hasattr(library, "synkit_mapper_solve_domains"):
260
+ raise RuntimeError("Library lacks the native kernel domain API")
261
+ result = library.synkit_mapper_solve_domains(
262
+ ct.byref(problem),
263
+ ct.byref(request),
264
+ domain_mask.ctypes.data_as(ct.POINTER(ct.c_uint8)),
265
+ callback,
266
+ None,
267
+ ct.byref(stats),
268
+ )
269
+ else:
270
+ result = library.synkit_mapper_solve(ct.byref(problem), ct.byref(request), callback, None, ct.byref(stats))
271
+ if errors:
272
+ raise errors[0]
273
+ if result:
274
+ raise RuntimeError(library.synkit_mapper_core_error().decode())
275
+ detail = {name: getattr(stats, name) for name, _ in stats._fields_}
276
+ detail.update(
277
+ core_abi=1,
278
+ backend=backend,
279
+ library_path=str(Path(library_path).resolve()),
280
+ CD_mode=CD_mode,
281
+ proof_only=proof_only,
282
+ cost_scale=2,
283
+ requested_symmetry=symmetry,
284
+ domain_restricted=domain_mask is not None,
285
+ enumeration_search_seconds=max(0, stats.enumeration_seconds - stats.callback_seconds),
286
+ )
287
+ metadata_function = getattr(library, "synkit_mapper_backend_metadata", None)
288
+ backend_executed = (
289
+ not impossible
290
+ and stats.status != 2
291
+ and not (stats.reason == 10 and stats.nodes == 0 and stats.model_seconds == 0 and stats.candidate_count == 0)
292
+ )
293
+ detail["backend_executed"] = backend_executed
294
+ if metadata_function and backend_executed:
295
+ detail["native_metadata"] = json.loads(metadata_function(BACKENDS[backend]).decode())
296
+ version_function = getattr(library, "synkit_mapper_backend_version", None)
297
+ detail.update(
298
+ solver_version=version_function(BACKENDS[backend]).decode() if version_function else None,
299
+ threads=1,
300
+ classification_reason=None if classification is None else classification.reason,
301
+ classification_delivery=(None if classification is None else _native_classifier.delivery_mode),
302
+ delivered_class_count=(None if classification is None else len(classification.classes)),
303
+ )
304
+ if backend == "scip":
305
+ detail.update(
306
+ numerical_qualification=(
307
+ "solver OPTIMAL under floating feasibility tolerances; " "no checked formal certificate"
308
+ ),
309
+ relative_gap=0,
310
+ absolute_gap=0,
311
+ feasibility_tolerance=1e-9,
312
+ )
313
+ if backend in {"cp_sat", "scip", "maxsat"}:
314
+ detail["implementation"] = "cpp_sparse_full_assignment_linearization"
315
+ complete = bool(stats.search_complete) and not proof_only and backend != "slap"
316
+ reason = REASONS.get(stats.reason, "unknown_stop")
317
+ return DistanceEnumerationResult(
318
+ target=target,
319
+ cost=next(iter(observed)) if len(observed) == 1 else None,
320
+ minimum_cost=stats.minimum2 / 2 if stats.minimum_proven else None,
321
+ mappings=mappings,
322
+ distances=distances,
323
+ total_bijections=total,
324
+ maximum_cost_upper_bound=maximum,
325
+ visited_leaves=stats.leaves,
326
+ pruned_branches=0,
327
+ visited_nodes=stats.nodes,
328
+ elapsed_seconds=time.perf_counter() - started,
329
+ status=(
330
+ ("complete" if stats.candidate_count else "no_solutions")
331
+ if complete
332
+ else "unsupported" if stats.status == 2 else "timeout"
333
+ ),
334
+ complete=complete,
335
+ truncation_reason=reason or ("proof_only" if proof_only else None),
336
+ selected_mapping_count=stats.candidate_count,
337
+ selected_labeled_mapping_count=None if stats.labeled_count < 0 else stats.labeled_count,
338
+ scope=(
339
+ "restricted_kernel_assignment_space"
340
+ if backend in {"kbb", "kmilp"}
341
+ else (
342
+ "heuristic_candidates"
343
+ if backend == "slap"
344
+ else (
345
+ "atom_compatible_assignment_space_modulo_verified_symmetry"
346
+ if symmetry or backend == "cpabs"
347
+ else "complete_atom_compatible_assignment_space"
348
+ )
349
+ )
350
+ ),
351
+ symmetry_group_order=None if symmetry or backend == "cpabs" else 1,
352
+ symmetry_search_complete=not symmetry,
353
+ symmetry_quotient_complete=False,
354
+ backend=f"{backend}_cpp",
355
+ backend_statistics=detail,
356
+ )
357
+
358
+
359
+ def map_reaction_core(reaction, *, library_path, backend="pabs", native_classification=None, **options):
360
+ from ...reaction_search import _map_reaction_with_search
361
+
362
+ domains = options.pop("allowed_domains", None)
363
+ if native_classification is None:
364
+ native_classification = True
365
+
366
+ def search(graphs, **kwargs):
367
+ kwargs.pop("backend")
368
+ kwargs["symmetry"] = backend in {"pabs", "cpabs"}
369
+ return enumerate_core_mappings(graphs, backend=backend, allowed_domains=domains, **kwargs)
370
+
371
+ return _map_reaction_with_search(
372
+ reaction,
373
+ search_function=search,
374
+ backend="cpp",
375
+ library_path=library_path,
376
+ native_classification_library=library_path if native_classification else None,
377
+ **options,
378
+ )
@@ -0,0 +1,120 @@
1
+ cmake_minimum_required(VERSION 3.16)
2
+ project(synkit_mapper VERSION 1.6.5 LANGUAGES C CXX)
3
+
4
+ add_library(synkit_mapper SHARED
5
+ src/slap.cpp src/core/dispatch.cpp src/core/pmcd_witness.cpp
6
+ src/pabs/bridge.cpp src/pabs/sparse_embedding.cpp src/symmetry/edge_deck.cpp
7
+ src/assignment/abb.cpp
8
+ src/supporting/dfs.cpp src/supporting/edit_support.cpp src/sepdp/sepdp.cpp
9
+ src/mces/mces.cpp
10
+ src/hydrogen/hydrogen.cpp
11
+ src/astar/astar.cpp src/astar/bound.cpp
12
+ src/symmetry/classification.cpp src/symmetry/classification_pipeline.cpp src/symmetry/cpabs.cpp)
13
+ target_compile_definitions(synkit_mapper PRIVATE SYNKIT_MAPPER_WITH_ASTAR SYNKIT_MAPPER_WITH_CPABS SYNKIT_MAPPER_WITH_ASSIGNMENT SYNKIT_MAPPER_WITH_SUPPORTING SYNKIT_MAPPER_WITH_MCES)
14
+ target_compile_features(synkit_mapper PUBLIC cxx_std_17)
15
+ target_include_directories(synkit_mapper PUBLIC
16
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
17
+ $<INSTALL_INTERFACE:include>)
18
+
19
+ # Only the sparse canonical-labeling engine and its transitive dependencies
20
+ # are vendored. Keep third-party compiler settings separate from our C++ core.
21
+ set(SYNKIT_NAUTY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/symmetry/vendor/nauty)
22
+ option(SYNKIT_MAPPER_WITH_NAUTY "Enable optional sparse edge-deck certificates" ${UNIX})
23
+ if(SYNKIT_MAPPER_WITH_NAUTY)
24
+ add_library(synkit_mapper_nauty STATIC
25
+ ${SYNKIT_NAUTY_DIR}/nauty.c ${SYNKIT_NAUTY_DIR}/nautil.c
26
+ ${SYNKIT_NAUTY_DIR}/nausparse.c ${SYNKIT_NAUTY_DIR}/naugraph.c
27
+ ${SYNKIT_NAUTY_DIR}/schreier.c ${SYNKIT_NAUTY_DIR}/naurng.c)
28
+ set_target_properties(synkit_mapper_nauty PROPERTIES POSITION_INDEPENDENT_CODE ON)
29
+ target_include_directories(synkit_mapper PRIVATE ${SYNKIT_NAUTY_DIR})
30
+ target_link_libraries(synkit_mapper PRIVATE synkit_mapper_nauty)
31
+ target_compile_definitions(synkit_mapper PRIVATE SYNKIT_MAPPER_WITH_NAUTY)
32
+ endif()
33
+
34
+ option(SYNKIT_MAPPER_TEST_HOOKS "Build private mathematical-oracle entry points" OFF)
35
+ if(SYNKIT_MAPPER_TEST_HOOKS)
36
+ target_compile_definitions(synkit_mapper PRIVATE SYNKIT_MAPPER_TEST_HOOKS)
37
+ endif()
38
+ if(MSVC)
39
+ target_compile_options(synkit_mapper PRIVATE /W4)
40
+ else()
41
+ target_compile_options(synkit_mapper PRIVATE -Wall -Wextra -Wpedantic)
42
+ endif()
43
+
44
+ option(SYNKIT_MAPPER_WITH_RDKIT "Build standalone native reaction preparation/rendering" OFF)
45
+ if(SYNKIT_MAPPER_WITH_RDKIT)
46
+ find_package(rdkit CONFIG REQUIRED)
47
+ add_library(synkit_mapper_reaction SHARED src/reaction/reaction.cpp)
48
+ # The optional RDKit 2026 SDK uses constexpr destructors in public headers.
49
+ # Keep the dependency-free mapper core on C++17.
50
+ target_compile_features(synkit_mapper_reaction PUBLIC cxx_std_20)
51
+ target_include_directories(synkit_mapper_reaction PUBLIC
52
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
53
+ $<INSTALL_INTERFACE:include>)
54
+ target_link_libraries(synkit_mapper_reaction PRIVATE synkit_mapper
55
+ RDKit::GraphMol RDKit::SmilesParse RDKit::RDGeneral)
56
+ add_executable(mapper_reaction examples/map_reaction.cpp)
57
+ target_link_libraries(mapper_reaction PRIVATE synkit_mapper_reaction)
58
+ endif()
59
+ set_target_properties(synkit_mapper PROPERTIES
60
+ CXX_EXTENSIONS OFF
61
+ WINDOWS_EXPORT_ALL_SYMBOLS ON
62
+ POSITION_INDEPENDENT_CODE ON)
63
+
64
+ option(SYNKIT_MAPPER_WITH_ORTOOLS "Build CP-SAT, SCIP and certified PABS PDLP bounds" OFF)
65
+ if(SYNKIT_MAPPER_WITH_ORTOOLS)
66
+ find_package(ortools CONFIG REQUIRED)
67
+ target_sources(synkit_mapper PRIVATE src/solvers/ortools.cpp)
68
+ target_link_libraries(synkit_mapper PRIVATE ortools::ortools)
69
+ target_compile_definitions(synkit_mapper PRIVATE SYNKIT_MAPPER_WITH_ORTOOLS)
70
+ endif()
71
+ set(SYNKIT_MAPPER_OPENWBO_EXECUTABLE "" CACHE FILEPATH "Qualified native Open-WBO executable")
72
+ set(SYNKIT_MAPPER_EVALMAXSAT_EXECUTABLE "" CACHE FILEPATH "Qualified native EvalMaxSAT executable")
73
+ if(SYNKIT_MAPPER_OPENWBO_EXECUTABLE OR SYNKIT_MAPPER_EVALMAXSAT_EXECUTABLE)
74
+ if(SYNKIT_MAPPER_OPENWBO_EXECUTABLE AND NOT EXISTS "${SYNKIT_MAPPER_OPENWBO_EXECUTABLE}")
75
+ message(FATAL_ERROR "Open-WBO executable does not exist")
76
+ endif()
77
+ target_sources(synkit_mapper PRIVATE src/solvers/maxsat.cpp)
78
+ target_compile_definitions(synkit_mapper PRIVATE SYNKIT_MAPPER_WITH_MAXSAT)
79
+ if(SYNKIT_MAPPER_OPENWBO_EXECUTABLE)
80
+ target_compile_definitions(synkit_mapper PRIVATE
81
+ SYNKIT_MAPPER_OPENWBO_EXECUTABLE="${SYNKIT_MAPPER_OPENWBO_EXECUTABLE}")
82
+ endif()
83
+ if(SYNKIT_MAPPER_EVALMAXSAT_EXECUTABLE)
84
+ if(NOT EXISTS "${SYNKIT_MAPPER_EVALMAXSAT_EXECUTABLE}")
85
+ message(FATAL_ERROR "EvalMaxSAT executable does not exist")
86
+ endif()
87
+ target_compile_definitions(synkit_mapper PRIVATE
88
+ SYNKIT_MAPPER_EVALMAXSAT_EXECUTABLE="${SYNKIT_MAPPER_EVALMAXSAT_EXECUTABLE}")
89
+ endif()
90
+ endif()
91
+
92
+ option(SYNKIT_MAPPER_BUILD_EXAMPLES "Build standalone C++ mapper examples" OFF)
93
+ if(SYNKIT_MAPPER_BUILD_EXAMPLES)
94
+ add_executable(slap_graph examples/slap_graph.cpp)
95
+ target_link_libraries(slap_graph PRIVATE synkit_mapper)
96
+ endif()
97
+
98
+ include(GNUInstallDirs)
99
+ option(SYNKIT_MAPPER_WHEEL "Install only the runtime library inside the Python wheel" OFF)
100
+ if(SYNKIT_MAPPER_WHEEL)
101
+ if(MSVC AND NOT SYNKIT_MAPPER_WITH_ORTOOLS)
102
+ # Standard wheels must not depend on a separately installed MSVC C++ runtime.
103
+ set_property(TARGET synkit_mapper PROPERTY MSVC_RUNTIME_LIBRARY
104
+ "MultiThreaded$<$<CONFIG:Debug>:Debug>")
105
+ endif()
106
+ install(TARGETS synkit_mapper
107
+ LIBRARY DESTINATION synkit/Chem/Mapper/solvers/native/lib
108
+ RUNTIME DESTINATION synkit/Chem/Mapper/solvers/native/lib)
109
+ else()
110
+ install(TARGETS synkit_mapper
111
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
112
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
113
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
114
+ install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
115
+ if(SYNKIT_MAPPER_WITH_RDKIT)
116
+ install(TARGETS synkit_mapper_reaction mapper_reaction
117
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
118
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
119
+ endif()
120
+ endif()
@@ -0,0 +1,29 @@
1
+ #include "synkit_mapper/reaction/reaction.h"
2
+ #include <cstdlib>
3
+ #include <iostream>
4
+
5
+ int main(int argc, char **argv) {
6
+ if (argc < 2) {
7
+ std::cerr << "usage: mapper_reaction 'reactants>>products' [backend_id] [seconds]\n";
8
+ return 2;
9
+ }
10
+ SynkitReactionOptions options{1, 1, 1, 0, 0, 0, 0, 100000, 10000};
11
+ SynkitMapperRequest request{};
12
+ request.abi_version = 1;
13
+ request.backend = argc > 2 ? std::atoi(argv[2]) : SYNKIT_PABS;
14
+ request.query = SYNKIT_MINIMUM_CLASSES;
15
+ request.workers = 1;
16
+ request.seconds = argc > 3 ? std::atof(argv[3]) : 10;
17
+ request.max_states = request.max_classes = request.max_frontier =
18
+ request.memory_limit_bytes = -1;
19
+ request.max_candidates = 100000;
20
+ request.slap_max_fingerprints = 10000;
21
+ char *json = nullptr;
22
+ if (synkit_mapper_reaction_solve(argv[1], &options, &request, &json)) {
23
+ std::cerr << synkit_mapper_reaction_error() << '\n';
24
+ return 1;
25
+ }
26
+ std::cout << json << '\n';
27
+ synkit_mapper_reaction_free(json);
28
+ return 0;
29
+ }
@@ -0,0 +1,63 @@
1
+ // Standalone SLAP on a permuted three-node path, with no Python runtime.
2
+ #include "synkit_mapper/slap.h"
3
+
4
+ #include <array>
5
+ #include <cmath>
6
+ #include <cstdint>
7
+ #include <iostream>
8
+
9
+ namespace {
10
+ constexpr int N = 3;
11
+ constexpr std::array<int64_t, N * N> A2{0, 2, 0, 2, 0, 2, 0, 2, 0};
12
+ constexpr std::array<int64_t, N * N> B2{0, 2, 2, 2, 0, 0, 2, 0, 0};
13
+
14
+ struct Output {
15
+ int count = 0;
16
+ bool valid = true;
17
+ };
18
+
19
+ int receive(const int32_t *mapping, int64_t cost2, void *userdata) {
20
+ auto &output = *static_cast<Output *>(userdata);
21
+ std::array<bool, N> seen{};
22
+ for (int i = 0; i < N; ++i) {
23
+ if (mapping[i] < 0 || mapping[i] >= N || seen[mapping[i]]) {
24
+ output.valid = false;
25
+ return 1;
26
+ }
27
+ seen[mapping[i]] = true;
28
+ }
29
+ int64_t score2 = 0;
30
+ for (int i = 0; i < N; ++i)
31
+ for (int j = i + 1; j < N; ++j)
32
+ score2 += std::abs(A2[i * N + j] - B2[mapping[i] * N + mapping[j]]);
33
+ if (score2 != cost2 || score2 != 0) {
34
+ output.valid = false;
35
+ return 1;
36
+ }
37
+ ++output.count;
38
+ std::cout << "candidate " << output.count << ": CD=" << cost2 / 2.0
39
+ << ", mapping=";
40
+ for (int i = 0; i < N; ++i)
41
+ std::cout << (i ? "," : "") << mapping[i];
42
+ std::cout << '\n';
43
+ return 0;
44
+ }
45
+ } // namespace
46
+
47
+ int main() {
48
+ const std::array<int32_t, N> labels{6, 6, 6};
49
+ const std::array<int32_t, N> stop_flags{0, 0, 0};
50
+ Output output;
51
+ SlapStatistics statistics{};
52
+ const int status = synkit_slap_solve(
53
+ N, A2.data(), B2.data(), labels.data(), labels.data(), stop_flags.data(),
54
+ 10000, -1, -1, -1, receive, &output, &statistics);
55
+ if (status || !output.valid || !statistics.completed || !output.count) {
56
+ std::cerr << "SLAP example failed: " << synkit_mapper_error() << '\n';
57
+ return 1;
58
+ }
59
+ std::cout << "Finished heuristic exploration: " << statistics.states
60
+ << " states, " << statistics.lap_calls << " LAP calls.\n"
61
+ << "SLAP provides no general optimality or all-class guarantee.\n";
62
+ return 0;
63
+ }
@@ -0,0 +1,18 @@
1
+ #pragma once
2
+ #include "synkit_mapper/mapper.h"
3
+
4
+ #ifdef __cplusplus
5
+ extern "C" {
6
+ #endif
7
+ SYNKIT_MAPPER_API const char *synkit_mapper_assignment_error(void);
8
+ // Construct a restricted uncertainty kernel from supplied heuristic candidates.
9
+ // Consensus rows are fixed, other rows retain observed images. Small uncertain
10
+ // same-type blocks may be closed when their size <= close_block_size. No
11
+ // assertion is made that these domains contain all full-space optima.
12
+ SYNKIT_MAPPER_API int synkit_mapper_kernel_domains(
13
+ int32_t n, int64_t count, const int32_t *mappings,
14
+ const int32_t *types_r, const int32_t *types_p, int32_t close_block_size,
15
+ uint8_t *allowed);
16
+ #ifdef __cplusplus
17
+ }
18
+ #endif
@@ -0,0 +1,18 @@
1
+ #ifndef SYNKIT_MAPPER_ASTAR_H
2
+ #define SYNKIT_MAPPER_ASTAR_H
3
+
4
+ #include "synkit_mapper/mapper.h"
5
+
6
+ #ifdef __cplusplus
7
+ extern "C" {
8
+ #endif
9
+ // Diagnostic for independent admissibility tests. partial has problem->n
10
+ // entries, -1 for unassigned. Returns 0 on success, -1 on invalid input.
11
+ SYNKIT_MAPPER_API int
12
+ synkit_astar_partial_bound2(const SynkitMapperProblem *problem,
13
+ const int32_t *partial, int64_t *bound2);
14
+ #ifdef __cplusplus
15
+ }
16
+ #endif
17
+
18
+ #endif
@@ -0,0 +1,33 @@
1
+ #ifndef SYNKIT_MAPPER_ASTAR_BOUND_H
2
+ #define SYNKIT_MAPPER_ASTAR_BOUND_H
3
+
4
+ #include <cstdint>
5
+ #include <functional>
6
+ #include <vector>
7
+
8
+ namespace synkit_mapper {
9
+ namespace astar {
10
+
11
+ // Total (committed plus residual) doubled-CD lower bound for a compatible
12
+ // partial map. A -1 image denotes an unassigned source. The complete vector is
13
+ // required; a used-target set alone does not define this bound. Throws on an
14
+ // invalid/incompatible partial map or unsupported integer arithmetic range.
15
+ // This C++ diagnostic uses the same bound as search and is independently
16
+ // checked against exhaustive completions in the conformance suite.
17
+ int64_t partial_lower_bound2(int n, const int64_t *a2, const int64_t *b2,
18
+ const int32_t *types_r, const int32_t *types_p,
19
+ const std::vector<int32_t> &mapping,
20
+ const std::function<void()> &poll = {});
21
+
22
+ // Feasible typed assignment minimizing the same sorted-neighbor profile
23
+ // relaxation used at an empty partial map. This is an input-only incumbent
24
+ // seed, not an optimum certificate for the pairwise mapping objective.
25
+ std::vector<int32_t> profile_assignment_seed(
26
+ int n, const int64_t *a2, const int64_t *b2,
27
+ const int32_t *types_r, const int32_t *types_p,
28
+ const std::function<void()> &poll = {});
29
+
30
+ } // namespace astar
31
+ } // namespace synkit_mapper
32
+
33
+ #endif
@@ -0,0 +1,16 @@
1
+ #pragma once
2
+ #include <stdint.h>
3
+ #ifdef __cplusplus
4
+ extern "C" {
5
+ #endif
6
+ // Per-thread witness for the most recent shared-core call. Each solve clears
7
+ // it first; a zero length means that this call retained no PMCD witness.
8
+ // Query with mapping == NULL and capacity == 0 to obtain the required length.
9
+ void synkit_mapper_clear_pmcd_witness(void);
10
+ void synkit_mapper_store_pmcd_witness(int n, const int32_t *mapping,
11
+ int64_t cost2, int proven);
12
+ int synkit_mapper_last_pmcd_witness(int32_t *mapping, int capacity,
13
+ int64_t *cost2, int *proven);
14
+ #ifdef __cplusplus
15
+ }
16
+ #endif