synkit 1.1.0__tar.gz → 1.1.1__tar.gz

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 (227) hide show
  1. {synkit-1.1.0 → synkit-1.1.1}/PKG-INFO +1 -1
  2. {synkit-1.1.0 → synkit-1.1.1}/pyproject.toml +1 -1
  3. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Topo/canon.py +59 -254
  4. synkit-1.1.1/synkit/CRN/Topo/wl_canon.py +301 -0
  5. synkit-1.1.1/synkit/Graph/Matcher/auto_est.py +779 -0
  6. synkit-1.1.1/synkit/Graph/Matcher/automorphism.py +307 -0
  7. synkit-1.1.1/synkit/Graph/Matcher/dedup_matches.py +243 -0
  8. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Matcher/partial_matcher.py +5 -1
  9. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Reactor/syn_reactor.py +16 -5
  10. synkit-1.1.0/synkit/Graph/Matcher/auto_est.py +0 -496
  11. synkit-1.1.0/synkit/Graph/Matcher/automorphism.py +0 -292
  12. {synkit-1.1.0 → synkit-1.1.1}/.gitignore +0 -0
  13. {synkit-1.1.0 → synkit-1.1.1}/LICENSE +0 -0
  14. {synkit-1.1.0 → synkit-1.1.1}/README.md +0 -0
  15. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/DAG/__init__.py +0 -0
  16. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/DAG/crn.py +0 -0
  17. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/DAG/dag.py +0 -0
  18. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/DAG/dcrn.py +0 -0
  19. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/DAG/mod_crn.py +0 -0
  20. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/DAG/sf.py +0 -0
  21. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/DAG/target_dag.py +0 -0
  22. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Hypergraph/__init__.py +0 -0
  23. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Hypergraph/backend.py +0 -0
  24. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Hypergraph/conversion.py +0 -0
  25. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Hypergraph/dag.py +0 -0
  26. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Hypergraph/hyperedge.py +0 -0
  27. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Hypergraph/hypergraph.py +0 -0
  28. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Hypergraph/rxn.py +0 -0
  29. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Path/__init__.py +0 -0
  30. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Path/realizability.py +0 -0
  31. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Petri/__init__.py +0 -0
  32. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Petri/analyzer.py +0 -0
  33. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Petri/net.py +0 -0
  34. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Petri/persistence.py +0 -0
  35. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Petri/semiflows.py +0 -0
  36. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Petri/structure.py +0 -0
  37. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Props/__init__.py +0 -0
  38. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Props/deficiency.py +0 -0
  39. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Props/injectivity.py +0 -0
  40. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Props/stoich.py +0 -0
  41. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Props/thermo.py +0 -0
  42. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Props/utils.py +0 -0
  43. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Stochastic/__init__.py +0 -0
  44. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Topo/__init__.py +0 -0
  45. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/Topo/automorphism.py +0 -0
  46. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/__init__.py +0 -0
  47. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/__init__.py +0 -0
  48. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/configs/__init__.py +0 -0
  49. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/configs/loader.py +0 -0
  50. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/configs/models.py +0 -0
  51. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/constants.py +0 -0
  52. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/crn_formula.py +0 -0
  53. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/enumerator.py +0 -0
  54. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/exceptions.py +0 -0
  55. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/explorer.py +0 -0
  56. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/helpers.py +0 -0
  57. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/motif.py +0 -0
  58. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/network.py +0 -0
  59. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/pathway.py +0 -0
  60. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/properties.py +0 -0
  61. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/reaction.py +0 -0
  62. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/utils.py +0 -0
  63. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/dev_crn/viz.py +0 -0
  64. {synkit-1.1.0 → synkit-1.1.1}/synkit/CRN/viz/crn_vis.py +0 -0
  65. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Cluster/__init__.py +0 -0
  66. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Cluster/butina.py +0 -0
  67. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Fingerprint/__init__.py +0 -0
  68. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Fingerprint/fp_calculator.py +0 -0
  69. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Fingerprint/smiles_featurizer.py +0 -0
  70. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Fingerprint/transformation_fp.py +0 -0
  71. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Molecule/__init__.py +0 -0
  72. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Molecule/atom_features.py +0 -0
  73. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Molecule/descriptors.py +0 -0
  74. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Molecule/formula.py +0 -0
  75. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Molecule/graph_annotator.py +0 -0
  76. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Molecule/standardize.py +0 -0
  77. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Molecule/valence.py +0 -0
  78. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Reaction/Mapper/__init__.py +0 -0
  79. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Reaction/Mapper/wl_mapper.py +0 -0
  80. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Reaction/__init__.py +0 -0
  81. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Reaction/aam_validator.py +0 -0
  82. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Reaction/balance_check.py +0 -0
  83. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Reaction/canon_rsmi.py +0 -0
  84. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Reaction/cleaning.py +0 -0
  85. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Reaction/deionize.py +0 -0
  86. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Reaction/fix_aam.py +0 -0
  87. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Reaction/neutralize.py +0 -0
  88. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Reaction/radical_wildcard.py +0 -0
  89. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Reaction/standardize.py +0 -0
  90. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/Reaction/tautomerize.py +0 -0
  91. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/__init__.py +0 -0
  92. {synkit-1.1.0 → synkit-1.1.1}/synkit/Chem/utils.py +0 -0
  93. {synkit-1.1.0 → synkit-1.1.1}/synkit/Data/__init__.py +0 -0
  94. {synkit-1.1.0 → synkit-1.1.1}/synkit/Data/gen_partial_aam.py +0 -0
  95. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Canon/__init__.py +0 -0
  96. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Canon/canon_algs.py +0 -0
  97. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Canon/canon_graph.py +0 -0
  98. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Canon/nauty.py +0 -0
  99. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Context/__init__.py +0 -0
  100. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Context/hier_context.py +0 -0
  101. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Context/radius_expand.py +0 -0
  102. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Feature/Descriptors/topology.py +0 -0
  103. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Feature/Fingerprint/__init__.py +0 -0
  104. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Feature/Fingerprint/wl_rxn_fps.py +0 -0
  105. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Feature/__init__.py +0 -0
  106. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Feature/graph_descriptors.py +0 -0
  107. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Feature/graph_fps.py +0 -0
  108. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Feature/graph_signature.py +0 -0
  109. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Feature/hash_fps.py +0 -0
  110. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Feature/morgan_fps.py +0 -0
  111. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Feature/path_fps.py +0 -0
  112. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Feature/wl_hash.py +0 -0
  113. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Hyrogen/__init__.py +0 -0
  114. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Hyrogen/_misc.py +0 -0
  115. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Hyrogen/hcomplete.py +0 -0
  116. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Hyrogen/hextend.py +0 -0
  117. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/ITS/__init__.py +0 -0
  118. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/ITS/its_builder.py +0 -0
  119. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/ITS/its_construction.py +0 -0
  120. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/ITS/its_decompose.py +0 -0
  121. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/ITS/its_destruction.py +0 -0
  122. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/ITS/its_expand.py +0 -0
  123. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/ITS/its_relabel.py +0 -0
  124. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/ITS/normalize_aam.py +0 -0
  125. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/ITS/partial_its.py +0 -0
  126. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/MTG/__init__.py +0 -0
  127. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/MTG/group_comp.py +0 -0
  128. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/MTG/groupoid.py +0 -0
  129. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/MTG/mcs_matcher.py +0 -0
  130. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/MTG/mtg.py +0 -0
  131. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/MTG/mtg_explore.py +0 -0
  132. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/MTG/utils.py +0 -0
  133. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Matcher/__init__.py +0 -0
  134. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Matcher/approx_mcs.py +0 -0
  135. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Matcher/batch_cluster.py +0 -0
  136. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Matcher/graph_cluster.py +0 -0
  137. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Matcher/graph_matcher.py +0 -0
  138. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Matcher/graph_morphism.py +0 -0
  139. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Matcher/mcs_matcher.py +0 -0
  140. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Matcher/multi_turbo_iso.py +0 -0
  141. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Matcher/orbit.py +0 -0
  142. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Matcher/sing.py +0 -0
  143. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Matcher/subgraph_matcher.py +0 -0
  144. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Matcher/turbo_iso.py +0 -0
  145. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Matcher/wl_sel.py +0 -0
  146. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Wildcard/__init__.py +0 -0
  147. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Wildcard/fuse_graph.py +0 -0
  148. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Wildcard/graph_wc.py +0 -0
  149. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Wildcard/its_merge.py +0 -0
  150. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Wildcard/radwc.py +0 -0
  151. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Wildcard/wc_matcher.py +0 -0
  152. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/Wildcard/wildcard.py +0 -0
  153. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/__init__.py +0 -0
  154. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/canon_graph.py +0 -0
  155. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/syn_graph.py +0 -0
  156. {synkit-1.1.0 → synkit-1.1.1}/synkit/Graph/utils.py +0 -0
  157. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/__init__.py +0 -0
  158. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/chem_converter.py +0 -0
  159. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/combinatorial/__init__.py +0 -0
  160. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/combinatorial/gml_to_graph.py +0 -0
  161. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/combinatorial/graph_to_gml.py +0 -0
  162. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/combinatorial/graph_to_smarts.py +0 -0
  163. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/combinatorial/smarts_expander.py +0 -0
  164. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/combinatorial/smarts_generalizer.py +0 -0
  165. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/combinatorial/smarts_to_graph.py +0 -0
  166. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/data_io.py +0 -0
  167. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/data_process.py +0 -0
  168. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/debug.py +0 -0
  169. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/dg_to_gml.py +0 -0
  170. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/gml_to_nx.py +0 -0
  171. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/graph_to_mol.py +0 -0
  172. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/mol_to_graph.py +0 -0
  173. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/nx_to_gml.py +0 -0
  174. {synkit-1.1.0 → synkit-1.1.1}/synkit/IO/smiles_to_id.py +0 -0
  175. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Apply/__init__.py +0 -0
  176. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Apply/reactor_rule.py +0 -0
  177. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Apply/retro_reactor.py +0 -0
  178. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Apply/rule_matcher.py +0 -0
  179. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Apply/rule_rbl.py +0 -0
  180. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Compose/__init__.py +0 -0
  181. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Compose/compose_rule.py +0 -0
  182. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Compose/rule_compose.py +0 -0
  183. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Compose/rule_mapping.py +0 -0
  184. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Compose/seq_comp.py +0 -0
  185. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Compose/valence_constrain.py +0 -0
  186. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Modify/__init__.py +0 -0
  187. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Modify/implict_rule.py +0 -0
  188. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Modify/longest_path.py +0 -0
  189. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Modify/molecule_rule.py +0 -0
  190. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Modify/prune_templates.py +0 -0
  191. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Modify/rule_utils.py +0 -0
  192. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/Modify/strip_rule.py +0 -0
  193. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/__init__.py +0 -0
  194. {synkit-1.1.0 → synkit-1.1.1}/synkit/Rule/syn_rule.py +0 -0
  195. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/MSR/__init__.py +0 -0
  196. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/MSR/multi_steps.py +0 -0
  197. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/MSR/path_finder.py +0 -0
  198. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Metrics/__init__.py +0 -0
  199. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Metrics/_base.py +0 -0
  200. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Metrics/_plot.py +0 -0
  201. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Metrics/_ranking.py +0 -0
  202. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Reactor/__init__.py +0 -0
  203. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Reactor/batch_reactor.py +0 -0
  204. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Reactor/benchmark.py +0 -0
  205. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Reactor/imba_engine.py +0 -0
  206. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Reactor/mod_aam.py +0 -0
  207. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Reactor/mod_reactor.py +0 -0
  208. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Reactor/partial_engine.py +0 -0
  209. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Reactor/post_syn.py +0 -0
  210. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Reactor/rbl_engine.py +0 -0
  211. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Reactor/rule_filter.py +0 -0
  212. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Reactor/single_predictor.py +0 -0
  213. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/Reactor/strategy.py +0 -0
  214. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/__init__.py +0 -0
  215. {synkit-1.1.0 → synkit-1.1.1}/synkit/Synthesis/reactor_utils.py +0 -0
  216. {synkit-1.1.0 → synkit-1.1.1}/synkit/Utils/__init__.py +0 -0
  217. {synkit-1.1.0 → synkit-1.1.1}/synkit/Utils/utils.py +0 -0
  218. {synkit-1.1.0 → synkit-1.1.1}/synkit/Vis/__init__.py +0 -0
  219. {synkit-1.1.0 → synkit-1.1.1}/synkit/Vis/chemical_space.py +0 -0
  220. {synkit-1.1.0 → synkit-1.1.1}/synkit/Vis/crn_vis.py +0 -0
  221. {synkit-1.1.0 → synkit-1.1.1}/synkit/Vis/embedding.py +0 -0
  222. {synkit-1.1.0 → synkit-1.1.1}/synkit/Vis/graph_visualizer.py +0 -0
  223. {synkit-1.1.0 → synkit-1.1.1}/synkit/Vis/pdf_writer.py +0 -0
  224. {synkit-1.1.0 → synkit-1.1.1}/synkit/Vis/rule_vis.py +0 -0
  225. {synkit-1.1.0 → synkit-1.1.1}/synkit/Vis/rxn_vis.py +0 -0
  226. {synkit-1.1.0 → synkit-1.1.1}/synkit/__init__.py +0 -0
  227. {synkit-1.1.0 → synkit-1.1.1}/synkit/examples.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: synkit
