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,74 @@
1
+ """Strict stereo-layer validation for ITS/DPO construction."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Mapping
6
+
7
+ import networkx as nx
8
+
9
+ from synkit.Graph.Stereo import (
10
+ StereoRefusal,
11
+ StereoRefusalCode,
12
+ StereoValue,
13
+ descriptor_graph_support_errors,
14
+ )
15
+
16
+
17
+ class StereoITSValidationError(ValueError):
18
+ """Raised when a stereo-bearing graph violates its support contract."""
19
+
20
+ def __init__(self, refusals: tuple[StereoRefusal, ...]) -> None:
21
+ self.refusals = refusals
22
+ detail = "; ".join(f"{item.targets}: {item.detail}" for item in refusals)
23
+ super().__init__(f"Invalid ITS stereo layer: {detail}")
24
+
25
+
26
+ def stereo_support_refusals(
27
+ graph: nx.Graph,
28
+ *,
29
+ side: str,
30
+ registry: Mapping[str, StereoValue] | None = None,
31
+ ) -> tuple[StereoRefusal, ...]:
32
+ """Return deterministic support/refusal evidence for one stereo layer."""
33
+ values = (
34
+ registry if registry is not None else graph.graph.get("stereo_descriptors", {})
35
+ )
36
+ refusals = []
37
+ for target, descriptor in sorted(values.items()):
38
+ errors = descriptor_graph_support_errors(
39
+ graph,
40
+ descriptor,
41
+ registry_key=target,
42
+ )
43
+ if errors:
44
+ refusals.append(
45
+ StereoRefusal(
46
+ StereoRefusalCode.INVALID_REFERENCE,
47
+ f"{side}: " + "; ".join(errors),
48
+ (target,),
49
+ )
50
+ )
51
+ return tuple(refusals)
52
+
53
+
54
+ def validate_stereo_support(
55
+ graph: nx.Graph,
56
+ *,
57
+ side: str,
58
+ registry: Mapping[str, StereoValue] | None = None,
59
+ ) -> None:
60
+ """Raise one aggregate error when any descriptor support is invalid."""
61
+ refusals = stereo_support_refusals(
62
+ graph,
63
+ side=side,
64
+ registry=registry,
65
+ )
66
+ if refusals:
67
+ raise StereoITSValidationError(refusals)
68
+
69
+
70
+ __all__ = [
71
+ "StereoITSValidationError",
72
+ "stereo_support_refusals",
73
+ "validate_stereo_support",
74
+ ]
@@ -0,0 +1,107 @@
1
+ """Mechanistic transition graphs and certified occurrence processes."""
2
+
3
+ from .process import (
4
+ ChoiceWitness,
5
+ IndependenceWitness,
6
+ LinearExtensionEquivalence,
7
+ MaterialBinding,
8
+ MaterialOccurrence,
9
+ OccurrenceProcess,
10
+ OccurrenceProcessFamily,
11
+ ProcessAlternative,
12
+ ProcessError,
13
+ ProcessIssue,
14
+ ProcessIssueCode,
15
+ RuleOccurrence,
16
+ )
17
+ from .series_parallel import SeriesParallelDecomposition, detect_series_parallel
18
+ from .inventory import StockBound, StockWitness, minimum_initial_stock
19
+ from .history import (
20
+ ABSENT,
21
+ CarrierState,
22
+ ConfigurationCut,
23
+ EdgeLineage,
24
+ HistoryError,
25
+ HistoryIssue,
26
+ HistoryIssueCode,
27
+ HistoryReplay,
28
+ NodeLineage,
29
+ OccurrenceMTG,
30
+ OccurrenceMTGAlternative,
31
+ OccurrenceMTGFamily,
32
+ )
33
+ from .gluing import (
34
+ CrossIndependenceWitness,
35
+ GluingError,
36
+ GluingIssueCode,
37
+ HistoryComposition,
38
+ HistoryEmbedding,
39
+ PortGluing,
40
+ compose_histories,
41
+ )
42
+ from .queries import cooccurrence_configuration
43
+ from .local import (
44
+ CoordinateCut,
45
+ GroundedLocalEvent,
46
+ LocalCoordinateHistory,
47
+ LocalEventRecord,
48
+ LocalHistoryError,
49
+ build_local_coordinate_history,
50
+ )
51
+ from .observation import (
52
+ ObservationCut,
53
+ ObservationProjection,
54
+ build_observation_projection,
55
+ )
56
+ from .realization import CoordinateRealization, realize_coordinate_history
57
+
58
+ __all__ = [
59
+ "CoordinateRealization",
60
+ "realize_coordinate_history",
61
+ "ObservationCut",
62
+ "ObservationProjection",
63
+ "build_observation_projection",
64
+ "CoordinateCut",
65
+ "GroundedLocalEvent",
66
+ "LocalCoordinateHistory",
67
+ "LocalEventRecord",
68
+ "LocalHistoryError",
69
+ "build_local_coordinate_history",
70
+ "ChoiceWitness",
71
+ "ABSENT",
72
+ "CarrierState",
73
+ "ConfigurationCut",
74
+ "CrossIndependenceWitness",
75
+ "EdgeLineage",
76
+ "HistoryError",
77
+ "GluingError",
78
+ "GluingIssueCode",
79
+ "HistoryComposition",
80
+ "HistoryEmbedding",
81
+ "HistoryIssue",
82
+ "HistoryIssueCode",
83
+ "HistoryReplay",
84
+ "IndependenceWitness",
85
+ "LinearExtensionEquivalence",
86
+ "MaterialBinding",
87
+ "MaterialOccurrence",
88
+ "NodeLineage",
89
+ "OccurrenceMTG",
90
+ "OccurrenceMTGAlternative",
91
+ "OccurrenceMTGFamily",
92
+ "OccurrenceProcess",
93
+ "OccurrenceProcessFamily",
94
+ "ProcessAlternative",
95
+ "ProcessError",
96
+ "ProcessIssue",
97
+ "ProcessIssueCode",
98
+ "PortGluing",
99
+ "RuleOccurrence",
100
+ "SeriesParallelDecomposition",
101
+ "StockBound",
102
+ "StockWitness",
103
+ "detect_series_parallel",
104
+ "compose_histories",
105
+ "cooccurrence_configuration",
106
+ "minimum_initial_stock",
107
+ ]
@@ -0,0 +1,451 @@
1
+ """Explicit port gluing of occurrence histories with retained origin maps.
2
+
3
+ This operation composes supplied material diagrams, not arbitrary guarded rule
4
+ spans. Local applications and finite commutation witnesses are checked; frame
5
+ locality under arbitrary spectators is an additional execution hypothesis.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from dataclasses import dataclass
11
+ from enum import Enum
12
+ from typing import Hashable, Iterable, Mapping
13
+
14
+ import networkx as nx
15
+
16
+ from synkit.Graph.Morphism import (
17
+ LLGError,
18
+ LLGMorphism,
19
+ LewisLabelledGraph,
20
+ derive_electron_labeled_graph,
21
+ is_electron_schema,
22
+ )
23
+ from synkit.Rule.Apply import DPOApplication, DPOError, apply_dpo
24
+ from synkit.Rule.Compose import CommutationCertificate
25
+
26
+ from .history import Carrier, HistoryError, OccurrenceMTG
27
+ from .process import (
28
+ IndependenceWitness,
29
+ MaterialBinding,
30
+ MaterialOccurrence,
31
+ OccurrenceProcess,
32
+ ProcessError,
33
+ RuleOccurrence,
34
+ )
35
+
36
+
37
+ class GluingIssueCode(str, Enum):
38
+ """Stable refusals for the supplied history-gluing premises."""
39
+
40
+ UNKNOWN_PORT = "GLUING_UNKNOWN_PORT"
41
+ NOT_BOUNDARY = "GLUING_NOT_BOUNDARY"
42
+ PORT_REUSED = "GLUING_PORT_REUSED"
43
+ PORT_ISOMORPHISM = "GLUING_PORT_ISOMORPHISM"
44
+ SCHEMA_MISMATCH = "GLUING_SCHEMA_MISMATCH"
45
+ LOCAL_APPLICATION = "GLUING_LOCAL_APPLICATION"
46
+ INVALID_CERTIFICATE = "GLUING_INVALID_CERTIFICATE"
47
+
48
+
49
+ class GluingError(ValueError):
50
+ """A refused premise, retaining the underlying source failure if present."""
51
+
52
+ def __init__(self, code: GluingIssueCode, message: str):
53
+ self.code = code
54
+ super().__init__(message)
55
+
56
+
57
+ @dataclass(frozen=True)
58
+ class PortGluing:
59
+ """One selected output/input copy pairing and output-to-input atom map."""
60
+
61
+ output_material: str
62
+ input_material: str
63
+ mapping: tuple[tuple[Hashable, Hashable], ...]
64
+
65
+ def __post_init__(self) -> None:
66
+ pairs = (
67
+ self.mapping.items() if isinstance(self.mapping, Mapping) else self.mapping
68
+ )
69
+ object.__setattr__(self, "mapping", tuple(sorted(pairs, key=repr)))
70
+
71
+
72
+ @dataclass(frozen=True)
73
+ class CrossIndependenceWitness:
74
+ """A left/right event pair, named in the two original namespaces."""
75
+
76
+ left_event: str
77
+ right_event: str
78
+ certificate: CommutationCertificate
79
+
80
+
81
+ @dataclass(frozen=True)
82
+ class HistoryEmbedding:
83
+ """Explicit event, copy, atom-origin and historic-bond transport maps."""
84
+
85
+ event_mapping: tuple[tuple[str, str], ...]
86
+ material_mapping: tuple[tuple[str, str], ...]
87
+ carrier_mapping: tuple[tuple[Carrier, Carrier], ...]
88
+ node_lineage_mapping: tuple[tuple[str, str], ...]
89
+ edge_lineage_mapping: tuple[tuple[str, str], ...]
90
+
91
+
92
+ def _validate_ports(
93
+ left: OccurrenceMTG, right: OccurrenceMTG, ports: tuple[PortGluing, ...]
94
+ ) -> None:
95
+ if left.schema != right.schema:
96
+ raise GluingError(
97
+ GluingIssueCode.SCHEMA_MISMATCH, "Histories must have the same schema."
98
+ )
99
+ used_left, used_right = set(), set()
100
+ for port in ports:
101
+ if (
102
+ port.output_material not in left.material_by_id
103
+ or port.input_material not in right.material_by_id
104
+ ):
105
+ raise GluingError(
106
+ GluingIssueCode.UNKNOWN_PORT, "A port names an unknown material copy."
107
+ )
108
+ if (
109
+ port.output_material not in left.final_material_ids
110
+ or port.input_material not in right.initial_material_ids
111
+ ):
112
+ raise GluingError(
113
+ GluingIssueCode.NOT_BOUNDARY,
114
+ "Ports must be an unconsumed output and unproduced input.",
115
+ )
116
+ if port.output_material in used_left or port.input_material in used_right:
117
+ raise GluingError(
118
+ GluingIssueCode.PORT_REUSED,
119
+ "Port pairings must be injective on both sides.",
120
+ )
121
+ used_left.add(port.output_material)
122
+ used_right.add(port.input_material)
123
+ output = left.material_by_id[port.output_material].value
124
+ input_value = right.material_by_id[port.input_material].value
125
+ try:
126
+ if len(dict(port.mapping)) != len(port.mapping):
127
+ raise GluingError(
128
+ GluingIssueCode.PORT_ISOMORPHISM,
129
+ "A port map repeats an output atom.",
130
+ )
131
+ isomorphism = LLGMorphism(output, input_value, port.mapping)
132
+ if not isomorphism.is_isomorphism:
133
+ raise GluingError(
134
+ GluingIssueCode.PORT_ISOMORPHISM,
135
+ "A port map must cover the whole input copy.",
136
+ )
137
+ except LLGError as error:
138
+ raise GluingError(
139
+ GluingIssueCode.PORT_ISOMORPHISM,
140
+ "A port map is not a semantic graph isomorphism.",
141
+ ) from error
142
+
143
+
144
+ def _copy_maps(
145
+ source: OccurrenceMTG, side: str, glued: Mapping[str, PortGluing]
146
+ ) -> tuple[dict[str, str], dict[str, str], dict[Carrier, Carrier]]:
147
+ events = {
148
+ event.occurrence_id: f"{side}:{event.occurrence_id}" for event in source.events
149
+ }
150
+ materials, carriers = {}, {}
151
+ for material in source.materials:
152
+ identifier = material.occurrence_id
153
+ port = glued.get(identifier)
154
+ target = (
155
+ f"left:{port.output_material}"
156
+ if port is not None
157
+ else f"{side}:{identifier}"
158
+ )
159
+ inverse = (
160
+ {after: before for before, after in port.mapping}
161
+ if port is not None
162
+ else None
163
+ )
164
+ materials[identifier] = target
165
+ for node in material.value.node_ids:
166
+ carriers[identifier, node] = (
167
+ target,
168
+ inverse[node] if inverse is not None else node,
169
+ )
170
+ return events, materials, carriers
171
+
172
+
173
+ def _transport_event(
174
+ event: RuleOccurrence,
175
+ events: Mapping[str, str],
176
+ materials: Mapping[str, str],
177
+ carriers: Mapping[Carrier, Carrier],
178
+ ) -> RuleOccurrence:
179
+ def bindings(source: tuple[MaterialBinding, ...]) -> tuple[MaterialBinding, ...]:
180
+ return tuple(
181
+ MaterialBinding(
182
+ materials[binding.material_id],
183
+ binding.endpoint_nodes,
184
+ tuple(
185
+ (node, carriers[binding.material_id, carrier][1])
186
+ for node, carrier in binding.mapping
187
+ ),
188
+ )
189
+ for binding in source
190
+ )
191
+
192
+ return RuleOccurrence(
193
+ events[event.occurrence_id],
194
+ event.rule,
195
+ bindings(event.inputs),
196
+ bindings(event.outputs),
197
+ )
198
+
199
+
200
+ def _transport_witness(
201
+ witness: IndependenceWitness, events: Mapping[str, str]
202
+ ) -> IndependenceWitness:
203
+ return IndependenceWitness(
204
+ events[witness.first_event], events[witness.second_event], witness.certificate
205
+ )
206
+
207
+
208
+ def _parts(
209
+ left: OccurrenceMTG,
210
+ right: OccurrenceMTG,
211
+ ports: tuple[PortGluing, ...],
212
+ cross: tuple[CrossIndependenceWitness, ...],
213
+ ) -> tuple[tuple, tuple, tuple, tuple, tuple]:
214
+ for source in (left, right):
215
+ replay = source.replay()
216
+ if not replay.valid:
217
+ raise HistoryError(*replay.issues)
218
+ _validate_ports(left, right, ports)
219
+ glued = {port.input_material: port for port in ports}
220
+ left_maps = _copy_maps(left, "left", {})
221
+ right_maps = _copy_maps(right, "right", glued)
222
+ materials = tuple(
223
+ MaterialOccurrence(left_maps[1][m.occurrence_id], m.value)
224
+ for m in left.materials
225
+ ) + tuple(
226
+ MaterialOccurrence(right_maps[1][m.occurrence_id], m.value)
227
+ for m in right.materials
228
+ if m.occurrence_id not in glued
229
+ )
230
+ events = tuple(_transport_event(e, *left_maps) for e in left.events) + tuple(
231
+ _transport_event(e, *right_maps) for e in right.events
232
+ )
233
+ witnesses = tuple(
234
+ _transport_witness(w, left_maps[0]) for w in left.independence
235
+ ) + tuple(_transport_witness(w, right_maps[0]) for w in right.independence)
236
+ for witness in cross:
237
+ if (
238
+ witness.left_event not in left_maps[0]
239
+ or witness.right_event not in right_maps[0]
240
+ ):
241
+ raise GluingError(
242
+ GluingIssueCode.INVALID_CERTIFICATE,
243
+ "A cross witness names an unknown source event.",
244
+ )
245
+ witnesses += tuple(
246
+ IndependenceWitness(
247
+ left_maps[0][w.left_event], right_maps[0][w.right_event], w.certificate
248
+ )
249
+ for w in cross
250
+ )
251
+ if len({w.key for w in witnesses}) != len(witnesses):
252
+ raise GluingError(
253
+ GluingIssueCode.INVALID_CERTIFICATE,
254
+ "An event pair has duplicate commutation evidence.",
255
+ )
256
+ return materials, events, witnesses, left_maps, right_maps
257
+
258
+
259
+ def _embedding(
260
+ source: OccurrenceMTG, target: OccurrenceMTG, maps: tuple
261
+ ) -> HistoryEmbedding:
262
+ events, materials, carriers = maps
263
+ target_nodes = target.node_lineage_by_carrier
264
+ target_edges = {
265
+ carrier: edge.lineage_id
266
+ for edge in target.edge_lineages
267
+ for carrier in edge.members
268
+ }
269
+ nodes, edges = [], []
270
+ for lineage in source.node_lineages:
271
+ images = {target_nodes[carriers[carrier]] for carrier in lineage.members}
272
+ if len(images) != 1:
273
+ raise GluingError(
274
+ GluingIssueCode.INVALID_CERTIFICATE,
275
+ "Gluing split a source atom lineage.",
276
+ )
277
+ nodes.append((lineage.lineage_id, images.pop()))
278
+ for lineage in source.edge_lineages:
279
+ images = set()
280
+ for material, edge in lineage.members:
281
+ transported = frozenset(carriers[material, node][1] for node in edge)
282
+ images.add(target_edges[materials[material], transported])
283
+ if len(images) != 1:
284
+ raise GluingError(
285
+ GluingIssueCode.INVALID_CERTIFICATE,
286
+ "Gluing split a source bond lineage.",
287
+ )
288
+ edges.append((lineage.lineage_id, images.pop()))
289
+ return HistoryEmbedding(
290
+ tuple(sorted(events.items())),
291
+ tuple(sorted(materials.items())),
292
+ tuple(sorted(carriers.items(), key=repr)),
293
+ tuple(nodes),
294
+ tuple(edges),
295
+ )
296
+
297
+
298
+ def _event_host(
299
+ event: RuleOccurrence, materials: Mapping[str, MaterialOccurrence]
300
+ ) -> LewisLabelledGraph:
301
+ graph = nx.Graph()
302
+ for binding in event.inputs:
303
+ material = materials[binding.material_id].value
304
+ inverse = {carrier: node for node, carrier in binding.mapping}
305
+ for carrier in material.node_ids:
306
+ graph.add_node(inverse[carrier], **material.node_labels(carrier))
307
+ for edge in material.edge_keys:
308
+ left, right = tuple(edge)
309
+ graph.add_edge(inverse[left], inverse[right], **material.edge_labels(edge))
310
+ if is_electron_schema(event.rule.left.schema):
311
+ graph = derive_electron_labeled_graph(graph)
312
+ return LewisLabelledGraph.from_networkx(graph, event.rule.left.schema)
313
+
314
+
315
+ def _local_applications(
316
+ events: tuple[RuleOccurrence, ...], materials: Mapping[str, MaterialOccurrence]
317
+ ) -> tuple[tuple[str, DPOApplication], ...]:
318
+ applications = []
319
+ for event in events:
320
+ try:
321
+ application = apply_dpo(
322
+ event.rule,
323
+ _event_host(event, materials),
324
+ {node: node for node in event.rule.left.node_ids},
325
+ )
326
+ except DPOError as error:
327
+ raise GluingError(
328
+ GluingIssueCode.LOCAL_APPLICATION,
329
+ f"Event {event.occurrence_id!r} is not admitted on its bound local inputs.",
330
+ ) from error
331
+ applications.append((event.occurrence_id, application))
332
+ return tuple(applications)
333
+
334
+
335
+ def _applications_valid(
336
+ events: tuple[RuleOccurrence, ...],
337
+ applications: tuple,
338
+ materials: Mapping[str, MaterialOccurrence],
339
+ ) -> bool:
340
+ observed = dict(applications)
341
+ if len(observed) != len(applications) or set(observed) != {
342
+ e.occurrence_id for e in events
343
+ }:
344
+ return False
345
+ for event in events:
346
+ application = observed[event.occurrence_id]
347
+ certificate = application.certificate
348
+ checks = (
349
+ certificate.rule is event.rule,
350
+ certificate.host == _event_host(event, materials),
351
+ dict(certificate.match)
352
+ == {node: node for node in event.rule.left.node_ids},
353
+ application.result == certificate.result,
354
+ certificate.replay().valid,
355
+ LLGMorphism(
356
+ event.rule.right, application.result, certificate.right_to_result
357
+ ).is_isomorphism,
358
+ )
359
+ if not all(checks):
360
+ return False
361
+ return True
362
+
363
+
364
+ @dataclass(frozen=True)
365
+ class HistoryComposition:
366
+ """A realized port gluing with checkable source and lineage correspondence."""
367
+
368
+ left: OccurrenceMTG
369
+ right: OccurrenceMTG
370
+ ports: tuple[PortGluing, ...]
371
+ cross_independence: tuple[CrossIndependenceWitness, ...]
372
+ history: OccurrenceMTG
373
+ left_embedding: HistoryEmbedding
374
+ right_embedding: HistoryEmbedding
375
+ local_applications: tuple[tuple[str, DPOApplication], ...]
376
+
377
+ def replay(self) -> bool:
378
+ """Check the supplied quotient, transport maps and finite applications.
379
+
380
+ :return: Whether all recorded construction premises validate.
381
+ """
382
+ try:
383
+ materials, events, witnesses, left_maps, right_maps = _parts(
384
+ self.left, self.right, self.ports, self.cross_independence
385
+ )
386
+ checks = (
387
+ self.history.replay().valid,
388
+ self.history.schema == self.left.schema,
389
+ self.history.materials == materials,
390
+ self.history.events == events,
391
+ all(
392
+ actual.rule is expected.rule
393
+ for actual, expected in zip(self.history.events, events)
394
+ ),
395
+ self.history.independence == witnesses,
396
+ self.left_embedding == _embedding(self.left, self.history, left_maps),
397
+ self.right_embedding
398
+ == _embedding(self.right, self.history, right_maps),
399
+ _applications_valid(
400
+ events, self.local_applications, self.history.material_by_id
401
+ ),
402
+ )
403
+ return all(checks)
404
+ except (GluingError, HistoryError, ProcessError, DPOError, LLGError, KeyError):
405
+ return False
406
+
407
+
408
+ def compose_histories(
409
+ left: OccurrenceMTG,
410
+ right: OccurrenceMTG,
411
+ ports: Iterable[PortGluing] = (),
412
+ *,
413
+ cross_independence: Iterable[CrossIndependenceWitness] = (),
414
+ process_id: str = "composition",
415
+ ) -> HistoryComposition:
416
+ """Glue selected left outputs to right inputs using explicit isomorphisms.
417
+
418
+ Empty port selection is the parallel product. Internal IDs are renamed
419
+ apart; unmatched ports remain boundaries. Every new incomparable pair must
420
+ carry supplied finite commutation evidence. Rule and guard objects stay in
421
+ their original local coordinates. No schedules are selected or enumerated.
422
+
423
+ :param left: Validated first history.
424
+ :param right: Validated second history with the same schema.
425
+ :param ports: Injective output/input copy pairings with explicit atom maps.
426
+ :param cross_independence: Finite witnesses for new incomparable pairs.
427
+ :param process_id: Identity of the resulting history.
428
+ :return: Composition with source embeddings and local DPO certificates.
429
+ """
430
+ ports, cross = tuple(ports), tuple(cross_independence)
431
+ materials, events, witnesses, left_maps, right_maps = _parts(
432
+ left, right, ports, cross
433
+ )
434
+ process = OccurrenceProcess(process_id, materials, events, witnesses)
435
+ history = OccurrenceMTG.from_process(process, empty_schema=left.schema)
436
+ result = HistoryComposition(
437
+ left,
438
+ right,
439
+ ports,
440
+ cross,
441
+ history,
442
+ _embedding(left, history, left_maps),
443
+ _embedding(right, history, right_maps),
444
+ _local_applications(events, history.material_by_id),
445
+ )
446
+ if not result.replay():
447
+ raise GluingError(
448
+ GluingIssueCode.INVALID_CERTIFICATE,
449
+ "The history-gluing certificate does not replay.",
450
+ )
451
+ return result