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.
- synkit/CRN/Benchmark/__init__.py +53 -0
- synkit/CRN/Benchmark/crosschecks.py +13 -0
- synkit/CRN/Benchmark/kegg.py +12 -0
- synkit/CRN/Benchmark/networks.py +13 -0
- synkit/CRN/Benchmark/scaling.py +13 -0
- synkit/CRN/Benchmark/validate.py +13 -0
- synkit/CRN/Construct/__init__.py +16 -0
- synkit/CRN/Construct/abstract.py +668 -0
- synkit/CRN/Construct/arity.py +36 -0
- synkit/CRN/Construct/builder.py +619 -0
- synkit/CRN/Construct/derivation.py +63 -0
- synkit/CRN/Construct/flattener.py +100 -0
- synkit/CRN/Construct/keys.py +14 -0
- synkit/CRN/Construct/mixtures.py +117 -0
- synkit/CRN/Construct/rdkit_worker.py +69 -0
- synkit/CRN/Construct/smiles.py +99 -0
- synkit/CRN/Construct/state.py +31 -0
- synkit/CRN/Construct/strategy.py +75 -0
- synkit/CRN/Construct/worker.py +42 -0
- synkit/CRN/IO/__init__.py +36 -0
- synkit/CRN/IO/sbml.py +925 -0
- synkit/CRN/Pathway/__init__.py +72 -0
- synkit/CRN/Pathway/_adapter.py +333 -0
- synkit/CRN/Pathway/pathfinder.py +500 -0
- synkit/CRN/Pathway/reachability.py +796 -0
- synkit/CRN/Pathway/realizability.py +1322 -0
- synkit/CRN/Petrinet/__init__.py +93 -0
- synkit/CRN/Petrinet/analyzer.py +486 -0
- synkit/CRN/Petrinet/minimal_semiflows.py +436 -0
- synkit/CRN/Petrinet/net.py +1041 -0
- synkit/CRN/Petrinet/persistence.py +97 -0
- synkit/CRN/Petrinet/semiflows.py +483 -0
- synkit/CRN/Petrinet/siphon_search.py +402 -0
- synkit/CRN/Petrinet/structure.py +286 -0
- synkit/CRN/Props/__init__.py +130 -0
- synkit/CRN/Props/_rank.py +29 -0
- synkit/CRN/Props/deficiency.py +953 -0
- synkit/CRN/Props/dynamics.py +832 -0
- synkit/CRN/Props/helper.py +151 -0
- synkit/CRN/Props/stoich.py +751 -0
- synkit/CRN/Props/thermo.py +584 -0
- synkit/CRN/Query/__init__.py +66 -0
- synkit/CRN/Query/cache.py +41 -0
- synkit/CRN/Query/kegg_api.py +99 -0
- synkit/CRN/Query/kegg_extract.py +714 -0
- synkit/CRN/Query/kegg_impute.py +707 -0
- synkit/CRN/Query/kegg_parse.py +480 -0
- synkit/CRN/Query/to_syncrn.py +290 -0
- synkit/CRN/README.md +234 -0
- synkit/CRN/Structure/__init__.py +12 -0
- synkit/CRN/Structure/_graph_io.py +713 -0
- synkit/CRN/Structure/_matrices.py +88 -0
- synkit/CRN/Structure/_parse.py +544 -0
- synkit/CRN/Structure/reaction.py +237 -0
- synkit/CRN/Structure/rule.py +55 -0
- synkit/CRN/Structure/species.py +46 -0
- synkit/CRN/Structure/syncrn.py +929 -0
- synkit/CRN/Symmetry/__init__.py +20 -0
- synkit/CRN/Symmetry/_common.py +1059 -0
- synkit/CRN/Symmetry/_ir.py +940 -0
- synkit/CRN/Symmetry/automorphism.py +472 -0
- synkit/CRN/Symmetry/canon.py +441 -0
- synkit/CRN/Symmetry/isomorphism.py +412 -0
- synkit/CRN/Symmetry/symmetry.py +61 -0
- synkit/CRN/Symmetry/wl_canon.py +967 -0
- synkit/CRN/Visualize/__init__.py +11 -0
- synkit/CRN/Visualize/labels.py +113 -0
- synkit/CRN/Visualize/layout.py +708 -0
- synkit/CRN/Visualize/palette.py +292 -0
- synkit/CRN/Visualize/validation.py +122 -0
- synkit/CRN/Visualize/vis.py +1152 -0
- synkit/CRN/__init__.py +233 -0
- synkit/CRN/_build.py +50 -0
- synkit/CRN/_native_build.py +175 -0
- synkit/CRN/analysis.py +629 -0
- synkit/CRN/backend.py +74 -0
- synkit/CRN/cpp/CMakeLists.txt +58 -0
- synkit/CRN/cpp/algebra.cpp +46 -0
- synkit/CRN/cpp/closure.cpp +29 -0
- synkit/CRN/cpp/exact.h +55 -0
- synkit/CRN/cpp/pathway.cpp +46 -0
- synkit/CRN/cpp/semiflows.cpp +209 -0
- synkit/CRN/cpp/structural.cpp +240 -0
- synkit/CRN/cpp/symmetry.cpp +45 -0
- synkit/CRN/cpp/write_manifest.cmake +28 -0
- synkit/CRN/kinds.py +137 -0
- synkit/CRN/lib/synkit_crn.dll +0 -0
- synkit/CRN/lib/synkit_crn.json +33 -0
- synkit/CRN/native.py +388 -0
- synkit/CRN/native_analysis.py +459 -0
- synkit/Chem/Cluster/__init__.py +0 -0
- synkit/Chem/Cluster/butina.py +140 -0
- synkit/Chem/Fingerprint/__init__.py +0 -0
- synkit/Chem/Fingerprint/fp_calculator.py +155 -0
- synkit/Chem/Fingerprint/smiles_featurizer.py +258 -0
- synkit/Chem/Fingerprint/transformation_fp.py +139 -0
- synkit/Chem/Mapper/README.rst +43 -0
- synkit/Chem/Mapper/__init__.py +255 -0
- synkit/Chem/Mapper/_compat.py +130 -0
- synkit/Chem/Mapper/adapters/__init__.py +1 -0
- synkit/Chem/Mapper/adapters/prediction.py +126 -0
- synkit/Chem/Mapper/adapters/template.py +412 -0
- synkit/Chem/Mapper/chem/__init__.py +52 -0
- synkit/Chem/Mapper/chem/aam.py +673 -0
- synkit/Chem/Mapper/chem/blind.py +160 -0
- synkit/Chem/Mapper/chem/its.py +309 -0
- synkit/Chem/Mapper/chem/smiles.py +564 -0
- synkit/Chem/Mapper/graph/__init__.py +66 -0
- synkit/Chem/Mapper/graph/automorphism.py +395 -0
- synkit/Chem/Mapper/graph/blockcut.py +98 -0
- synkit/Chem/Mapper/graph/labeled_graph.py +104 -0
- synkit/Chem/Mapper/graph/refine.py +176 -0
- synkit/Chem/Mapper/graph/synkit_adapter.py +110 -0
- synkit/Chem/Mapper/io/__init__.py +13 -0
- synkit/Chem/Mapper/io/idxmapstr.py +82 -0
- synkit/Chem/Mapper/mapper.py +685 -0
- synkit/Chem/Mapper/reaction_search.py +554 -0
- synkit/Chem/Mapper/reporting/__init__.py +1 -0
- synkit/Chem/Mapper/reporting/alternatives.py +451 -0
- synkit/Chem/Mapper/reporting/analysis.py +681 -0
- synkit/Chem/Mapper/reporting/native_analysis.py +485 -0
- synkit/Chem/Mapper/reporting/spectrum.py +642 -0
- synkit/Chem/Mapper/solvers/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/__init__.py +141 -0
- synkit/Chem/Mapper/solvers/exact/assignment/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/assignment/assignment_certificate.py +113 -0
- synkit/Chem/Mapper/solvers/exact/assignment/assignment_domains.py +162 -0
- synkit/Chem/Mapper/solvers/exact/assignment/assignment_verification.py +58 -0
- synkit/Chem/Mapper/solvers/exact/assignment/incremental_assignment.py +247 -0
- synkit/Chem/Mapper/solvers/exact/certificate.py +128 -0
- synkit/Chem/Mapper/solvers/exact/core.py +183 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/bounds.py +319 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/exhaustive.py +179 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/inputs.py +283 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/records.py +242 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/search.py +1025 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/verify.py +378 -0
- synkit/Chem/Mapper/solvers/exact/edit_support.py +375 -0
- synkit/Chem/Mapper/solvers/exact/hybrid.py +224 -0
- synkit/Chem/Mapper/solvers/exact/hydrogen.py +264 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/branching.py +499 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/enumerate.py +1050 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/enumeration_result.py +30 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/kernel.py +256 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/milp.py +194 -0
- synkit/Chem/Mapper/solvers/exact/native/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/native/build.py +154 -0
- synkit/Chem/Mapper/solvers/exact/native/candidates.py +593 -0
- synkit/Chem/Mapper/solvers/exact/native/canonical.py +396 -0
- synkit/Chem/Mapper/solvers/exact/native/disk_frontier.py +415 -0
- synkit/Chem/Mapper/solvers/exact/native/frontier.py +390 -0
- synkit/Chem/Mapper/solvers/exact/native/hydrogen_quotient.py +213 -0
- synkit/Chem/Mapper/solvers/exact/native/its.py +528 -0
- synkit/Chem/Mapper/solvers/exact/native/native_distance.cpp +2803 -0
- synkit/Chem/Mapper/solvers/exact/native/orbit_aggregation.py +328 -0
- synkit/Chem/Mapper/solvers/exact/native/parallel.py +205 -0
- synkit/Chem/Mapper/solvers/exact/native/pmcd.py +203 -0
- synkit/Chem/Mapper/solvers/exact/native/runtime.py +40 -0
- synkit/Chem/Mapper/solvers/exact/native/search.py +294 -0
- synkit/Chem/Mapper/solvers/exact/native/separator.py +224 -0
- synkit/Chem/Mapper/solvers/exact/native_build.py +12 -0
- synkit/Chem/Mapper/solvers/exact/pabs/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/pabs/cost_lattice.py +43 -0
- synkit/Chem/Mapper/solvers/exact/pabs/factor_spectrum.py +110 -0
- synkit/Chem/Mapper/solvers/exact/pabs/multi_shell.py +368 -0
- synkit/Chem/Mapper/solvers/exact/pabs/propagation.py +679 -0
- synkit/Chem/Mapper/solvers/exact/pabs/propagation_bounds.py +436 -0
- synkit/Chem/Mapper/solvers/exact/pabs/propagation_limits.py +13 -0
- synkit/Chem/Mapper/solvers/exact/pabs/propagation_search.py +856 -0
- synkit/Chem/Mapper/solvers/exact/pabs/propagation_symmetry.py +66 -0
- synkit/Chem/Mapper/solvers/exact/pabs/residual_typed_bonds.py +136 -0
- synkit/Chem/Mapper/solvers/exact/pabs/reward_frontier.py +201 -0
- synkit/Chem/Mapper/solvers/exact/pabs/separator_bound.py +258 -0
- synkit/Chem/Mapper/solvers/exact/pabs/separator_spectrum.py +308 -0
- synkit/Chem/Mapper/solvers/exact/pabs/sparse_reward_bound.py +207 -0
- synkit/Chem/Mapper/solvers/exact/pabs/suffix_spectrum.py +299 -0
- synkit/Chem/Mapper/solvers/exact/search.py +55 -0
- synkit/Chem/Mapper/solvers/exact/seeds/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/seeds/seed.py +104 -0
- synkit/Chem/Mapper/solvers/exact/seeds/seed_fragments.py +148 -0
- synkit/Chem/Mapper/solvers/exact/seeds/seed_relaxation.py +181 -0
- synkit/Chem/Mapper/solvers/exact/symmetry.py +223 -0
- synkit/Chem/Mapper/solvers/native/__init__.py +4 -0
- synkit/Chem/Mapper/solvers/native/assignment.py +99 -0
- synkit/Chem/Mapper/solvers/native/astar.py +22 -0
- synkit/Chem/Mapper/solvers/native/build.py +385 -0
- synkit/Chem/Mapper/solvers/native/classification.py +641 -0
- synkit/Chem/Mapper/solvers/native/core.py +378 -0
- synkit/Chem/Mapper/solvers/native/cpp/CMakeLists.txt +120 -0
- synkit/Chem/Mapper/solvers/native/cpp/examples/map_reaction.cpp +29 -0
- synkit/Chem/Mapper/solvers/native/cpp/examples/slap_graph.cpp +63 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/assignment/assignment.h +18 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/astar/astar.h +18 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/astar/bound.h +33 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/core/pmcd_witness.h +16 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/core/runtime.h +130 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/hydrogen/hydrogen.h +73 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/mapper.h +175 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/mces/mces.h +9 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/pabs/seed.h +34 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/reaction/reaction.h +30 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/sepdp/sepdp.h +21 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/slap.h +72 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/solvers/solvers.h +16 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/symmetry/classification.h +140 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/symmetry/cpabs.h +33 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/assignment/abb.cpp +302 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/astar/CMakeLists.txt +12 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/astar/README.md +47 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/astar/astar.cpp +228 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/astar/astar_graph.cpp +37 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/astar/bound.cpp +212 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/core/dispatch.cpp +272 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/core/pmcd_witness.cpp +36 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/hydrogen/hydrogen.cpp +380 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/mces/README.md +57 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/mces/mces.cpp +287 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/bridge.cpp +334 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/chemical_floor.inc +181 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/endpoint_symmetry.inc +104 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/exact_helpers.h +20 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_assignment_certificate.h +165 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_certificate.h +125 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_model.h +365 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_provider.inc +319 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_rounding.inc +170 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_test_hooks.h +342 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/objective_reduction.inc +137 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/overlap_dual.inc +351 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/profile_seed.inc +214 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/seed_heuristics.inc +640 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/sparse_embedding.cpp +430 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/sparse_root_lp.h +176 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/test_hooks.inc +262 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/reaction/reaction.cpp +611 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/sepdp/README.md +61 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/sepdp/sepdp.cpp +253 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/slap.cpp +810 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/solvers/formulation.h +138 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/solvers/maxsat.cpp +526 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/solvers/ortools.cpp +475 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/solvers/seed.h +80 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/solvers/weighted_cnf.h +256 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/supporting/README.md +43 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/supporting/dfs.cpp +123 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/supporting/edit_support.cpp +224 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/classification.cpp +553 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/classification_pipeline.cpp +124 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/classification_stream.h +13 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/cpabs.cpp +455 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/edge_deck.cpp +743 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/COPYRIGHT +44 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/LICENSE-2.0.txt +202 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naugraph.c +732 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naurng.c +94 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naurng.h +49 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nausparse.c +1771 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nausparse.h +133 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nautil.c +750 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naututil.h +355 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nauty.c +1256 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nauty.h +1544 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/schreier.c +1131 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/schreier.h +70 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/sorttemplates.c +580 -0
- synkit/Chem/Mapper/solvers/native/hydrogen.py +711 -0
- synkit/Chem/Mapper/solvers/native/implicit.py +506 -0
- synkit/Chem/Mapper/solvers/native/implicit_certificate.py +187 -0
- synkit/Chem/Mapper/solvers/native/implicit_preparation.py +309 -0
- synkit/Chem/Mapper/solvers/native/lib/synkit_mapper.dll +0 -0
- synkit/Chem/Mapper/solvers/native/mces.py +16 -0
- synkit/Chem/Mapper/solvers/native/reaction.py +179 -0
- synkit/Chem/Mapper/solvers/native/reaction_build.py +277 -0
- synkit/Chem/Mapper/solvers/native/reaction_text.py +26 -0
- synkit/Chem/Mapper/solvers/native/runtime.py +242 -0
- synkit/Chem/Mapper/solvers/native/sepdp.py +47 -0
- synkit/Chem/Mapper/solvers/native/slap.py +266 -0
- synkit/Chem/Mapper/solvers/native/solvers.py +67 -0
- synkit/Chem/Mapper/solvers/native/stereo.py +86 -0
- synkit/Chem/Mapper/solvers/native/supporting.py +34 -0
- synkit/Chem/Mapper/solvers/native/symmetry.py +91 -0
- synkit/Chem/Mapper/solvers/slap/__init__.py +29 -0
- synkit/Chem/Mapper/solvers/slap/lap.py +174 -0
- synkit/Chem/Mapper/solvers/slap/sequential.py +696 -0
- synkit/Chem/Mapper/validation/__init__.py +1 -0
- synkit/Chem/Mapper/validation/aam_validator.py +442 -0
- synkit/Chem/Mapper/validation/annotations.py +274 -0
- synkit/Chem/Mapper/validation/bonds.py +124 -0
- synkit/Chem/Mapper/validation/cohorts.py +72 -0
- synkit/Chem/Mapper/validation/identifiability.py +150 -0
- synkit/Chem/Mapper/validation/numerical_scope.py +36 -0
- synkit/Chem/Mapper/validation/orbits.py +137 -0
- synkit/Chem/Molecule/__init__.py +0 -0
- synkit/Chem/Molecule/_chirality_loci.py +165 -0
- synkit/Chem/Molecule/_chirality_types.py +231 -0
- synkit/Chem/Molecule/_helical_loci.py +167 -0
- synkit/Chem/Molecule/_stereo_axis_evidence.py +202 -0
- synkit/Chem/Molecule/_stereo_element_detection.py +193 -0
- synkit/Chem/Molecule/_stereo_orientation_constraints.py +511 -0
- synkit/Chem/Molecule/_tetrahedral_carriers.py +63 -0
- synkit/Chem/Molecule/atom_features.py +379 -0
- synkit/Chem/Molecule/chirality.py +1041 -0
- synkit/Chem/Molecule/cip_assignment.py +569 -0
- synkit/Chem/Molecule/cip_ranking.py +843 -0
- synkit/Chem/Molecule/coordinate_stereo.py +503 -0
- synkit/Chem/Molecule/derived_stereo_naming.py +165 -0
- synkit/Chem/Molecule/descriptors.py +452 -0
- synkit/Chem/Molecule/formula.py +249 -0
- synkit/Chem/Molecule/global_stereo.py +175 -0
- synkit/Chem/Molecule/graph_annotator.py +300 -0
- synkit/Chem/Molecule/standardize.py +817 -0
- synkit/Chem/Molecule/stereo_evidence.py +179 -0
- synkit/Chem/Molecule/stereo_perception.py +1032 -0
- synkit/Chem/Molecule/valence.py +123 -0
- synkit/Chem/Reaction/Mapper/__init__.py +44 -0
- synkit/Chem/Reaction/__init__.py +20 -0
- synkit/Chem/Reaction/aam_validator.py +5 -0
- synkit/Chem/Reaction/balance_check.py +138 -0
- synkit/Chem/Reaction/canon_rsmi.py +249 -0
- synkit/Chem/Reaction/cleaning.py +58 -0
- synkit/Chem/Reaction/deionize.py +199 -0
- synkit/Chem/Reaction/explicit_h_audit.py +232 -0
- synkit/Chem/Reaction/fix_aam.py +64 -0
- synkit/Chem/Reaction/neutralize.py +207 -0
- synkit/Chem/Reaction/radical_wildcard.py +224 -0
- synkit/Chem/Reaction/standardize.py +203 -0
- synkit/Chem/Reaction/tautomerize.py +205 -0
- synkit/Chem/__init__.py +1 -0
- synkit/Chem/utils.py +315 -0
- synkit/Data/__init__.py +0 -0
- synkit/Data/aldol.json.gz +1 -0
- synkit/Data/gen_partial_aam.py +147 -0
- synkit/Data/paracetamol.json.gz +1 -0
- synkit/Graph/Canon/__init__.py +16 -0
- synkit/Graph/Canon/_native/__init__.py +13 -0
- synkit/Graph/Canon/_native/build.py +93 -0
- synkit/Graph/Canon/_native/lib/synkit_canon.dll +0 -0
- synkit/Graph/Canon/_native/prepare.py +49 -0
- synkit/Graph/Canon/_native/runtime.py +140 -0
- synkit/Graph/Canon/_native/search.py +137 -0
- synkit/Graph/Canon/canon_algs.py +228 -0
- synkit/Graph/Canon/canon_graph.py +531 -0
- synkit/Graph/Canon/cpp/CMakeLists.txt +42 -0
- synkit/Graph/Canon/cpp/README.md +123 -0
- synkit/Graph/Canon/cpp/examples/canonical_graph.cpp +16 -0
- synkit/Graph/Canon/cpp/include/synkit_canon/canon.h +85 -0
- synkit/Graph/Canon/cpp/src/canonical.cpp +391 -0
- synkit/Graph/Canon/cpp/src/symmetry.h +83 -0
- synkit/Graph/Canon/cpp/tests/symmetry.cpp +93 -0
- synkit/Graph/Canon/exact.py +1020 -0
- synkit/Graph/Canon/exact_refinement.py +368 -0
- synkit/Graph/Canon/nauty.py +143 -0
- synkit/Graph/Context/__init__.py +0 -0
- synkit/Graph/Context/hier_context.py +244 -0
- synkit/Graph/Context/radius_expand.py +252 -0
- synkit/Graph/FG/__init__.py +19 -0
- synkit/Graph/FG/api.py +39 -0
- synkit/Graph/FG/audit.py +155 -0
- synkit/Graph/FG/catalog.py +919 -0
- synkit/Graph/FG/detector.py +288 -0
- synkit/Graph/FG/model.py +97 -0
- synkit/Graph/FG/recognizers.py +274 -0
- synkit/Graph/FG/ring_system.py +154 -0
- synkit/Graph/Feature/Descriptors/topology.py +857 -0
- synkit/Graph/Feature/Fingerprint/__init__.py +0 -0
- synkit/Graph/Feature/Fingerprint/wl_rxn_fps.py +222 -0
- synkit/Graph/Feature/__init__.py +5 -0
- synkit/Graph/Feature/graph_descriptors.py +323 -0
- synkit/Graph/Feature/graph_fps.py +96 -0
- synkit/Graph/Feature/graph_signature.py +239 -0
- synkit/Graph/Feature/hash_fps.py +133 -0
- synkit/Graph/Feature/morgan_fps.py +88 -0
- synkit/Graph/Feature/path_fps.py +81 -0
- synkit/Graph/Feature/wl_hash.py +134 -0
- synkit/Graph/Fusion/__init__.py +85 -0
- synkit/Graph/Fusion/candidate.py +559 -0
- synkit/Graph/Fusion/constructor.py +877 -0
- synkit/Graph/Fusion/identity.py +184 -0
- synkit/Graph/Fusion/interface.py +700 -0
- synkit/Graph/Fusion/search.py +241 -0
- synkit/Graph/Hyrogen/__init__.py +6 -0
- synkit/Graph/Hyrogen/_misc.py +591 -0
- synkit/Graph/Hyrogen/hcomplete.py +995 -0
- synkit/Graph/Hyrogen/hcomplete_legacy.py +368 -0
- synkit/Graph/Hyrogen/hcompletion_algorithms.py +713 -0
- synkit/Graph/Hyrogen/hextend.py +570 -0
- synkit/Graph/Hyrogen/hextend_legacy.py +215 -0
- synkit/Graph/ITS/__init__.py +4 -0
- synkit/Graph/ITS/its_builder.py +120 -0
- synkit/Graph/ITS/its_construction.py +719 -0
- synkit/Graph/ITS/its_decompose.py +572 -0
- synkit/Graph/ITS/its_destruction.py +331 -0
- synkit/Graph/ITS/its_expand.py +1251 -0
- synkit/Graph/ITS/its_relabel.py +187 -0
- synkit/Graph/ITS/its_reverter.py +356 -0
- synkit/Graph/ITS/normalize_aam.py +145 -0
- synkit/Graph/ITS/partial_its.py +238 -0
- synkit/Graph/ITS/rc_extractor.py +656 -0
- synkit/Graph/ITS/stereo.py +74 -0
- synkit/Graph/MTG/__init__.py +107 -0
- synkit/Graph/MTG/gluing.py +451 -0
- synkit/Graph/MTG/history.py +928 -0
- synkit/Graph/MTG/inventory.py +118 -0
- synkit/Graph/MTG/local.py +447 -0
- synkit/Graph/MTG/mcs_matcher.py +246 -0
- synkit/Graph/MTG/mtg.py +611 -0
- synkit/Graph/MTG/mtg_explore.py +74 -0
- synkit/Graph/MTG/observation.py +209 -0
- synkit/Graph/MTG/process.py +577 -0
- synkit/Graph/MTG/queries.py +66 -0
- synkit/Graph/MTG/realization.py +95 -0
- synkit/Graph/MTG/series_parallel.py +107 -0
- synkit/Graph/MTG/utils.py +424 -0
- synkit/Graph/Matcher/__init__.py +10 -0
- synkit/Graph/Matcher/approx_mcs.py +1264 -0
- synkit/Graph/Matcher/auto_est.py +736 -0
- synkit/Graph/Matcher/automorphism.py +314 -0
- synkit/Graph/Matcher/batch_cluster.py +224 -0
- synkit/Graph/Matcher/dedup_matches.py +247 -0
- synkit/Graph/Matcher/graph_cluster.py +191 -0
- synkit/Graph/Matcher/graph_matcher.py +312 -0
- synkit/Graph/Matcher/graph_morphism.py +421 -0
- synkit/Graph/Matcher/mcs_matcher.py +804 -0
- synkit/Graph/Matcher/multi_turbo_iso.py +186 -0
- synkit/Graph/Matcher/orbit.py +284 -0
- synkit/Graph/Matcher/partial_matcher.py +694 -0
- synkit/Graph/Matcher/sing.py +544 -0
- synkit/Graph/Matcher/subgraph_matcher.py +812 -0
- synkit/Graph/Matcher/turbo_iso.py +272 -0
- synkit/Graph/Matcher/wl_sel.py +537 -0
- synkit/Graph/Mech/__init__.py +26 -0
- synkit/Graph/Mech/conversion.py +1466 -0
- synkit/Graph/Mech/conversion_debug.py +237 -0
- synkit/Graph/Mech/electron_accounting.py +200 -0
- synkit/Graph/Mech/lwg_editor.py +406 -0
- synkit/Graph/Mech/lwg_ops.py +313 -0
- synkit/Graph/Morphism/__init__.py +99 -0
- synkit/Graph/Morphism/constraints.py +460 -0
- synkit/Graph/Morphism/llg.py +999 -0
- synkit/Graph/Morphism/morphism.py +349 -0
- synkit/Graph/Morphism/stereo.py +258 -0
- synkit/Graph/Morphism/stereo_morphism.py +383 -0
- synkit/Graph/Morphism/stereo_morphism_helpers.py +957 -0
- synkit/Graph/Morphism/stereo_morphism_types.py +117 -0
- synkit/Graph/Stereo/__init__.py +376 -0
- synkit/Graph/Stereo/_descriptor_core.py +207 -0
- synkit/Graph/Stereo/_descriptor_serialization.py +138 -0
- synkit/Graph/Stereo/canonical.py +648 -0
- synkit/Graph/Stereo/changes.py +964 -0
- synkit/Graph/Stereo/composition.py +391 -0
- synkit/Graph/Stereo/configured.py +946 -0
- synkit/Graph/Stereo/couplings.py +245 -0
- synkit/Graph/Stereo/descriptors.py +1030 -0
- synkit/Graph/Stereo/enumeration.py +597 -0
- synkit/Graph/Stereo/extended_descriptors.py +406 -0
- synkit/Graph/Stereo/global_configured.py +152 -0
- synkit/Graph/Stereo/global_stereo.py +304 -0
- synkit/Graph/Stereo/identity.py +648 -0
- synkit/Graph/Stereo/interchange.py +496 -0
- synkit/Graph/Stereo/legacy.py +460 -0
- synkit/Graph/Stereo/matching.py +899 -0
- synkit/Graph/Stereo/native.py +154 -0
- synkit/Graph/Stereo/orbits.py +668 -0
- synkit/Graph/Stereo/outcomes.py +99 -0
- synkit/Graph/Stereo/pairwise.py +350 -0
- synkit/Graph/Stereo/rdkit_adapter.py +662 -0
- synkit/Graph/Stereo/rdkit_identity.py +118 -0
- synkit/Graph/Stereo/rdkit_resonance.py +140 -0
- synkit/Graph/Stereo/reaction_interchange.py +266 -0
- synkit/Graph/Stereo/semantics.py +296 -0
- synkit/Graph/Stereo/supports.py +257 -0
- synkit/Graph/Stereo/wire.py +339 -0
- synkit/Graph/Wildcard/__init__.py +0 -0
- synkit/Graph/Wildcard/fuse_graph.py +156 -0
- synkit/Graph/Wildcard/graph_wc.py +303 -0
- synkit/Graph/Wildcard/its_merge.py +857 -0
- synkit/Graph/Wildcard/radwc.py +114 -0
- synkit/Graph/Wildcard/wc_matcher.py +576 -0
- synkit/Graph/Wildcard/wildcard.py +225 -0
- synkit/Graph/__init__.py +17 -0
- synkit/Graph/canon_graph.py +14 -0
- synkit/Graph/syn_graph.py +199 -0
- synkit/Graph/utils.py +324 -0
- synkit/IO/__init__.py +4 -0
- synkit/IO/chem_converter.py +1059 -0
- synkit/IO/combinatorial/__init__.py +8 -0
- synkit/IO/combinatorial/gml_to_graph.py +223 -0
- synkit/IO/combinatorial/graph_to_gml.py +280 -0
- synkit/IO/combinatorial/graph_to_smarts.py +186 -0
- synkit/IO/combinatorial/smarts_expander.py +147 -0
- synkit/IO/combinatorial/smarts_generalizer.py +133 -0
- synkit/IO/combinatorial/smarts_to_graph.py +179 -0
- synkit/IO/conversion.py +42 -0
- synkit/IO/data_io.py +269 -0
- synkit/IO/data_process.py +143 -0
- synkit/IO/debug.py +73 -0
- synkit/IO/gml_to_nx.py +150 -0
- synkit/IO/graph_to_mol.py +199 -0
- synkit/IO/mol_to_graph.py +1105 -0
- synkit/IO/mol_to_graph_chemistry.py +545 -0
- synkit/IO/nx_to_gml.py +209 -0
- synkit/IO/smiles_to_id.py +123 -0
- synkit/Mechanism/__init__.py +151 -0
- synkit/Mechanism/adapters.py +136 -0
- synkit/Mechanism/audit.py +323 -0
- synkit/Mechanism/benchmark.py +638 -0
- synkit/Mechanism/compatibility.py +13 -0
- synkit/Mechanism/drawing.py +85 -0
- synkit/Mechanism/electron_models.py +725 -0
- synkit/Mechanism/equivalence.py +521 -0
- synkit/Mechanism/evidence.py +262 -0
- synkit/Mechanism/interchange.py +141 -0
- synkit/Mechanism/model.py +918 -0
- synkit/Mechanism/neighbor_stereo.py +312 -0
- synkit/Mechanism/radical_data.py +740 -0
- synkit/Mechanism/replay.py +986 -0
- synkit/Mechanism/schema.py +264 -0
- synkit/Mechanism/stereo_state.py +416 -0
- synkit/Mechanism/symbols.py +91 -0
- synkit/Rule/Apply/__init__.py +35 -0
- synkit/Rule/Apply/conditions.py +45 -0
- synkit/Rule/Apply/dpo.py +998 -0
- synkit/Rule/Apply/rule_matcher.py +218 -0
- synkit/Rule/Apply/validation.py +354 -0
- synkit/Rule/Compose/__init__.py +106 -0
- synkit/Rule/Compose/_identity.py +43 -0
- synkit/Rule/Compose/composition.py +976 -0
- synkit/Rule/Compose/laws.py +439 -0
- synkit/Rule/Compose/search.py +771 -0
- synkit/Rule/Compose/synrule.py +170 -0
- synkit/Rule/Modify/__init__.py +0 -0
- synkit/Rule/Modify/implict_rule.py +56 -0
- synkit/Rule/Modify/longest_path.py +92 -0
- synkit/Rule/Modify/molecule_rule.py +115 -0
- synkit/Rule/Modify/prune_templates.py +78 -0
- synkit/Rule/Modify/rule_utils.py +194 -0
- synkit/Rule/Modify/strip_rule.py +97 -0
- synkit/Rule/__init__.py +28 -0
- synkit/Rule/generic_stereo.py +884 -0
- synkit/Rule/stereo_identity.py +271 -0
- synkit/Rule/syn_rule.py +1090 -0
- synkit/Synthesis/MSR/__init__.py +0 -0
- synkit/Synthesis/MSR/path_finder.py +239 -0
- synkit/Synthesis/Metrics/__init__.py +0 -0
- synkit/Synthesis/Metrics/_base.py +52 -0
- synkit/Synthesis/Metrics/_plot.py +129 -0
- synkit/Synthesis/Metrics/_ranking.py +179 -0
- synkit/Synthesis/RBL/__init__.py +80 -0
- synkit/Synthesis/RBL/engine.py +1249 -0
- synkit/Synthesis/RBL/matching.py +652 -0
- synkit/Synthesis/RBL/overlap.py +336 -0
- synkit/Synthesis/RBL/pipeline.py +376 -0
- synkit/Synthesis/RBL/policy.py +139 -0
- synkit/Synthesis/RBL/proof.py +370 -0
- synkit/Synthesis/RBL/reaction.py +506 -0
- synkit/Synthesis/RBL/state.py +169 -0
- synkit/Synthesis/RBL/validation.py +1060 -0
- synkit/Synthesis/Reactor/__init__.py +60 -0
- synkit/Synthesis/Reactor/core/__init__.py +1 -0
- synkit/Synthesis/Reactor/core/engine.py +967 -0
- synkit/Synthesis/Reactor/core/product.py +621 -0
- synkit/Synthesis/Reactor/core/rewrite.py +561 -0
- synkit/Synthesis/Reactor/core/strategy.py +44 -0
- synkit/Synthesis/Reactor/matching/__init__.py +1 -0
- synkit/Synthesis/Reactor/matching/mixin.py +920 -0
- synkit/Synthesis/Reactor/matching/policy.py +345 -0
- synkit/Synthesis/Reactor/matching/symmetry.py +309 -0
- synkit/Synthesis/Reactor/output/__init__.py +1 -0
- synkit/Synthesis/Reactor/output/deduplication.py +703 -0
- synkit/Synthesis/Reactor/output/policy.py +16 -0
- synkit/Synthesis/Reactor/output/serialization.py +485 -0
- synkit/Synthesis/Reactor/output/structural.py +893 -0
- synkit/Synthesis/Reactor/stereo/__init__.py +1 -0
- synkit/Synthesis/Reactor/stereo/assignment.py +35 -0
- synkit/Synthesis/Reactor/stereo/mixin.py +780 -0
- synkit/Synthesis/Reactor/variants/__init__.py +1 -0
- synkit/Synthesis/Reactor/variants/imbalanced.py +180 -0
- synkit/Synthesis/Reactor/variants/partial.py +84 -0
- synkit/Synthesis/Reactor/workflow/__init__.py +1 -0
- synkit/Synthesis/Reactor/workflow/batch.py +550 -0
- synkit/Synthesis/Reactor/workflow/benchmark.py +143 -0
- synkit/Synthesis/Reactor/workflow/postprocess.py +267 -0
- synkit/Synthesis/Reactor/workflow/rule_filter.py +210 -0
- synkit/Synthesis/__init__.py +0 -0
- synkit/Synthesis/reactor_utils.py +316 -0
- synkit/Utils/__init__.py +0 -0
- synkit/Utils/utils.py +172 -0
- synkit/Vis/__init__.py +91 -0
- synkit/Vis/crn/__init__.py +40 -0
- synkit/Vis/epd/__init__.py +20 -0
- synkit/Vis/epd/arrows.py +425 -0
- synkit/Vis/epd/chem.py +197 -0
- synkit/Vis/epd/constants.py +83 -0
- synkit/Vis/epd/layout.py +283 -0
- synkit/Vis/epd/mapping.py +51 -0
- synkit/Vis/epd/models.py +136 -0
- synkit/Vis/epd/render.py +543 -0
- synkit/Vis/epd/utils.py +108 -0
- synkit/Vis/epd/visualizer.py +811 -0
- synkit/Vis/graph_visualizer.py +375 -0
- synkit/Vis/its/__init__.py +19 -0
- synkit/Vis/its/drawer.py +615 -0
- synkit/Vis/its_drawer.py +35 -0
- synkit/Vis/molecule/__init__.py +31 -0
- synkit/Vis/molecule/drawer.py +563 -0
- synkit/Vis/molecule/reaction.py +285 -0
- synkit/Vis/molecule_drawer.py +33 -0
- synkit/Vis/mtg/__init__.py +17 -0
- synkit/Vis/mtg/drawer.py +769 -0
- synkit/Vis/mtg_drawer.py +34 -0
- synkit/Vis/pdf_writer.py +146 -0
- synkit/Vis/reaction/__init__.py +19 -0
- synkit/Vis/reaction/rule.py +141 -0
- synkit/Vis/reaction/rxn.py +532 -0
- synkit/Vis/reaction_drawer.py +41 -0
- synkit/Vis/space/__init__.py +17 -0
- synkit/Vis/space/chemical.py +80 -0
- synkit/Vis/space/embedding.py +87 -0
- synkit/Vis/vis_synedu/Vis/__init__.py +7 -0
- synkit/Vis/vis_synedu/Vis/dpo.py +862 -0
- synkit/Vis/vis_synedu/rxn_vis.py +377 -0
- synkit/Vis/vis_synedu/vis.py +501 -0
- synkit/Vis/visual_drawer.py +215 -0
- synkit/Vis/visual_model.py +520 -0
- synkit/__init__.py +3 -0
- synkit/_native.py +91 -0
- synkit/examples.py +50 -0
- synkit/version.py +23 -0
- synkit-1.6.5.dist-info/METADATA +156 -0
- synkit-1.6.5.dist-info/RECORD +636 -0
- synkit-1.6.5.dist-info/WHEEL +4 -0
- synkit-1.6.5.dist-info/licenses/LICENSE +21 -0
- synkit-1.6.5.dist-info/licenses/synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/COPYRIGHT +44 -0
- 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 @@
|
|
|
1
|
+
[{"R-id": 1, "aam": "[c:4]1([H:11])[cH:5][cH:6][cH:7][cH:8][cH:9]1.[CH3:1][CH:2]([CH3:3])[Cl:10]>>[CH3:1][CH:2]([CH3:3])[c:4]1[cH:5][cH:6][cH:7][cH:8][cH:9]1.[H:11][Cl:10]"}, {"R-id": 2, "aam": "[CH3:1][C:2]([H:12])([CH3:3])[c:6]1[cH:7][cH:8][cH:9][cH:10][cH:11]1.[O:4]=[O:5]>>[CH3:1][C:2]([CH3:3])([O:4][O:5][H:12])[c:6]1[cH:7][cH:8][cH:9][cH:10][cH:11]1"}, {"R-id": 3, "aam": "[CH3:8][C:9]([CH3:11])([O:10][OH:1])[c:2]1[cH:3][cH:4][cH:5][cH:6][cH:7]1>>[OH:1][c:2]1[cH:3][cH:4][cH:5][cH:6][cH:7]1.[CH3:8][C:9](=[O:10])[CH3:11]"}, {"R-id": 4, "aam": "[H:12][O:4][c:5]1[cH:6][cH:7][cH:8][cH:9][cH:10]1.[CH3:1][C:2](=[O:3])[Cl:11]>>[CH3:1][C:2](=[O:3])[O:4][c:5]1[cH:6][cH:7][cH:8][cH:9][cH:10]1.[Cl:11][H:12]"}, {"R-id": 5, "aam": "[CH3:11][C:9](=[O:10])[O:8][c:7]1[cH:6][cH:5][c:4]([H:15])[cH:13][cH:12]1.[O:1]=[N+:2]([O-:3])[OH:14]>>[O:1]=[N+:2]([O-:3])[c:4]1[cH:5][cH:6][c:7]([O:8][C:9](=[O:10])[CH3:11])[cH:12][cH:13]1.[OH:14][H:15]"}, {"R-id": 6, "aam": "[O:12]=[N+:1]([O-:13])[c:2]1[cH:3][cH:4][c:5]([O:6][C:7](=[O:8])[CH3:9])[cH:10][cH:11]1.[H:14][H:15].[H:16][H:18].[H:17][H:19]>>[N:1]([H:18])([H:19])[c:2]1[cH:3][cH:4][c:5]([O:6][C:7](=[O:8])[CH3:9])[cH:10][cH:11]1.[H:14][O:12][H:15].[H:16][O:13][H:17]"}, {"R-id": 7, "aam": "[NH2:1][c:2]1[cH:3][cH:4][c:5]([O:6][C:10](=[O:11])[CH3:9])[cH:7][cH:8]1.[OH:12][H:13]>>[NH2:1][c:2]1[cH:3][cH:4][c:5]([O:6][H:13])[cH:7][cH:8]1.[CH3:9][C:10](=[O:11])[OH:12]"}, {"R-id": 8, "aam": "[H:13][NH:4][c:5]1[cH:6][cH:7][c:8]([OH:9])[cH:10][cH:11]1.[CH3:1][C:2](=[O:3])[Cl:12]>>[CH3:1][C:2](=[O:3])[NH:4][c:5]1[cH:6][cH:7][c:8]([OH:9])[cH:10][cH:11]1.[Cl:12][H:13]"}, {"R-id": 9, "aam": "[CH3:19][C:17](=[O:18])[NH:16][c:13]1[cH:12][cH:11][c:10]([O:9][H:21])[cH:15][cH:14]1.[CH3:1][CH2:2][N:3]([CH2:4][CH3:5])[CH2:6][C:7](=[O:8])[Cl:20]>>[CH3:1][CH2:2][N:3]([CH2:4][CH3:5])[CH2:6][C:7](=[O:8])[O:9][C:10]1=[CH:11][CH:12]=[C:13]([NH:16][C:17](=[O:18])[CH3:19])[CH:14]=[CH:15]1.[Cl:20][H:21]"}]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from .canon_graph import GraphCanonicaliser, CanonicalGraph
|
|
2
|
+
from .exact import (
|
|
3
|
+
CanonicalSearchIncomplete,
|
|
4
|
+
ExactCanonicalResult,
|
|
5
|
+
ExactColoredGraphCanonicalizer,
|
|
6
|
+
IncompleteCanonicalResult,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"CanonicalGraph",
|
|
11
|
+
"CanonicalSearchIncomplete",
|
|
12
|
+
"ExactCanonicalResult",
|
|
13
|
+
"ExactColoredGraphCanonicalizer",
|
|
14
|
+
"GraphCanonicaliser",
|
|
15
|
+
"IncompleteCanonicalResult",
|
|
16
|
+
]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Opt-in native graph backend using a bundled or explicitly built library."""
|
|
2
|
+
|
|
3
|
+
from .build import build_native_canon
|
|
4
|
+
from .runtime import CancellationToken, bundled_native_canon
|
|
5
|
+
from .search import NativeCanonicalResult, canonicalize_native_graph
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"build_native_canon",
|
|
9
|
+
"bundled_native_canon",
|
|
10
|
+
"CancellationToken",
|
|
11
|
+
"NativeCanonicalResult",
|
|
12
|
+
"canonicalize_native_graph",
|
|
13
|
+
]
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""Explicit immutable CMake builds of the dependency-free C++17 graph core."""
|
|
2
|
+
|
|
3
|
+
import hashlib
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
import platform
|
|
8
|
+
import shutil
|
|
9
|
+
import subprocess
|
|
10
|
+
import sys
|
|
11
|
+
import tempfile
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _digest(path):
|
|
15
|
+
return hashlib.sha256(Path(path).read_bytes()).hexdigest()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _verify(path):
|
|
19
|
+
probe = subprocess.run(
|
|
20
|
+
[sys.executable, "-c", "import ctypes,sys; assert ctypes.CDLL(sys.argv[1]).synkit_canon_abi()==1", str(path)],
|
|
21
|
+
capture_output=True, text=True,
|
|
22
|
+
)
|
|
23
|
+
if probe.returncode:
|
|
24
|
+
raise RuntimeError("Built graph core advertises an incompatible ABI")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _run(command):
|
|
28
|
+
result = subprocess.run(command, capture_output=True, text=True)
|
|
29
|
+
if result.returncode:
|
|
30
|
+
raise RuntimeError("Native graph build failed:\n" + (result.stdout + result.stderr)[-6000:])
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def build_native_canon(output_dir, *, compiler=None):
|
|
34
|
+
"""Build explicitly and return a content-addressed library with provenance.
|
|
35
|
+
|
|
36
|
+
No native build or dependency download occurs during package import.
|
|
37
|
+
CMake and a C++17 compiler are developer requirements, not runtime SDKs.
|
|
38
|
+
"""
|
|
39
|
+
cmake = shutil.which("cmake")
|
|
40
|
+
if cmake is None:
|
|
41
|
+
raise RuntimeError("CMake is required for an explicit native graph build")
|
|
42
|
+
if compiler is not None:
|
|
43
|
+
compiler = shutil.which(compiler)
|
|
44
|
+
if compiler is None:
|
|
45
|
+
raise RuntimeError("Requested C++ compiler is unavailable")
|
|
46
|
+
source = Path(__file__).resolve().parents[1] / "cpp"
|
|
47
|
+
inputs = [p for p in source.rglob("*") if p.is_file()
|
|
48
|
+
and (p.name in {"CMakeLists.txt", "README.md"}
|
|
49
|
+
or p.relative_to(source).parts[0] in {"include", "src", "examples", "tests"})]
|
|
50
|
+
detected_compiler = compiler or shutil.which(os.environ.get("CXX", "cl" if os.name == "nt" else "c++"))
|
|
51
|
+
compiler_info = subprocess.run([detected_compiler, "--version"], capture_output=True, text=True) \
|
|
52
|
+
if detected_compiler else None
|
|
53
|
+
config = {
|
|
54
|
+
"abi": 1, "builder_sha256": _digest(__file__),
|
|
55
|
+
"sources": {str(p.relative_to(source)): _digest(p) for p in sorted(inputs)},
|
|
56
|
+
"cmake": subprocess.check_output([cmake, "--version"], text=True),
|
|
57
|
+
"compiler": compiler, "platform": sys.platform, "machine": platform.machine(),
|
|
58
|
+
"detected_compiler": detected_compiler,
|
|
59
|
+
"compiler_version": (compiler_info.stdout + compiler_info.stderr) if compiler_info else None,
|
|
60
|
+
"environment": {k: os.environ.get(k) for k in ("CXX", "CXXFLAGS", "CMAKE_GENERATOR")},
|
|
61
|
+
}
|
|
62
|
+
key = hashlib.sha256(json.dumps(config, sort_keys=True).encode()).hexdigest()
|
|
63
|
+
output = Path(output_dir).expanduser().resolve()
|
|
64
|
+
output.mkdir(parents=True, exist_ok=True)
|
|
65
|
+
suffix = ".dll" if os.name == "nt" else ".dylib" if sys.platform == "darwin" else ".so"
|
|
66
|
+
library = output / ("libsynkit_canon_" + key[:20] + suffix)
|
|
67
|
+
manifest = library.with_suffix(".json")
|
|
68
|
+
if library.exists():
|
|
69
|
+
if not manifest.exists():
|
|
70
|
+
raise RuntimeError("Existing graph library has no build manifest")
|
|
71
|
+
saved = json.loads(manifest.read_text())
|
|
72
|
+
if saved.get("configuration") != config or saved.get("library_sha256") != _digest(library):
|
|
73
|
+
raise RuntimeError("Native graph build integrity verification failed")
|
|
74
|
+
_verify(library)
|
|
75
|
+
return library
|
|
76
|
+
with tempfile.TemporaryDirectory(prefix="synkit-canon-build-", dir=output) as name:
|
|
77
|
+
work = Path(name)
|
|
78
|
+
configure = [cmake, "-S", str(source), "-B", str(work), "-DCMAKE_BUILD_TYPE=Release"]
|
|
79
|
+
if compiler:
|
|
80
|
+
configure.append("-DCMAKE_CXX_COMPILER=" + compiler)
|
|
81
|
+
_run(configure)
|
|
82
|
+
_run([cmake, "--build", str(work), "--config", "Release", "--parallel", "2"])
|
|
83
|
+
built = list(work.rglob("*synkit_canon" + suffix))
|
|
84
|
+
if len(built) != 1:
|
|
85
|
+
raise RuntimeError(f"Expected one native graph library, found {built}")
|
|
86
|
+
_verify(built[0])
|
|
87
|
+
cache = (work / "CMakeCache.txt").read_text()
|
|
88
|
+
shutil.copy2(built[0], library)
|
|
89
|
+
manifest.write_text(json.dumps({
|
|
90
|
+
"configuration": config, "library_sha256": _digest(library),
|
|
91
|
+
"cmake_cache": cache,
|
|
92
|
+
}, indent=2) + "\n")
|
|
93
|
+
return library
|
|
Binary file
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Snapshot exact typed colors and simple graph incidence for the native core."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
import json
|
|
5
|
+
|
|
6
|
+
import networkx as nx
|
|
7
|
+
|
|
8
|
+
from ..exact import _encode_color, _selector_value
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(frozen=True)
|
|
12
|
+
class PreparedGraph:
|
|
13
|
+
"""Immutable Python-owned CSR snapshot; input handles are output witnesses."""
|
|
14
|
+
|
|
15
|
+
nodes: tuple
|
|
16
|
+
offsets: tuple[int, ...]
|
|
17
|
+
neighbors: tuple[int, ...]
|
|
18
|
+
colors: tuple[int, ...]
|
|
19
|
+
palette_bytes: bytes
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def prepare_graph(graph, *, node_color="color", edge_color=None):
|
|
23
|
+
"""Prepare a simple undirected vertex-colored graph without normalization.
|
|
24
|
+
|
|
25
|
+
Edge attributes are intentionally outside this prepared graph contract.
|
|
26
|
+
An explicit edge-color selector is refused; encode typed edges as colored
|
|
27
|
+
incidence vertices first, as the stereo expansion already does.
|
|
28
|
+
"""
|
|
29
|
+
if not isinstance(graph, nx.Graph) or graph.is_directed() or graph.is_multigraph():
|
|
30
|
+
raise TypeError("Native graph search requires a simple undirected graph")
|
|
31
|
+
if edge_color is not None:
|
|
32
|
+
raise NotImplementedError("Encode edge colors as incidence vertices before native search")
|
|
33
|
+
if nx.number_of_selfloops(graph):
|
|
34
|
+
raise ValueError("Native graph search does not support self loops")
|
|
35
|
+
nodes = tuple(graph)
|
|
36
|
+
if len(nodes) > 2**31 - 1:
|
|
37
|
+
raise ValueError("Native graph dimensions exceed int32 vertex capacity")
|
|
38
|
+
tokens = tuple(_encode_color(_selector_value(graph.nodes[v], node_color)) for v in nodes)
|
|
39
|
+
palette = sorted(set(tokens))
|
|
40
|
+
ranks = {token: i for i, token in enumerate(palette)}
|
|
41
|
+
indices = {v: i for i, v in enumerate(nodes)}
|
|
42
|
+
offsets, neighbors = [0], []
|
|
43
|
+
for v in nodes:
|
|
44
|
+
neighbors.extend(sorted(indices[w] for w in graph[v]))
|
|
45
|
+
offsets.append(len(neighbors))
|
|
46
|
+
return PreparedGraph(
|
|
47
|
+
nodes, tuple(offsets), tuple(neighbors), tuple(ranks[t] for t in tokens),
|
|
48
|
+
json.dumps(palette, separators=(",", ":"), ensure_ascii=True).encode("ascii"),
|
|
49
|
+
)
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"""Versioned ctypes declarations and cancellation ownership for graph search."""
|
|
2
|
+
|
|
3
|
+
import ctypes as ct
|
|
4
|
+
from contextlib import contextmanager
|
|
5
|
+
from functools import lru_cache
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from threading import Lock
|
|
8
|
+
|
|
9
|
+
from synkit._native import bundled_library, verify_wheel_library
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def bundled_native_canon():
|
|
13
|
+
"""Return the graph/stereograph library installed with a platform wheel."""
|
|
14
|
+
return bundled_library(Path(__file__).parent, "synkit_canon")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def resolve_library_path(library_path=None):
|
|
18
|
+
return (Path(library_path).expanduser().resolve()
|
|
19
|
+
if library_path is not None else bundled_native_canon())
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Request(ct.Structure):
|
|
23
|
+
_fields_ = [
|
|
24
|
+
("abi_version", ct.c_int32), ("struct_size", ct.c_int32),
|
|
25
|
+
("n", ct.c_int64), ("arcs", ct.c_int64),
|
|
26
|
+
("offsets", ct.POINTER(ct.c_int64)),
|
|
27
|
+
("neighbors", ct.POINTER(ct.c_int32)),
|
|
28
|
+
("colors", ct.POINTER(ct.c_int32)), ("seconds", ct.c_double),
|
|
29
|
+
("max_nodes", ct.c_int64), ("workspace_bytes", ct.c_int64),
|
|
30
|
+
("output_bytes", ct.c_int64), ("max_depth", ct.c_int32),
|
|
31
|
+
("cancel_token", ct.c_void_p),
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class Statistics(ct.Structure):
|
|
36
|
+
_fields_ = [
|
|
37
|
+
("complete", ct.c_int32), ("reason", ct.c_int32),
|
|
38
|
+
("nodes", ct.c_int64), ("leaves", ct.c_int64),
|
|
39
|
+
("refinement_rounds", ct.c_int64), ("peak_workspace_bytes", ct.c_int64),
|
|
40
|
+
("elapsed_seconds", ct.c_double),
|
|
41
|
+
("validation_seconds", ct.c_double), ("search_seconds", ct.c_double),
|
|
42
|
+
("serialization_seconds", ct.c_double),
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class PruningStatistics(ct.Structure):
|
|
47
|
+
_fields_ = [(name, ct.c_int64) for name in (
|
|
48
|
+
"implicit_twin_factors", "twin_vertices", "automorphism_generators", "orbit_rebuilds",
|
|
49
|
+
"symmetry_pruned_branches", "stabilizer_calls", "stabilizer_fallbacks",
|
|
50
|
+
)]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@lru_cache(maxsize=8)
|
|
54
|
+
def load_library(path):
|
|
55
|
+
"""Load a selected library without compiling or selecting a fallback."""
|
|
56
|
+
path = Path(path).expanduser().resolve()
|
|
57
|
+
if path.parent == Path(__file__).resolve().parent / "lib":
|
|
58
|
+
verify_wheel_library(path)
|
|
59
|
+
lib = ct.CDLL(str(path))
|
|
60
|
+
if lib.synkit_canon_abi() != 1:
|
|
61
|
+
raise RuntimeError("Unsupported graph canonicalization ABI")
|
|
62
|
+
lib.synkit_canon_error.restype = ct.c_char_p
|
|
63
|
+
lib.synkit_canon_search.argtypes = [ct.POINTER(Request), ct.POINTER(ct.c_void_p)]
|
|
64
|
+
lib.synkit_canon_search.restype = ct.c_int
|
|
65
|
+
lib.synkit_canon_statistics.argtypes = [ct.c_void_p]
|
|
66
|
+
lib.synkit_canon_statistics.restype = ct.POINTER(Statistics)
|
|
67
|
+
if hasattr(lib, "synkit_canon_pruning_statistics"):
|
|
68
|
+
lib.synkit_canon_pruning_statistics.argtypes = [ct.c_void_p]
|
|
69
|
+
lib.synkit_canon_pruning_statistics.restype = ct.POINTER(PruningStatistics)
|
|
70
|
+
lib.synkit_canon_bytes.argtypes = [ct.c_void_p, ct.POINTER(ct.c_int64)]
|
|
71
|
+
lib.synkit_canon_bytes.restype = ct.POINTER(ct.c_uint8)
|
|
72
|
+
lib.synkit_canon_order.argtypes = [ct.c_void_p, ct.POINTER(ct.c_int64)]
|
|
73
|
+
lib.synkit_canon_order.restype = ct.POINTER(ct.c_int32)
|
|
74
|
+
lib.synkit_canon_free.argtypes = [ct.c_void_p]
|
|
75
|
+
lib.synkit_canon_free.restype = None
|
|
76
|
+
lib.synkit_canon_cancel_create.restype = ct.c_void_p
|
|
77
|
+
for name in ("synkit_canon_cancel_request", "synkit_canon_cancel_free"):
|
|
78
|
+
getattr(lib, name).argtypes = [ct.c_void_p]
|
|
79
|
+
getattr(lib, name).restype = None
|
|
80
|
+
return lib
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class CancellationToken:
|
|
84
|
+
"""Own a one-shot native cancellation flag shared by explicitly chosen calls."""
|
|
85
|
+
|
|
86
|
+
def __init__(self, library_path=None):
|
|
87
|
+
self.library = load_library(str(resolve_library_path(library_path)))
|
|
88
|
+
self._lock = Lock()
|
|
89
|
+
self._active = 0
|
|
90
|
+
self._cancelled = False
|
|
91
|
+
self._handle = self.library.synkit_canon_cancel_create()
|
|
92
|
+
if not self._handle:
|
|
93
|
+
raise MemoryError("Cannot allocate native cancellation token")
|
|
94
|
+
|
|
95
|
+
@contextmanager
|
|
96
|
+
def borrow(self, library):
|
|
97
|
+
"""Keep the token alive until the native call has returned."""
|
|
98
|
+
with self._lock:
|
|
99
|
+
if not self._handle:
|
|
100
|
+
raise RuntimeError("Cancellation token is closed")
|
|
101
|
+
if library is not self.library:
|
|
102
|
+
raise ValueError("Cancellation token belongs to a different library")
|
|
103
|
+
self._active += 1
|
|
104
|
+
handle = self._handle
|
|
105
|
+
try:
|
|
106
|
+
yield handle
|
|
107
|
+
finally:
|
|
108
|
+
with self._lock:
|
|
109
|
+
self._active -= 1
|
|
110
|
+
|
|
111
|
+
def cancel(self):
|
|
112
|
+
"""Request cancellation without waiting for the active search."""
|
|
113
|
+
with self._lock:
|
|
114
|
+
if not self._handle:
|
|
115
|
+
raise RuntimeError("Cancellation token is closed")
|
|
116
|
+
self._cancelled = True
|
|
117
|
+
self.library.synkit_canon_cancel_request(self._handle)
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def cancelled(self):
|
|
121
|
+
return self._cancelled
|
|
122
|
+
|
|
123
|
+
def close(self):
|
|
124
|
+
"""Free an idle token; refuse to invalidate a running call's pointer."""
|
|
125
|
+
with self._lock:
|
|
126
|
+
if self._active:
|
|
127
|
+
raise RuntimeError("Cancellation token is in use")
|
|
128
|
+
if self._handle:
|
|
129
|
+
self.library.synkit_canon_cancel_free(self._handle)
|
|
130
|
+
self._handle = None
|
|
131
|
+
|
|
132
|
+
def __enter__(self):
|
|
133
|
+
return self
|
|
134
|
+
|
|
135
|
+
def __exit__(self, *unused):
|
|
136
|
+
self.close()
|
|
137
|
+
|
|
138
|
+
def __del__(self):
|
|
139
|
+
if getattr(self, "_handle", None) and not getattr(self, "_active", 0):
|
|
140
|
+
self.library.synkit_canon_cancel_free(self._handle)
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"""Bounded sparse graph canonicalization under an explicit native convention."""
|
|
2
|
+
|
|
3
|
+
from contextlib import nullcontext
|
|
4
|
+
import ctypes as ct
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
import hashlib
|
|
7
|
+
import math
|
|
8
|
+
from numbers import Integral, Real
|
|
9
|
+
import struct
|
|
10
|
+
from time import perf_counter
|
|
11
|
+
|
|
12
|
+
from ..exact import CanonicalSearchIncomplete
|
|
13
|
+
from .prepare import prepare_graph
|
|
14
|
+
from .runtime import Request, load_library
|
|
15
|
+
|
|
16
|
+
SCHEMA = "synkit.native-sparse-canonical-graph/1"
|
|
17
|
+
REASONS = {0: None, 1: "time_limit", 2: "node_limit", 3: "workspace_limit",
|
|
18
|
+
4: "output_limit", 5: "cancelled", 6: "depth_limit"}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass(frozen=True)
|
|
22
|
+
class NativeCanonicalResult:
|
|
23
|
+
"""Exact native certificate or a stopped request without any usable key."""
|
|
24
|
+
|
|
25
|
+
complete: bool
|
|
26
|
+
reason: str | None
|
|
27
|
+
canonical_code: bytes | None
|
|
28
|
+
canonical_order: tuple
|
|
29
|
+
statistics: dict
|
|
30
|
+
schema: str = SCHEMA
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def exact(self):
|
|
34
|
+
return self.complete
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def canonical_digest(self):
|
|
38
|
+
return hashlib.sha256(self.canonical_code).hexdigest() if self.complete else None
|
|
39
|
+
|
|
40
|
+
def require_complete(self):
|
|
41
|
+
"""Refuse promotion of bounded-search evidence to an identity key."""
|
|
42
|
+
if not self.complete:
|
|
43
|
+
raise CanonicalSearchIncomplete(f"Native canonical search is incomplete: {self.reason}")
|
|
44
|
+
return self
|
|
45
|
+
|
|
46
|
+
def same_canonical_graph(self, other):
|
|
47
|
+
"""Compare full same-convention bytes; unfinished requests raise."""
|
|
48
|
+
self.require_complete()
|
|
49
|
+
if not isinstance(other, NativeCanonicalResult) or other.schema != self.schema:
|
|
50
|
+
raise TypeError("Cannot compare different canonical conventions")
|
|
51
|
+
other.require_complete()
|
|
52
|
+
return self.canonical_code == other.canonical_code
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _cap(value, name):
|
|
56
|
+
if value is None:
|
|
57
|
+
return -1
|
|
58
|
+
if isinstance(value, bool) or not isinstance(value, Integral) or not 0 < value < 2**63:
|
|
59
|
+
raise ValueError(f"{name} must be a positive int64 or None")
|
|
60
|
+
return int(value)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _timeout(value):
|
|
64
|
+
if value is None:
|
|
65
|
+
return -1.0
|
|
66
|
+
if isinstance(value, bool) or not isinstance(value, Real) or not math.isfinite(value) or value < 0:
|
|
67
|
+
raise ValueError("timeout_seconds must be finite and nonnegative, or None")
|
|
68
|
+
return float(value)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def canonicalize_native_graph(
|
|
72
|
+
graph, *, library_path=None, node_color="color", edge_color=None,
|
|
73
|
+
timeout_seconds=None, max_search_nodes=None, max_workspace_bytes=None,
|
|
74
|
+
max_output_bytes=None, max_depth=1024, cancel_token=None,
|
|
75
|
+
):
|
|
76
|
+
"""Canonicalize a simple colored graph with an explicitly selected library.
|
|
77
|
+
|
|
78
|
+
The new sparse byte convention is NOT interchangeable with the reference
|
|
79
|
+
JSON certificate. The deadline includes Python preparation but its checks
|
|
80
|
+
there are cooperative (before/after stages). Workspace bounds tracked
|
|
81
|
+
native allocations, not Python/NetworkX or process RSS. No group is emitted.
|
|
82
|
+
"""
|
|
83
|
+
started = perf_counter()
|
|
84
|
+
seconds = _timeout(timeout_seconds)
|
|
85
|
+
caps = [_cap(v, n) for v, n in (
|
|
86
|
+
(max_search_nodes, "max_search_nodes"), (max_workspace_bytes, "max_workspace_bytes"),
|
|
87
|
+
(max_output_bytes, "max_output_bytes"),
|
|
88
|
+
)]
|
|
89
|
+
if isinstance(max_depth, bool) or not isinstance(max_depth, Integral) or not 0 <= max_depth <= 1024:
|
|
90
|
+
raise ValueError("max_depth must be an integer between zero and 1024")
|
|
91
|
+
from .runtime import resolve_library_path
|
|
92
|
+
|
|
93
|
+
library = load_library(str(resolve_library_path(library_path)))
|
|
94
|
+
prepared = prepare_graph(graph, node_color=node_color, edge_color=edge_color)
|
|
95
|
+
preparation = perf_counter() - started
|
|
96
|
+
n = len(prepared.nodes)
|
|
97
|
+
offsets = (ct.c_int64 * (n + 1))(*prepared.offsets)
|
|
98
|
+
neighbors = (ct.c_int32 * len(prepared.neighbors))(*prepared.neighbors)
|
|
99
|
+
colors = (ct.c_int32 * n)(*prepared.colors)
|
|
100
|
+
prefix = SCHEMA.encode("ascii") + b"\0" + struct.pack("<Q", len(prepared.palette_bytes)) + prepared.palette_bytes
|
|
101
|
+
output_limit = caps[2] - len(prefix) if caps[2] >= 0 else -1
|
|
102
|
+
if caps[2] >= 0 and output_limit <= 0:
|
|
103
|
+
return NativeCanonicalResult(False, "output_limit", None, (), {"preparation_seconds": preparation})
|
|
104
|
+
remaining = max(0.0, seconds - (perf_counter() - started)) if seconds >= 0 else -1.0
|
|
105
|
+
context = cancel_token.borrow(library) if cancel_token is not None else nullcontext(None)
|
|
106
|
+
with context as token:
|
|
107
|
+
request = Request(1, ct.sizeof(Request), n, len(prepared.neighbors), offsets,
|
|
108
|
+
neighbors, colors, remaining, caps[0], caps[1], output_limit, int(max_depth), token)
|
|
109
|
+
handle = ct.c_void_p()
|
|
110
|
+
if library.synkit_canon_search(ct.byref(request), ct.byref(handle)):
|
|
111
|
+
raise ValueError(library.synkit_canon_error().decode("utf-8"))
|
|
112
|
+
try:
|
|
113
|
+
stat = library.synkit_canon_statistics(handle).contents
|
|
114
|
+
metrics = {name: getattr(stat, name) for name, _ in stat._fields_}
|
|
115
|
+
if hasattr(library, "synkit_canon_pruning_statistics"):
|
|
116
|
+
pruning = library.synkit_canon_pruning_statistics(handle).contents
|
|
117
|
+
metrics.update((name, getattr(pruning, name)) for name, _ in pruning._fields_)
|
|
118
|
+
metrics["preparation_seconds"] = preparation
|
|
119
|
+
metrics["packing_seconds"] = max(0.0, perf_counter() - started - preparation - stat.elapsed_seconds)
|
|
120
|
+
if not stat.complete:
|
|
121
|
+
return NativeCanonicalResult(False, REASONS[stat.reason], None, (), metrics)
|
|
122
|
+
size = ct.c_int64()
|
|
123
|
+
data = library.synkit_canon_bytes(handle, ct.byref(size))
|
|
124
|
+
code = prefix + ct.string_at(data, size.value)
|
|
125
|
+
order = library.synkit_canon_order(handle, ct.byref(size))
|
|
126
|
+
indices = tuple(order[i] for i in range(size.value))
|
|
127
|
+
if len(indices) != n or set(indices) != set(range(n)):
|
|
128
|
+
raise RuntimeError("Native graph core returned an invalid permutation")
|
|
129
|
+
elapsed = perf_counter() - started
|
|
130
|
+
metrics["total_seconds"] = elapsed
|
|
131
|
+
if cancel_token is not None and cancel_token.cancelled:
|
|
132
|
+
return NativeCanonicalResult(False, "cancelled", None, (), metrics)
|
|
133
|
+
if seconds >= 0 and elapsed >= seconds:
|
|
134
|
+
return NativeCanonicalResult(False, "time_limit", None, (), metrics)
|
|
135
|
+
return NativeCanonicalResult(True, None, code, tuple(prepared.nodes[i] for i in indices), metrics)
|
|
136
|
+
finally:
|
|
137
|
+
library.synkit_canon_free(handle)
|