3
- Version: 1.1.0
3
+ Version: 1.1.1
4
4
  Summary: Utility for reaction modeling using graph grammar
5
5
  Project-URL: homepage, https://github.com/TieuLongPhan/SynKit
6
6
  Project-URL: source, https://github.com/TieuLongPhan/SynKit
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "synkit"
7
- version = "1.1.0"
7
+ version = "1.1.1"
8
8
  description = "Utility for reaction modeling using graph grammar"
9
9
  readme = "README.md"
10
10
  long-description = { file = "CHANGELOG.md" }
@@ -10,19 +10,20 @@ from ..Hypergraph.backend import _CRNGraphBackend
10
10
 
11
11
 
12
12
  # -------------------------------------------------------------------------
13
- # Canon: Nauty-style canonicalization
13
+ # Canon: Exact Nauty-style individualization + refinement (no heuristic pruning)
14
14
  # -------------------------------------------------------------------------
15
15
 
16
16
 
17
17
  class CRNCanonicalizer(_CRNGraphBackend):
18
18
  """
19
- Nauty-style canonicalization and automorphism enumeration for a CRN.
20
-
21
- The underlying :class:`CRNHyperGraph` is first converted to either a
22
- bipartite species→reaction→species DiGraph (include_rule=True) or a
23
- collapsed species→species DiGraph (include_rule=False). A
24
- partition-refinement search then computes a canonical labeling and
25
- associated automorphisms.
19
+ Exact canonicalization and automorphism enumeration for a CRN via
20
+ individualization-refinement (IR) search.
21
+
22
+ This implementation is **exact**:
23
+ - No branch-shape skipping
24
+ - No prefix/label pruning that could drop valid automorphisms
25
+ - Enumerates all permutations achieving the minimal canonical label
26
+ (these correspond to automorphisms w.r.t. the labeling function)
26
27
  """
