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