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,380 @@
1
+ #include "synkit_mapper/hydrogen/hydrogen.h"
2
+ #include "synkit_mapper/core/runtime.h"
3
+ #include <exception>
4
+ #include <functional>
5
+ #include <limits>
6
+ #include <numeric>
7
+ #include <set>
8
+ #include <sstream>
9
+
10
+ namespace {
11
+ using namespace synkit_mapper;
12
+ using Values=std::vector<int32_t>;
13
+ thread_local std::string h_error;
14
+ struct BigInteger {
15
+ std::vector<uint32_t> limbs{1};
16
+ void multiply(uint32_t k) {uint64_t carry=0;for(auto &v:limbs) {uint64_t x=uint64_t(v)*k+carry;v=x%1000000000;carry=x/1000000000;}if(carry) limbs.push_back(carry);}
17
+ void divide(uint32_t k) {uint64_t rest=0;for(size_t i=limbs.size();i-->0;) {uint64_t x=rest*1000000000+limbs[i];limbs[i]=x/k;rest=x%k;}if(rest) throw std::logic_error("Nonintegral H multiplicity");while(limbs.size()>1&&!limbs.back()) limbs.pop_back();}
18
+ std::string text() const {std::ostringstream out;out<<limbs.back();for(size_t i=limbs.size()-1;i-->0;) {auto s=std::to_string(limbs[i]);out<<std::string(9-s.size(),'0')<<s;}return out.str();}
19
+ };
20
+ std::string multiplicity(const Values &rows,const Values &columns,const Values &cells,Budget &budget) {
21
+ BigInteger value;
22
+ for(const auto *counts:{&rows,&columns}) for(int count:*counts) for(int k=2;k<=count;++k) {if(k%64==0) budget.check();value.multiply(k);}
23
+ size_t processed=0;
24
+ for(int count:cells) {if(++processed%1024==0) budget.check();for(int k=2;k<=count;++k) {if(k%64==0) budget.check();value.divide(k);}}
25
+ return value.text();
26
+ }
27
+ struct Transport {
28
+ int n,reservoir,query;int64_t target,max_plans,max_nodes;
29
+ Values original_rows,original_columns,rows,columns,cells,active;
30
+ Request timing{};Budget budget;
31
+ SynkitHydrogenTransportCallback callback;void *userdata;
32
+ SynkitHydrogenTransportStatistics &stats;
33
+ Transport(int size,const int32_t *r,const int32_t *c,int dummy,int q,int64_t t,
34
+ double seconds,int64_t plans,int64_t nodes,void *cancel,
35
+ SynkitHydrogenTransportCallback cb,void *data,SynkitHydrogenTransportStatistics &s)
36
+ :n(size),reservoir(dummy),query(q),target(t),max_plans(plans),max_nodes(nodes),
37
+ original_rows(r,r+size),original_columns(c,c+size),rows(original_rows),columns(original_columns),
38
+ cells(size*size,0),timing{},budget(timing),callback(cb),userdata(data),stats(s) {
39
+ timing.seconds=seconds;timing.cancel_token=cancel;
40
+ }
41
+ bool real(int i) const {return i!=reservoir;}
42
+ int64_t edge_cost(int i,int j) const {return i==j?0:2*(int(real(i))+int(real(j)));}
43
+ void poll() {budget.check();if(max_nodes>=0&&stats.nodes>=max_nodes) throw Stop{SYNKIT_STOP_STATES};++stats.nodes;}
44
+ bool viable(size_t pos,int first_column,int remaining,int64_t cost) {
45
+ int64_t out_rows=0,out_columns=0,diagonal=0;
46
+ for(int j=0;j<n;++j) if(real(j)) out_columns+=columns[j];
47
+ for(size_t k=pos;k<active.size();++k) {
48
+ int i=active[k],count=k==pos?remaining:rows[i];
49
+ if(real(i)) {out_rows+=count;if(k!=pos||i>=first_column) diagonal+=std::min(count,columns[i]);}
50
+ }
51
+ int64_t lower=cost+2*(out_rows+out_columns-2*diagonal);
52
+ if(lower>target) return false;
53
+ return query!=SYNKIT_EXACT_DISTANCE||cost+2*(out_rows+out_columns)>=target;
54
+ }
55
+ void emit(int64_t cost) {
56
+ budget.check();
57
+ if(cost>target||(query==SYNKIT_EXACT_DISTANCE&&cost!=target)) return;
58
+ if(max_plans>=0&&stats.plans>=max_plans) throw Stop{SYNKIT_STOP_CANDIDATES};
59
+ std::string count=multiplicity(original_rows,original_columns,cells,budget);++stats.plans;
60
+ if(callback(cells.data(),cost,count.c_str(),userdata)) throw Stop{SYNKIT_STOP_CALLBACK};
61
+ budget.check();
62
+ }
63
+ void row(size_t pos,int64_t cost) {
64
+ poll();if(pos==active.size()) {emit(cost);return;}
65
+ distribute(pos,0,rows[active[pos]],cost);
66
+ }
67
+ void distribute(size_t pos,int first_column,int remaining,int64_t cost) {
68
+ poll();if(!remaining) {row(pos+1,cost);return;}
69
+ if(!viable(pos,first_column,remaining,cost)) return;
70
+ int i=active[pos];
71
+ // Enumerate positive cells in increasing column order; omitted cells are
72
+ // zero. Recursion depth depends on H count, not parents squared.
73
+ for(int j=first_column;j<n;++j) if(columns[j]) {
74
+ int maximum=std::min(remaining,columns[j]);
75
+ for(int count=1;count<=maximum;++count) {
76
+ int64_t next=cost+count*edge_cost(i,j);if(next>target) break;
77
+ if(query==SYNKIT_MINIMUM_CLASSES&&i==j&&real(i)) continue;
78
+ cells[i*n+j]+=count;columns[j]-=count;
79
+ distribute(pos,j+1,remaining-count,next);
80
+ columns[j]+=count;cells[i*n+j]-=count;
81
+ }
82
+ }
83
+ }
84
+ void run() {
85
+ stats={};
86
+ int64_t minimum=0;
87
+ for(int i=0;i<n;++i) if(real(i)) minimum+=2*std::abs(rows[i]-columns[i]);
88
+ stats.minimum2=minimum;
89
+ budget.check();
90
+ if(query==SYNKIT_MINIMUM_CLASSES) {
91
+ target=minimum;
92
+ for(int i=0;i<n;++i) if(real(i)) {int kept=std::min(rows[i],columns[i]);cells[i*n+i]=kept;rows[i]-=kept;columns[i]-=kept;}
93
+ }
94
+ for(int i=0;i<n;++i) if(rows[i]) active.push_back(i);
95
+ if(minimum<=target) row(0,0);
96
+ stats.complete=1;
97
+ }
98
+ };
99
+
100
+ struct Endpoint {
101
+ Values heavy,counts,reservoir;
102
+ std::vector<Values> groups;
103
+ };
104
+ struct Quotient {
105
+ Problem problem{};
106
+ std::vector<int64_t> a,b;
107
+ Values tr,tp,nr,np,er,ep;
108
+ Endpoint r,p;
109
+ };
110
+ bool uniform_hydrogen_classes(const Problem &p,const SynkitHydrogenAttributes &attrs,const SynkitClassProblem &classes,Budget &budget) {
111
+ if(!classes.node_pair_colors||!classes.edges_r||!classes.edges_p||!classes.edge_pair_colors||classes.edge_states_r<1||classes.edge_states_p<1)
112
+ throw std::invalid_argument("Invalid exact H class palette");
113
+ for(bool right:{false,true}) {
114
+ auto z=right?attrs.atomic_numbers_p:attrs.atomic_numbers_r;
115
+ auto other_z=right?attrs.atomic_numbers_r:attrs.atomic_numbers_p;
116
+ auto dummy=right?attrs.dummies_p:attrs.dummies_r;
117
+ auto weights=right?p.b2:p.a2;
118
+ auto edges=right?classes.edges_p:classes.edges_r;
119
+ int states=right?classes.edge_states_p:classes.edge_states_r;
120
+ int other_states=right?classes.edge_states_r:classes.edge_states_p;
121
+ if(!z||!other_z||!dummy) throw std::invalid_argument("Missing H class eligibility metadata");
122
+ std::map<int,Values> node_signatures,edge_signatures;
123
+ for(int i=0;i<p.n;++i) if(z[i]==1) {
124
+ budget.check();
125
+ Values node;
126
+ for(int j=0;j<p.n;++j) if(other_z[j]==1) node.push_back(classes.node_pair_colors[right?j*p.n+i:i*p.n+j]);
127
+ auto inserted=node_signatures.emplace(int(bool(dummy[i])),node);
128
+ if(!inserted.second&&inserted.first->second!=node) return false;
129
+ for(int j=0;j<p.n;++j) if(i!=j) {
130
+ int state=edges[i*p.n+j];if(state<0||state>=states) throw std::invalid_argument("Invalid H edge palette state");
131
+ Values signature;signature.reserve(other_states);
132
+ for(int k=0;k<other_states;++k) {if(k%64==0) budget.check();signature.push_back(classes.edge_pair_colors[right?k*classes.edge_states_p+state:state*classes.edge_states_p+k]);}
133
+ // All ordinary attachment bonds share one class state; absent states
134
+ // also share one effect. This sufficient condition is deliberately
135
+ // conservative for arbitrary user annotations outside chemistry.
136
+ int kind=weights[i*p.n+j]?1:0;
137
+ auto old=edge_signatures.emplace(kind,signature);
138
+ if(!old.second&&old.first->second!=signature) return false;
139
+ }
140
+ }
141
+ }
142
+ return true;
143
+ }
144
+ int endpoint(const Problem &p,const SynkitHydrogenAttributes &attrs,bool right,Endpoint &out,Budget &budget) {
145
+ const int32_t *z=right?attrs.atomic_numbers_p:attrs.atomic_numbers_r;
146
+ const int32_t *isotope=right?attrs.isotopes_p:attrs.isotopes_r;
147
+ const int32_t *charge=right?attrs.charges_p:attrs.charges_r;
148
+ const int32_t *radical=right?attrs.radicals_p:attrs.radicals_r;
149
+ const int32_t *dummy=right?attrs.dummies_p:attrs.dummies_r;
150
+ const int32_t *stereo=right?attrs.stereo_p:attrs.stereo_r;
151
+ const int64_t *weights=right?p.b2:p.a2;
152
+ const int32_t *colors=right?p.node_colors_p:p.node_colors_r;
153
+ const int32_t *edges=right?p.edge_colors_p:p.edge_colors_r;
154
+ if(!z||!isotope||!charge||!radical||!dummy||!stereo) throw std::invalid_argument("Missing hydrogen eligibility metadata");
155
+ bool found=false;Values positions(p.n,-1);
156
+ for(int i=0;i<p.n;++i) {budget.check();if(stereo[i]) return SYNKIT_H_STEREO;if(z[i]==1) found=true;else {positions[i]=out.heavy.size();out.heavy.push_back(i);}}
157
+ if(!found) return SYNKIT_H_NO_HYDROGEN;
158
+ out.groups.resize(out.heavy.size());out.counts.assign(out.heavy.size(),0);
159
+ bool have_real=false,have_dummy=false;int real_color=0,dummy_color=0,bond_color=0;
160
+ for(int i=0;i<p.n;++i) if(z[i]==1) {
161
+ budget.check();
162
+ if(isotope[i]) return SYNKIT_H_ISOTOPE;
163
+ if(charge[i]||radical[i]) return SYNKIT_H_ELECTRON_STATE;
164
+ int parent=-1,degree=0;
165
+ for(int j=0;j<p.n;++j) if(weights[i*p.n+j]) {parent=j;++degree;}
166
+ if(dummy[i]) {
167
+ if(degree) return SYNKIT_H_DUMMY_BOND;
168
+ if(colors&&have_dummy&&colors[i]!=dummy_color) return SYNKIT_H_CLASS_ATTRIBUTES;
169
+ dummy_color=colors?colors[i]:0;have_dummy=true;out.reservoir.push_back(i);continue;
170
+ }
171
+ if(degree!=1) return SYNKIT_H_NONTERMINAL;
172
+ if(weights[i*p.n+parent]!=2||positions[parent]<0||z[parent]<=1) return SYNKIT_H_BOND_STATE;
173
+ if((colors&&have_real&&colors[i]!=real_color)||(edges&&have_real&&edges[i*p.n+parent]!=bond_color)) return SYNKIT_H_CLASS_ATTRIBUTES;
174
+ real_color=colors?colors[i]:0;bond_color=edges?edges[i*p.n+parent]:0;have_real=true;
175
+ out.groups[positions[parent]].push_back(i);++out.counts[positions[parent]];
176
+ }
177
+ return SYNKIT_H_SUPPORTED;
178
+ }
179
+ int32_t fresh_type(const Problem &p) {
180
+ std::set<int32_t> used(p.types_r,p.types_r+p.n);used.insert(p.types_p,p.types_p+p.n);
181
+ for(int64_t value=std::numeric_limits<int32_t>::min();value<=std::numeric_limits<int32_t>::max();++value)
182
+ if(!used.count(static_cast<int32_t>(value))) return value;
183
+ throw std::logic_error("No available H anchor type");
184
+ }
185
+ int reduce(const Problem &p,const SynkitHydrogenAttributes &attrs,Quotient &q,Budget &budget) {
186
+ int reason=endpoint(p,attrs,false,q.r,budget);if(reason) return reason;
187
+ reason=endpoint(p,attrs,true,q.p,budget);if(reason) return reason;
188
+ std::set<int32_t> hydrogen_types,heavy_types;
189
+ for(int i=0;i<p.n;++i) {
190
+ (attrs.atomic_numbers_r[i]==1?hydrogen_types:heavy_types).insert(p.types_r[i]);
191
+ (attrs.atomic_numbers_p[i]==1?hydrogen_types:heavy_types).insert(p.types_p[i]);
192
+ }
193
+ if(hydrogen_types.size()!=1||heavy_types.count(*hydrogen_types.begin())) return SYNKIT_H_CLASS_ATTRIBUTES;
194
+ if(q.r.heavy.size()!=q.p.heavy.size()) throw std::invalid_argument("Unequal heavy inventories");
195
+ int m=q.r.heavy.size(),n=m+1;int32_t anchor=fresh_type(p);
196
+ q.a.assign(n*n,0);q.b.assign(n*n,0);q.er.assign(n*n,0);q.ep.assign(n*n,0);
197
+ for(bool right:{false,true}) {
198
+ auto &side=right?q.p:q.r;auto &matrix=right?q.b:q.a;auto &types=right?q.tp:q.tr;
199
+ auto &colors=right?q.np:q.nr;auto &edgecolors=right?q.ep:q.er;
200
+ auto full=right?p.b2:p.a2;auto typed=right?p.types_p:p.types_r;
201
+ auto nodes=right?p.node_colors_p:p.node_colors_r;auto edges=right?p.edge_colors_p:p.edge_colors_r;
202
+ for(int i=0;i<m;++i) {
203
+ budget.check();
204
+ int source=side.heavy[i];types.push_back(typed[source]);colors.push_back(nodes?nodes[source]:0);
205
+ for(int j=0;j<m;++j) {matrix[i*n+j]=full[source*p.n+side.heavy[j]];edgecolors[i*n+j]=edges?edges[source*p.n+side.heavy[j]]:0;}
206
+ matrix[i*n+m]=matrix[m*n+i]=2*side.counts[i];
207
+ }
208
+ types.push_back(anchor);colors.push_back(0);
209
+ }
210
+ q.problem={1,n,q.a.data(),q.b.data(),q.tr.data(),q.tp.data(),q.nr.data(),q.np.data(),q.er.data(),q.ep.data()};
211
+ return SYNKIT_H_SUPPORTED;
212
+ }
213
+ struct HydrogenSearch {
214
+ const Problem &full;const Request &request;Quotient &q;
215
+ int64_t max_plans;Callback callback;void *userdata;Statistics &stats;SynkitHydrogenStatistics &hs;
216
+ Budget budget;int stop=0;bool plan_limit=false;std::exception_ptr failure;
217
+ Values mapping;std::vector<Values> rows,columns;
218
+ int64_t heavy_cost=0;
219
+ HydrogenSearch(const Problem &p,const Request &r,Quotient &reduced,int64_t plans,Callback cb,void *data,Statistics &s,SynkitHydrogenStatistics &h)
220
+ :full(p),request(r),q(reduced),max_plans(plans),callback(cb),userdata(data),stats(s),hs(h),budget(r) {}
221
+ static int flow(const int32_t *cells,int64_t cost,const char *,void *data) {
222
+ auto &self=*static_cast<HydrogenSearch*>(data);
223
+ try {
224
+ self.budget.check();
225
+ if(self.max_plans>=0&&self.hs.transport_plans>=self.max_plans) {self.plan_limit=true;throw Stop{SYNKIT_STOP_CANDIDATES};}
226
+ if(self.request.max_candidates>=0&&self.hs.transport_plans>=self.request.max_candidates) throw Stop{SYNKIT_STOP_CANDIDATES};
227
+ Values lifted=self.mapping;int n=self.rows.size();std::vector<size_t> source_offset(n,0),target_offset(n,0);
228
+ for(int i=0;i<n;++i) for(int j=0;j<n;++j) for(int count=0;count<cells[i*n+j];++count)
229
+ lifted[self.rows[i][source_offset[i]++]]=self.columns[j][target_offset[j]++];
230
+ int64_t total=self.heavy_cost+cost;
231
+ if(mapping_cost2(self.full,lifted)!=total) throw std::logic_error("Hydrogen quotient full cost mismatch");
232
+ ++self.hs.transport_plans;
233
+ if(self.callback(lifted.data(),total,self.userdata)) throw Stop{SYNKIT_STOP_CALLBACK};
234
+ self.budget.check();return 0;
235
+ } catch(const Stop &s) {self.stop=s.reason;return 1;}catch(...) {self.failure=std::current_exception();return 1;}
236
+ }
237
+ static int heavy(const int32_t *images,int64_t,void *data) {
238
+ auto &self=*static_cast<HydrogenSearch*>(data);
239
+ try {
240
+ self.budget.check();++self.hs.heavy_candidates;
241
+ int m=self.q.r.heavy.size();self.mapping.assign(self.full.n,-1);self.rows=self.q.r.groups;self.columns.clear();
242
+ self.heavy_cost=0;
243
+ for(int i=0;i<m;++i) {
244
+ if(images[i]<0||images[i]>=m) throw std::logic_error("H anchor not fixed");
245
+ self.mapping[self.q.r.heavy[i]]=self.q.p.heavy[images[i]];
246
+ self.columns.push_back(self.q.p.groups[images[i]]);
247
+ for(int j=0;j<i;++j) self.heavy_cost+=std::abs(self.full.a2[self.q.r.heavy[i]*self.full.n+self.q.r.heavy[j]]-
248
+ self.full.b2[self.q.p.heavy[images[i]]*self.full.n+self.q.p.heavy[images[j]]]);
249
+ }
250
+ self.rows.push_back(self.q.r.reservoir);self.columns.push_back(self.q.p.reservoir);
251
+ Values rcounts,pcounts;for(const auto &group:self.rows) rcounts.push_back(group.size());for(const auto &group:self.columns) pcounts.push_back(group.size());
252
+ SynkitHydrogenTransportStatistics transport{};
253
+ int query=(self.request.query==SYNKIT_MINIMUM_CLASSES)?SYNKIT_MINIMUM_CLASSES:self.request.query;
254
+ int64_t target=query==SYNKIT_MINIMUM_CLASSES?0:self.request.target2-self.heavy_cost;
255
+ if(query!=SYNKIT_MINIMUM_CLASSES&&target<0) return 0;
256
+ int result=synkit_mapper_hydrogen_transport(m+1,rcounts.data(),pcounts.data(),m,query,target,
257
+ self.request.seconds<0?-1:self.budget.remaining(),-1,-1,self.request.cancel_token,flow,&self,&transport);
258
+ self.hs.transport_nodes+=transport.nodes;self.hs.transport_seconds+=transport.elapsed_seconds;
259
+ if(result) throw std::runtime_error(h_error);
260
+ if(self.failure) return 1;
261
+ if(self.stop) return 1;
262
+ if(!transport.complete) {self.stop=transport.reason;return 1;}
263
+ return 0;
264
+ } catch(const Stop &s) {self.stop=s.reason;return 1;}catch(...) {self.failure=std::current_exception();return 1;}
265
+ }
266
+ };
267
+ } // namespace
268
+
269
+ extern "C" int synkit_mapper_hydrogen_abi() {return 1;}
270
+ extern "C" const char *synkit_mapper_hydrogen_error() {return h_error.c_str();}
271
+ extern "C" int synkit_mapper_hydrogen_transport(int n,const int32_t *rows,const int32_t *columns,int reservoir,int query,
272
+ int64_t target,double seconds,int64_t plans,int64_t nodes,void *cancel,SynkitHydrogenTransportCallback callback,void *data,SynkitHydrogenTransportStatistics *statistics) {
273
+ try {
274
+ h_error.clear();
275
+ if(!statistics||!callback||!rows||!columns||n<1||n>1025||reservoir< -1||reservoir>=n||query<0||query>2||target<0||
276
+ !std::isfinite(seconds)||(seconds<0&&seconds!=-1)||(plans<1&&plans!=-1)||(nodes<1&&nodes!=-1)) throw std::invalid_argument("Invalid hydrogen transport request");
277
+ int64_t left=0,right=0;
278
+ for(int i=0;i<n;++i) {if(rows[i]<0||columns[i]<0) throw std::invalid_argument("Negative hydrogen count");left+=rows[i];right+=columns[i];}
279
+ if(left!=right||left>4096) throw std::invalid_argument("Unbalanced or oversized hydrogen transport");
280
+ Transport transport(n,rows,columns,reservoir,query,target,seconds,plans,nodes,cancel,callback,data,*statistics);
281
+ try {transport.run();} catch(const Stop &stop) {statistics->complete=0;statistics->reason=stop.reason;}
282
+ statistics->elapsed_seconds=transport.budget.seconds();return 0;
283
+ } catch(const std::exception &e) {h_error=e.what();return -1;}catch(...) {h_error="Native hydrogen transport failed";return -1;}
284
+ }
285
+
286
+ extern "C" int synkit_mapper_hydrogen_solve(const Problem *p,const SynkitHydrogenAttributes *attrs,const Request *request,
287
+ int64_t max_plans,Callback callback,void *data,Statistics *statistics,SynkitHydrogenStatistics *hs) {
288
+ const auto invocation_start=Clock::now();
289
+ try {
290
+ h_error.clear();if(!p||!attrs||!request||!statistics||!hs||(max_plans<1&&max_plans!=-1)) throw std::invalid_argument("Invalid hydrogen solve request");
291
+ Budget total(*request);
292
+ validate(*p,*request);initialize(*statistics,*request);*hs={};hs->full_nodes=p->n;
293
+ if(request->classify||request->max_classes!=-1) return unsupported(*statistics);
294
+ if(!callback&&request->query!=SYNKIT_MINIMUM_PROOF) throw std::invalid_argument("Hydrogen enumeration requires callback");
295
+ auto start=Clock::now();Quotient q;
296
+ hs->eligibility_reason=reduce(*p,*attrs,q,total);hs->reduction_seconds=elapsed(start);
297
+ if(hs->eligibility_reason) {statistics->hydrogen_complete=0;statistics->elapsed_seconds=total.seconds();return unsupported(*statistics);}
298
+ hs->supported=1;hs->quotient_nodes=q.problem.n;statistics->hydrogen_complete=0;
299
+ Request raw=*request;raw.max_candidates=-1;raw.max_classes=-1;
300
+ if(raw.query==SYNKIT_EXACT_DISTANCE) raw.query=SYNKIT_AT_MOST_DISTANCE;
301
+ raw.seconds=request->seconds<0?-1:total.remaining();
302
+ Request lift_request=*request;lift_request.seconds=raw.seconds;
303
+ HydrogenSearch search(*p,lift_request,q,max_plans,callback,data,*statistics,*hs);
304
+ start=Clock::now();int result=synkit_mapper_solve(&q.problem,&raw,HydrogenSearch::heavy,&search,statistics);
305
+ hs->heavy_seconds=std::max(0.0,elapsed(start)-hs->transport_seconds);
306
+ if(result) {h_error=synkit_mapper_core_error();return -1;}
307
+ if(statistics->status==SYNKIT_UNSUPPORTED) hs->eligibility_reason=SYNKIT_H_REDUCED_BACKEND;
308
+ if(search.failure) std::rethrow_exception(search.failure);
309
+ if(search.stop) stopped(*statistics,search.stop);
310
+ hs->reason=search.plan_limit?11:search.stop;
311
+ hs->transport_complete=statistics->search_complete&&search.stop==0&&request->query!=SYNKIT_MINIMUM_PROOF;
312
+ statistics->hydrogen_complete=hs->transport_complete;statistics->candidate_count=hs->transport_plans;
313
+ statistics->labeled_count=-1;statistics->class_count=-1;statistics->elapsed_seconds=total.seconds();
314
+ return 0;
315
+ } catch(const Stop &stop) {
316
+ if(statistics) {stopped(*statistics,stop.reason);statistics->hydrogen_complete=0;statistics->elapsed_seconds=elapsed(invocation_start);}
317
+ if(hs) {hs->transport_complete=0;hs->reason=stop.reason;if(!hs->supported) hs->reduction_seconds=elapsed(invocation_start);}return 0;
318
+ } catch(const std::exception &e) {h_error=e.what();return -1;}catch(...) {h_error="Native hydrogen quotient failed";return -1;}
319
+ }
320
+
321
+ static int hydrogen_solve_classified_impl(const Problem *p,const SynkitHydrogenAttributes *attrs,const Request *request,
322
+ const SynkitClassProblem *classes,int64_t max_plans,int64_t max_nodes,SynkitClassCallback callback,void *data,
323
+ Statistics *statistics,SynkitHydrogenStatistics *hs,SynkitClassStatistics *cs,bool updates) {
324
+ const auto invocation_start=Clock::now();
325
+ try {
326
+ h_error.clear();
327
+ if(!p||!attrs||!request||!classes||!statistics||!hs||!cs||!callback||request->query==SYNKIT_MINIMUM_PROOF||p->n!=classes->n||(max_nodes<1&&max_nodes!=-1)) throw std::invalid_argument("Invalid classified hydrogen request");
328
+ initialize(*statistics,*request);*hs={};*cs={};hs->full_nodes=p->n;
329
+ validate(*p,*request);
330
+ Budget budget(*request);Request raw=*request;raw.classify=0;raw.max_classes=-1;
331
+ auto preflight_start=Clock::now();Endpoint left,right;
332
+ int eligibility=endpoint(*p,*attrs,false,left,budget);
333
+ if(!eligibility) eligibility=endpoint(*p,*attrs,true,right,budget);
334
+ if(!eligibility&&!uniform_hydrogen_classes(*p,*attrs,*classes,budget)) eligibility=SYNKIT_H_CLASS_ATTRIBUTES;
335
+ double preflight_seconds=elapsed(preflight_start);
336
+ if(eligibility) {
337
+ initialize(*statistics,*request);*hs={};*cs={};hs->full_nodes=p->n;
338
+ hs->eligibility_reason=eligibility;hs->reduction_seconds=preflight_seconds;
339
+ statistics->classification_complete=0;statistics->hydrogen_complete=0;
340
+ statistics->elapsed_seconds=budget.seconds();
341
+ return unsupported(*statistics);
342
+ }
343
+ raw.seconds=request->seconds<0?-1:budget.remaining();
344
+ struct Batch {int n;Values maps;std::vector<int64_t> costs;std::exception_ptr failure;};
345
+ Batch batch{p->n,{}, {},nullptr};
346
+ auto remember=[](const int32_t *mapping,int64_t cost,void *ptr)->int {auto &b=*static_cast<Batch*>(ptr);try {b.maps.insert(b.maps.end(),mapping,mapping+b.n);b.costs.push_back(cost);return 0;}catch(...) {b.failure=std::current_exception();return 1;}};
347
+ *cs={};int result=synkit_mapper_hydrogen_solve(p,attrs,&raw,max_plans,remember,&batch,statistics,hs);
348
+ hs->reduction_seconds+=preflight_seconds;
349
+ statistics->classification_complete=0;
350
+ if(result) return result;
351
+ if(batch.failure) std::rethrow_exception(batch.failure);
352
+ if(statistics->status==SYNKIT_UNSUPPORTED) return 0;
353
+ auto classify=updates?synkit_mapper_classify_batch_updates_with_cancel:
354
+ synkit_mapper_classify_batch_with_cancel;
355
+ result=classify(classes,batch.costs.size(),batch.maps.data(),batch.costs.data(),
356
+ request->seconds<0?-1:budget.remaining(),max_nodes,request->max_classes,request->cancel_token,callback,data,cs);
357
+ statistics->classification_complete=cs->complete;statistics->class_count=cs->classes;
358
+ statistics->classification_seconds=cs->elapsed_seconds;statistics->elapsed_seconds=budget.seconds();
359
+ if(result) {h_error=synkit_mapper_classification_error();return result;}
360
+ if(!cs->complete&&statistics->status==SYNKIT_FINISHED) {const int reasons[]={0,1,2,4,5,10};statistics->status=SYNKIT_LIMIT;statistics->reason=reasons[cs->reason];}
361
+ return 0;
362
+ } catch(const Stop &stop) {
363
+ if(statistics) {stopped(*statistics,stop.reason);statistics->classification_complete=statistics->hydrogen_complete=0;statistics->elapsed_seconds=elapsed(invocation_start);}
364
+ if(hs) {hs->transport_complete=0;hs->reason=stop.reason;if(!hs->supported) hs->reduction_seconds=elapsed(invocation_start);}return 0;
365
+ } catch(const std::exception &e) {h_error=e.what();return -1;}catch(...) {h_error="Classified hydrogen solve failed";return -1;}
366
+ }
367
+
368
+ extern "C" int synkit_mapper_hydrogen_solve_classified(const Problem *p,const SynkitHydrogenAttributes *attrs,const Request *request,
369
+ const SynkitClassProblem *classes,int64_t max_plans,int64_t max_nodes,SynkitClassCallback callback,void *data,
370
+ Statistics *statistics,SynkitHydrogenStatistics *hs,SynkitClassStatistics *cs) {
371
+ return hydrogen_solve_classified_impl(p,attrs,request,classes,max_plans,max_nodes,
372
+ callback,data,statistics,hs,cs,false);
373
+ }
374
+
375
+ extern "C" int synkit_mapper_hydrogen_solve_classified_updates(const Problem *p,const SynkitHydrogenAttributes *attrs,const Request *request,
376
+ const SynkitClassProblem *classes,int64_t max_plans,int64_t max_nodes,SynkitClassCallback callback,void *data,
377
+ Statistics *statistics,SynkitHydrogenStatistics *hs,SynkitClassStatistics *cs) {
378
+ return hydrogen_solve_classified_impl(p,attrs,request,classes,max_plans,max_nodes,
379
+ callback,data,statistics,hs,cs,true);
380
+ }
@@ -0,0 +1,57 @@
1
+ # Weighted full-bijection common-edge mapper
2
+
3
+ This module constructs an explicit association graph and enumerates size-n
4
+ cliques. It does not invoke or relabel the existing assignment B&B/PABS kernel.
5
+ It is an objective-correct weighted common-edge architecture, not a claim that
6
+ ordinary binary MCES automatically solves the Lewis objective.
7
+
8
+ For nonnegative symmetric loop-free integer matrices A2 and B2, let
9
+ C = sum(i<k) A2[i,k] + sum(j<l) B2[j,l]. The common doubled chemical distance of
10
+ a compatible bijection p is
11
+
12
+ D2(p) = sum(i<k) abs(A2[i,k] - B2[p(i),p(k)])
13
+ = C - 2 * sum(i<k) min(A2[i,k], B2[p(i),p(k)]).
14
+
15
+ The equality follows term by term from abs(a-b)=a+b-2*min(a,b). C is independent
16
+ of p because p is a full bijection. Therefore maximizing weighted common-edge
17
+ overlap is exactly equivalent to minimizing the registered weighted distance.
18
+ Forced electron anchors, explicit H and typed dummy padding are already in
19
+ these matrices/types; the proof includes them without a separate electron term.
20
+ Half-integer chemical weights are exact after the common doubling conversion.
21
+ Charge, radical, dummy and stereo class attributes do not restrict compatibility.
22
+
23
+ Association vertices are all type-compatible correspondences (i,j). Two are
24
+ adjacent exactly when both source and target indices differ; the edge weight is
25
+ min(A2[i,k],B2[j,l]). Every n-clique uses every source and target once and hence
26
+ represents a compatible bijection. Conversely each compatible bijection yields
27
+ one n-clique. This remains true for zero-weight common edges, which are retained
28
+ as compatibility edges rather than deleted. Deleting them would incorrectly
29
+ restrict the feasible mapping space.
30
+
31
+ Traversal intersects the remaining ordered vertices with the selected vertex's
32
+ neighbors and retains only later vertices. Thus every clique has one unique
33
+ increasing-ID construction path. Source indices form a proper coloring of the
34
+ association graph. A full clique needs every missing source color: absence of
35
+ one color safely prunes that branch. Bounds sum independent maxima of weights
36
+ from each missing color into the current clique, plus an independent maximum
37
+ for each pair of missing colors. Dropping mutual consistency only increases
38
+ that overlap upper bound. The analogous sum of minimum current-clique
39
+ contributions is a lower bound because all future edge weights are nonnegative.
40
+ These bounds support maximum-overlap proof, fixed-overlap shells and overlap
41
+ threshold balls. No node/class symmetry equivalence is assumed for pruning.
42
+
43
+ The minimum request first proves maximum overlap, then separately traverses its
44
+ exact shell. Proof-only is separately named. Exact D2 queries whose C-target is
45
+ odd are empty; at-most queries use ceil((C-target)/2). Every emitted permutation
46
+ is independently rescored against the original matrices. States, candidate cap,
47
+ shared deadline/cancellation, and accounted graph/candidate memory controls keep
48
+ minimum proof separate from enumeration completion. Memory accounting is not
49
+ process RSS and excludes allocator overhead and transient per-node bound arrays;
50
+ its scope is reported explicitly in metadata. Frontier and native-class caps are
51
+ unsupported in this raw module. The common class pipeline can process outputs.
52
+
53
+ The explicit graph is limited to n<=256 and at most 8192 compatible association
54
+ vertices. This is an exploratory exact implementation with tiny-instance and
55
+ chemical conformance evidence, not a published-engine reproduction or a speed
56
+ claim. Model construction is quadratic in association vertices; molecular H
57
+ multiplicity can make its search expensive.