27
28
 
28
29
  def __init__(
@@ -35,24 +36,6 @@ class CRNCanonicalizer(_CRNGraphBackend):
35
36
  integer_ids: bool = False,
36
37
  include_stoich: bool = True,
37
38
  ) -> None:
38
- """
39
- Initialize a canonicalizer for a CRN.
40
-
41
- :param hg: Hypergraph to canonicalize.
42
- :type hg: CRNHyperGraph
43
- :param include_rule: If True, work on bipartite species→reaction→species
44
- graph; if False, use collapsed species graph.
45
- :type include_rule: bool
46
- :param node_attr_keys: Node attribute keys used in partition refinement
47
- and canonical label construction.
48
- :type node_attr_keys: Iterable[str]
49
- :param edge_attr_keys: Edge attribute keys included in canonical labels.
50
- :type edge_attr_keys: Iterable[str]
51
- :param integer_ids: If True, use integer node ids in the bipartite view.
52
- :type integer_ids: bool
53
- :param include_stoich: If True, include stoichiometry on bipartite edges.
54
- :type include_stoich: bool
55
- """
56
39
  super().__init__(
57
40
  hg,
58
41
  include_rule=include_rule,
@@ -63,10 +46,6 @@ class CRNCanonicalizer(_CRNGraphBackend):
63
46
  self.edge_attr_keys: Tuple[str, ...] = tuple(edge_attr_keys)
64
47
 
65
48
  def __repr__(self) -> str:
66
- """
67
- :returns: String representation of the canonicalizer.
68
- :rtype: str
69
- """
70
49
  return (
71
50
  f"CRNCanonicalizer(include_rule={self.include_rule}, "
72
51
  f"node_attr_keys={self.node_attr_keys}, "
@@ -78,37 +57,19 @@ class CRNCanonicalizer(_CRNGraphBackend):
78
57
 
79
58
  @staticmethod
80
59
  def _freeze(x: Any) -> Any:
81
- """
82
- Convert nested containers into hashable equivalents.
83
-
84
- Lists become tuples; dicts become frozensets of sorted (key, value)
85
- pairs; other types are returned unchanged.
86
-
87
- :param x: Object to convert.
88
- :type x: Any
89
- :returns: Hashable representation of x.
90
- :rtype: Any
91
- """
60
+ """Convert nested containers into hashable equivalents."""
92
61
  if isinstance(x, list):
93
62
  return tuple(CRNCanonicalizer._freeze(v) for v in x)
94
63
  if isinstance(x, dict):
95
64
  return frozenset(
96
65
  (k, CRNCanonicalizer._freeze(v)) for k, v in sorted(x.items())
97
66
  )
67
+ if isinstance(x, set):
68
+ return tuple(sorted(CRNCanonicalizer._freeze(v) for v in x))
98
69
  return x
99
70
 
100
71
  def _init_part(self, G: nx.Graph) -> List[List[Any]]:
101
- """
102
- Build the initial node partition for refinement.
103
-
104
- Nodes are grouped by tuples of node_attr_keys. If no node_attr_keys
105
- are provided, all nodes start in a single cell.
106
-
107
- :param G: Graph whose nodes are to be partitioned.
108
- :type G: nx.Graph
109
- :returns: List of partition cells, each a list of nodes.
110
- :rtype: List[List[Any]]
111
- """
72
+ """Initial partition by node attributes."""
112
73
  if not self.node_attr_keys:
113
74
  return [sorted(G.nodes())]
114
75
  buckets: Dict[Tuple[Any, ...], List[Any]] = {}
@@ -128,19 +89,13 @@ class CRNCanonicalizer(_CRNGraphBackend):
128
89
  part: List[List[Any]],
129
90
  ) -> Tuple[Any, ...]:
130
91
  """
131
- Compute the refinement signature for a single node.
132
-
133
- The signature combines node attributes, degree information, neighbor
134
- counts per partition cell, and a multiset of selected edge attributes.
135
-
136
- :param G: Graph on which refinement is performed.
137
- :type G: nx.DiGraph
138
- :param v: Node whose signature is computed.
139
- :type v: Any
140
- :param part: Current node partition.
141
- :type part: List[List[Any]]
142
- :returns: Signature tuple used to split cells.
143
- :rtype: Tuple[Any, ...]
92
+ Refinement signature for node v under current partition.
93
+
94
+ Uses:
95
+ - node attributes
96
+ - (in_degree, out_degree)
97
+ - neighbor counts per cell (undirected union for directed graphs)
98
+ - multiset of outgoing edge attributes
144
99
  """
145
100
  node_attrs = tuple(
146
101
  self._freeze(G.nodes[v].get(a, None)) for a in self.node_attr_keys
@@ -156,7 +111,8 @@ class CRNCanonicalizer(_CRNGraphBackend):
156
111
 
157
112
  counts: List[int] = []
158
113
  for cell in part:
159
- counts.append(sum(1 for n in nbrs if n in cell))
114
+ s = set(cell)
115
+ counts.append(sum(1 for n in nbrs if n in s))
160
116
  counts_t = tuple(counts)
161
117
 
162
118
  edge_mult: List[Tuple[Any, ...]] = []
@@ -174,56 +130,40 @@ class CRNCanonicalizer(_CRNGraphBackend):
174
130
  return (node_attrs, degree, counts_t, edge_mult_t)
175
131
 
176
132
  def _refine(self, G: nx.DiGraph, part: List[List[Any]]) -> List[List[Any]]:
177
- """
178
- Refine a partition until no further splits occur.
179
-
180
- Each non-singleton cell is split by grouping nodes with identical
181
- signatures from :meth:`_sig`. Refinement continues until stable.
182
-
183
- :param G: Graph to refine.
184
- :type G: nx.DiGraph
185
- :param part: Current node partition.
186
- :type part: List[List[Any]]
187
- :returns: Refined partition.
188
- :rtype: List[List[Any]]
189
- """
133
+ """Refine partition until stable (exact, deterministic)."""
190
134
  changed = True
191
- cache: Dict[Any, Tuple[Any, ...]] = {}
135
+ cache: Dict[Tuple[Any, int], Tuple[Any, ...]] = {}
192
136
  while changed:
193
137
  changed = False
194
138
  new_part: List[List[Any]] = []
139
+ # note: cache depends on part, but we keep it simple & exact:
140
+ # cache key includes an epoch id via id(part) to avoid reusing across parts.
141
+ epoch = id(tuple(tuple(c) for c in part))
195
142
  for cell in part:
196
143
  if len(cell) <= 1:
197
144
  new_part.append(cell)
198
145
  continue
199
146
  sigs: Dict[Tuple[Any, ...], List[Any]] = {}
200
147
  for v in cell:
201
- if v not in cache:
202
- cache[v] = self._sig(G, v, part)
203
- s = cache[v]
148
+ ck = (v, epoch)
149
+ if ck not in cache:
150
+ cache[ck] = self._sig(G, v, part)
151
+ s = cache[ck]
204
152
  sigs.setdefault(s, []).append(v)
153
+
205
154
  if len(sigs) > 1:
206
155
  changed = True
207
156
  for s in sorted(sigs.keys()):
208
157
  new_part.append(sorted(sigs[s]))
209
158
  else:
210
- new_part.append(cell)
159
+ new_part.append(sorted(cell))
211
160
  part = new_part
212
161
  return part
213
162
 
214
163
  def _label(self, G: nx.DiGraph, perm: List[Any]) -> str:
215
164
  """
216
- Build a canonical label string for a full node permutation.
217
-
218
- The label encodes node attributes in order, plus the full adjacency
219
- pattern and selected edge attributes for all ordered node pairs.
220
-
221
- :param G: Graph to label.
222
- :type G: nx.DiGraph
223
- :param perm: Full node permutation (ordering).
224
- :type perm: List[Any]
225
- :returns: Canonical label string for this permutation.
226
- :rtype: str
165
+ Canonical label string for a full node permutation.
166
+ Deterministic and exact (no approximations).
227
167
  """
228
168
  node_seg = "|".join(
229
169
  ":".join(
@@ -250,29 +190,6 @@ class CRNCanonicalizer(_CRNGraphBackend):
250
190
  edge_seg = "|".join(edge_bits)
251
191
  return node_seg + "||" + edge_seg
252
192
 
253
- def _partial_label(self, G: nx.DiGraph, prefix: List[Any]) -> str:
254
- """
255
- Build a partial label for a permutation prefix.
256
-
257
- A long sequence of ``'{'`` characters is appended so that partial
258
- labels compare lexicographically larger than any full label with
259
- the same prefix, enabling safe pruning.
260
-
261
- :param G: Graph to label.
262
- :type G: nx.DiGraph
263
- :param prefix: Partial node permutation.
264
- :type prefix: List[Any]
265
- :returns: Partial label string.
266
- :rtype: str
267
- """
268
- node_seg = "|".join(
269
- ":".join(
270
- str(self._freeze(G.nodes[v].get(a, ""))) for a in self.node_attr_keys
271
- )
272
- for v in prefix
273
- )
274
- return node_seg + "{" * 1000
275
-
276
193
  def _search(
277
194
  self,
278
195
  G: nx.DiGraph,
@@ -287,29 +204,9 @@ class CRNCanonicalizer(_CRNGraphBackend):
287
204
  timeout_sec: Optional[float],
288
205
  ) -> bool:
289
206
  """
290
- Recursive backtracking search for minimal canonical labels.
291
-
292
- :param G: Graph to canonicalize.
293
- :type G: nx.DiGraph
294
- :param part: Current node partition.
295
- :type part: List[List[Any]]
296
- :param prefix: Current permutation prefix.
297
- :type prefix: List[Any]
298
- :param best: Dict with keys ``"label"`` and ``"perm"`` for the best
299
- full label and permutation seen so far.
300
- :type best: Dict[str, Optional[str]]
301
- :param perms: List to collect permutations that achieve the best label.
302
- :type perms: List[List[Any]]
303
- :param depth: Current recursion depth.
304
- :type depth: int
305
- :param max_depth: Optional maximum recursion depth; None for unlimited.
306
- :type max_depth: Optional[int]
307
- :param start: Start time (:func:`time.time`) for timeout accounting.
308
- :type start: float
309
- :param timeout_sec: Optional wall-clock timeout in seconds.
310
- :type timeout_sec: Optional[float]
311
- :returns: True if the search stopped early due to timeout/depth.
312
- :rtype: bool
207
+ Exact recursive IR search for minimal canonical label.
208
+
209
+ Returns True only if stopped early due to max_depth/timeout.
313
210
  """
314
211
  if timeout_sec is not None and (time.time() - start) > timeout_sec:
315
212
  return True
@@ -318,32 +215,29 @@ class CRNCanonicalizer(_CRNGraphBackend):
318
215
 
319
216
  part = self._refine(G, part)
320
217
 
321
- # Fully discrete partition: construct final permutation.
218
+ # Fully discrete partition: finalize permutation and score it.
322
219
  if all(len(c) == 1 for c in part):
323
220
  perm = prefix + [v for c in part for v in c]
324
221
  lab = self._label(G, perm)
325
222
  if best["label"] is None or lab < best["label"]:
326
- best["label"], best["perm"] = lab, perm
223
+ best["label"], best["perm"] = lab, perm # type: ignore[assignment]
327
224
  perms.clear()
328
225
  perms.append(perm)
329
226
  elif lab == best["label"]:
330
227
  perms.append(perm)
331
228
  return False
332
229
 
333
- # Choose first non-singleton cell for branching.
230
+ # Choose a non-singleton cell (deterministic choice keeps exactness).
334
231
  idx = next(i for i, c in enumerate(part) if len(c) > 1)
335
- cell = part[idx]
336
- cell_sorted = sorted(cell)
232
+ cell = sorted(part[idx])
337
233
 
338
- for v in cell_sorted:
234
+ for v in cell:
339
235
  rest = [w for w in cell if w != v]
340
236
  new_part = (
341
237
  part[:idx] + [[v]] + ([sorted(rest)] if rest else []) + part[idx + 1 :]
342
238
  )
343
239
  pref = prefix + [v]
344
- p_lab = self._partial_label(G, pref)
345
- if best["label"] is not None and p_lab > best["label"]:
346
- continue
240
+
347
241
  if self._search(
348
242
  G,
349
243
  new_part,
@@ -360,14 +254,7 @@ class CRNCanonicalizer(_CRNGraphBackend):
360
254
 
361
255
  @staticmethod
362
256
  def _orbits_from_perms(perms: List[List[Any]]) -> List[Set[Any]]:
363
- """
364
- Derive node orbits from a list of automorphism permutations.
365
-
366
- :param perms: List of permutations (each a list of nodes).
367
- :type perms: List[List[Any]]
368
- :returns: List of disjoint sets of nodes, one per orbit.
369
- :rtype: List[Set[Any]]
370
- """
257
+ """Derive node orbits from a list of automorphism permutations."""
371
258
  if not perms:
372
259
  return []
373
260
  orbit_map: Dict[Any, int] = {}
@@ -401,23 +288,13 @@ class CRNCanonicalizer(_CRNGraphBackend):
401
288
  def _maps_from_perms(
402
289
  ref: List[Any], perms: List[List[Any]]
403
290
  ) -> List[Dict[Any, Any]]:
404
- """
405
- Convert permutations into mapping dicts relative to a reference order.
406
-
407
- :param ref: Reference permutation (canonical ordering of nodes).
408
- :type ref: List[Any]
409
- :param perms: List of permutations to convert.
410
- :type perms: List[List[Any]]
411
- :returns: List of mappings {ref_node -> perm_node}.
412
- :rtype: List[Dict[Any, Any]]
413
- """
291
+ """Convert permutations into mapping dicts relative to a reference order."""
414
292
  maps: List[Dict[Any, Any]] = []
415
293
  n = len(ref)
416
294
  for p in perms:
417
295
  if len(p) != n:
418
296
  continue
419
- m = {ref[i]: p[i] for i in range(n)}
420
- maps.append(m)
297
+ maps.append({ref[i]: p[i] for i in range(n)})
421
298
  return maps
422
299
 
423
300
  def _canon(
@@ -433,21 +310,7 @@ class CRNCanonicalizer(_CRNGraphBackend):
433
310
  List[Dict[Any, Any]],
434
311
  bool,
435
312
  ]:
436
- """
437
- Compute canonical graph, minimal permutations, orbits and mappings.
438
-
439
- :param max_depth: Optional maximum recursion depth; None for unlimited.
440
- :type max_depth: Optional[int]
441
- :param timeout_sec: Optional wall-clock timeout in seconds.
442
- :type timeout_sec: Optional[float]
443
- :returns: Tuple (G_can, perm, perms, orbits, maps, early_stop) where
444
- G_can is the canonical graph, perm is a representative
445
- minimal permutation, perms is the list of all minimal
446
- permutations, orbits are node orbits, maps are mapping
447
- dicts, and early_stop indicates early termination.
448
- :rtype: Tuple[nx.DiGraph, List[Any], List[List[Any]], List[Set[Any]], List[Dict[Any, Any]], bool]
449
- :raises RuntimeError: If no canonical form is found (e.g. due to early stop).
450
- """
313
+ """Compute canonical graph, minimal permutations, orbits and mappings (exact)."""
451
314
  G = self.G
452
315
  best: Dict[str, Optional[str]] = {"label": None, "perm": None}
453
316
  perms: List[List[Any]] = []
@@ -466,7 +329,7 @@ class CRNCanonicalizer(_CRNGraphBackend):
466
329
  timeout_sec=timeout_sec,
467
330
  )
468
331
 
469
- perm = best["perm"]
332
+ perm = best.get("perm") # type: ignore[assignment]
470
333
  if perm is None:
471
334
  raise RuntimeError(
472
335
  f"Canonical form not found; early stop (max_depth={max_depth}, timeout_sec={timeout_sec})"
@@ -487,16 +350,7 @@ class CRNCanonicalizer(_CRNGraphBackend):
487
350
  max_depth: Optional[int] = None,
488
351
  timeout_sec: Optional[float] = None,
489
352
  ) -> nx.DiGraph:
490
- """
491
- Return the canonical relabeled graph.
492
-
493
- :param max_depth: Optional maximum recursion depth; None for unlimited.
494
- :type max_depth: Optional[int]
495
- :param timeout_sec: Optional wall-clock timeout in seconds.
496
- :type timeout_sec: Optional[float]
497
- :returns: Canonically relabeled DiGraph with nodes 1..N.
498
- :rtype: nx.DiGraph
499
- """
353
+ """Return the canonical relabeled graph."""
500
354
  G_can, _, _, _, _, _ = self._canon(max_depth=max_depth, timeout_sec=timeout_sec)
501
355
  return G_can
502
356
 
@@ -506,16 +360,7 @@ class CRNCanonicalizer(_CRNGraphBackend):
506
360
  max_depth: Optional[int] = None,
507
361
  timeout_sec: Optional[float] = None,
508
362
  ) -> bool:
509
- """
510
- Test whether the canonical graph has nontrivial automorphisms.
511
-
512
- :param max_depth: Optional maximum recursion depth; None for unlimited.
513
- :type max_depth: Optional[int]
514
- :param timeout_sec: Optional wall-clock timeout in seconds.
515
- :type timeout_sec: Optional[float]
516
- :returns: True if more than one minimal-label permutation exists.
517
- :rtype: bool
518
- """
363
+ """True iff >1 minimal-label permutation exists."""
519
364
  _, _, perms, _, _, _ = self._canon(max_depth=max_depth, timeout_sec=timeout_sec)
520
365
  return len(perms) > 1
521
366
 
@@ -525,21 +370,11 @@ class CRNCanonicalizer(_CRNGraphBackend):
525
370
  max_depth: Optional[int] = None,
526
371
  timeout_sec: Optional[float] = None,
527
372
  ) -> Dict[str, Any]:
528
- """
529
- Run canonicalization and return a summary dictionary.
530
-
531
- :param max_depth: Optional maximum recursion depth; None for unlimited.
532
- :type max_depth: Optional[int]
533
- :param timeout_sec: Optional wall-clock timeout in seconds.
534
- :type timeout_sec: Optional[float]
535
- :returns: Summary with permutations, mappings, orbits and diagnostics.
536
- :rtype: Dict[str, Any]
537
- """
373
+ """Run canonicalization and return a summary dictionary."""
538
374
  G_can, perm, perms, orbits, maps, early = self._canon(
539
375
  max_depth=max_depth,
540
376
  timeout_sec=timeout_sec,
541
377
  )
542
-
543
378
  return {
544
379
  "canon_graph": G_can,
545
380
  "graph_type": self.graph_type,
@@ -559,16 +394,7 @@ class CRNCanonicalizer(_CRNGraphBackend):
559
394
  max_depth: Optional[int] = None,
560
395
  timeout_sec: Optional[float] = None,
561
396
  ) -> List[Set[Any]]:
562
- """
563
- Compute node orbits for the canonical form.
564
-
565
- :param max_depth: Optional maximum recursion depth; None for unlimited.
566
- :type max_depth: Optional[int]
567
- :param timeout_sec: Optional wall-clock timeout in seconds.
568
- :type timeout_sec: Optional[float]
569
- :returns: List of disjoint node sets representing orbits.
570
- :rtype: List[Set[Any]]
571
- """
397
+ """Compute node orbits for the canonical form."""
572
398
  _, _, _, orbits, _, _ = self._canon(
573
399
  max_depth=max_depth,
574
400
  timeout_sec=timeout_sec,
@@ -593,31 +419,9 @@ def canonical(
593
419
  timeout_sec: Optional[float] = None,
594
420
  ) -> CRNCanonicalizer:
595
421
  """
596
- Run canonicalization and return a CRNCanonicalizer instance.
597
-
598
- The canonicalization is performed once (via :meth:`summary`) to
599
- populate internal state; the returned object can then be queried.
600
-
601
- :param hg: Hypergraph to canonicalize.
602
- :type hg: CRNHyperGraph
603
- :param include_rule: If True, use bipartite species→reaction→species view;
604
- if False, use collapsed species graph.
605
- :type include_rule: bool
606
- :param node_attr_keys: Node attributes used in partition refinement and
607
- canonical labels.
608
- :type node_attr_keys: Iterable[str]
609
- :param edge_attr_keys: Edge attributes included in canonical labels.
610
- :type edge_attr_keys: Iterable[str]
611
- :param integer_ids: If True, use integer node ids in bipartite view.
612
- :type integer_ids: bool
613
- :param include_stoich: If True, include stoichiometry on bipartite edges.
614
- :type include_stoich: bool
615
- :param max_depth: Optional maximum recursion depth; None for unlimited.
616
- :type max_depth: Optional[int]
617
- :param timeout_sec: Optional wall-clock timeout in seconds.
618
- :type timeout_sec: Optional[float]
619
- :returns: Canonicalizer instance with populated internal state.
620
- :rtype: CRNCanonicalizer
422
+ Run canonicalization and return a CRNCanonicalizer instance (exact).
423
+
424
+ NOTE: returns the canonicalizer object (not the summary dict).
621
425
  """
622
426
  canon = CRNCanonicalizer(
623
427
  hg,
@@ -627,5 +431,6 @@ def canonical(
627
431
  integer_ids=integer_ids,
628
432
  include_stoich=include_stoich,
629
433
  )
630
- summary = canon.summary(max_depth=max_depth, timeout_sec=timeout_sec)
631
- return summary
434
+ # compute once to validate / warm results (optional)
435
+ canon.summary(max_depth=max_depth, timeout_sec=timeout_sec)
436
+ return canon