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,93 @@
|
|
|
1
|
+
"""Petri-net view of a reaction network: incidence, invariants, persistence.
|
|
2
|
+
|
|
3
|
+
A CRN maps onto a Petri net by reading species as places and reactions as
|
|
4
|
+
transitions. This subpackage exposes that view together with the standard
|
|
5
|
+
structural diagnostics computed on it.
|
|
6
|
+
|
|
7
|
+
Semiflows here are genuine semiflows: minimal, non-negative and integer-valued
|
|
8
|
+
(:mod:`synkit.CRN.Petrinet.minimal_semiflows`). If you want a plain kernel
|
|
9
|
+
basis instead, ask for :func:`left_kernel_basis` or :func:`right_kernel_basis`
|
|
10
|
+
explicitly.
|
|
11
|
+
|
|
12
|
+
.. rubric:: Example
|
|
13
|
+
|
|
14
|
+
.. code-block:: python
|
|
15
|
+
|
|
16
|
+
from synkit.CRN.Structure import SynCRN
|
|
17
|
+
from synkit.CRN.Petrinet import PetriAnalyzer
|
|
18
|
+
|
|
19
|
+
crn = SynCRN.from_reaction_strings(["A>>B", "B>>A"])
|
|
20
|
+
print(PetriAnalyzer(crn, max_siphon_size=4).compute_all().explain())
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
from .net import (
|
|
26
|
+
Marking,
|
|
27
|
+
Multiset,
|
|
28
|
+
PetriNet,
|
|
29
|
+
Place,
|
|
30
|
+
SynCRNIncidence,
|
|
31
|
+
Transition,
|
|
32
|
+
TransitionId,
|
|
33
|
+
extract_syncrn_incidence,
|
|
34
|
+
)
|
|
35
|
+
from .minimal_semiflows import (
|
|
36
|
+
SemiflowSearchLimit,
|
|
37
|
+
is_semiflow,
|
|
38
|
+
minimal_semiflow_supports,
|
|
39
|
+
minimal_semiflows,
|
|
40
|
+
)
|
|
41
|
+
from .semiflows import (
|
|
42
|
+
find_p_semiflows,
|
|
43
|
+
find_t_semiflows,
|
|
44
|
+
left_kernel_basis,
|
|
45
|
+
right_kernel_basis,
|
|
46
|
+
semiflow_supports,
|
|
47
|
+
stoichiometric_matrix,
|
|
48
|
+
)
|
|
49
|
+
from .structure import (
|
|
50
|
+
find_siphons,
|
|
51
|
+
find_traps,
|
|
52
|
+
species_transition_neighborhoods,
|
|
53
|
+
)
|
|
54
|
+
from .persistence import (
|
|
55
|
+
PersistenceCheckResult,
|
|
56
|
+
siphon_persistence_condition,
|
|
57
|
+
siphon_persistence_details,
|
|
58
|
+
)
|
|
59
|
+
from .analyzer import PetriAnalyzer, PetriSummary
|
|
60
|
+
|
|
61
|
+
__all__ = [
|
|
62
|
+
# net
|
|
63
|
+
"Marking",
|
|
64
|
+
"Multiset",
|
|
65
|
+
"PetriNet",
|
|
66
|
+
"Place",
|
|
67
|
+
"SynCRNIncidence",
|
|
68
|
+
"Transition",
|
|
69
|
+
"TransitionId",
|
|
70
|
+
"extract_syncrn_incidence",
|
|
71
|
+
# invariants
|
|
72
|
+
"find_p_semiflows",
|
|
73
|
+
"find_t_semiflows",
|
|
74
|
+
"semiflow_supports",
|
|
75
|
+
"minimal_semiflows",
|
|
76
|
+
"SemiflowSearchLimit",
|
|
77
|
+
"minimal_semiflow_supports",
|
|
78
|
+
"is_semiflow",
|
|
79
|
+
"left_kernel_basis",
|
|
80
|
+
"right_kernel_basis",
|
|
81
|
+
"stoichiometric_matrix",
|
|
82
|
+
# structure
|
|
83
|
+
"find_siphons",
|
|
84
|
+
"find_traps",
|
|
85
|
+
"species_transition_neighborhoods",
|
|
86
|
+
# persistence
|
|
87
|
+
"PersistenceCheckResult",
|
|
88
|
+
"siphon_persistence_condition",
|
|
89
|
+
"siphon_persistence_details",
|
|
90
|
+
# analysis
|
|
91
|
+
"PetriAnalyzer",
|
|
92
|
+
"PetriSummary",
|
|
93
|
+
]
|
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any, Dict, List, Optional, Set, Tuple
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
from .net import PetriNet
|
|
9
|
+
from .persistence import (
|
|
10
|
+
PersistenceCheckResult,
|
|
11
|
+
siphon_persistence_condition as _siphon_persistence_condition,
|
|
12
|
+
siphon_persistence_details,
|
|
13
|
+
)
|
|
14
|
+
from .semiflows import find_p_semiflows, find_t_semiflows, stoichiometric_matrix
|
|
15
|
+
from .structure import find_siphons, find_traps
|
|
16
|
+
|
|
17
|
+
# Preserve the historical module-level re-export.
|
|
18
|
+
siphon_persistence_condition = _siphon_persistence_condition
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class PetriSummary:
|
|
23
|
+
"""
|
|
24
|
+
Structured container summarizing Petri-style SynCRN diagnostics.
|
|
25
|
+
|
|
26
|
+
:param p_semiflows:
|
|
27
|
+
Numerical basis of P-semiflows, arranged as columns.
|
|
28
|
+
:type p_semiflows: numpy.ndarray
|
|
29
|
+
|
|
30
|
+
:param t_semiflows:
|
|
31
|
+
Numerical basis of T-semiflows, arranged as columns.
|
|
32
|
+
:type t_semiflows: numpy.ndarray
|
|
33
|
+
|
|
34
|
+
:param siphons:
|
|
35
|
+
Detected siphons as sets of place labels.
|
|
36
|
+
:type siphons: List[Set[str]]
|
|
37
|
+
|
|
38
|
+
:param traps:
|
|
39
|
+
Detected traps as sets of place labels.
|
|
40
|
+
:type traps: List[Set[str]]
|
|
41
|
+
|
|
42
|
+
:param persistence_ok:
|
|
43
|
+
Whether the tested siphon-based persistence condition is satisfied.
|
|
44
|
+
:type persistence_ok: bool
|
|
45
|
+
|
|
46
|
+
:param place_order:
|
|
47
|
+
Place ordering associated with the Petri/stoichiometric representation.
|
|
48
|
+
:type place_order: List[str]
|
|
49
|
+
|
|
50
|
+
:param transition_order:
|
|
51
|
+
Transition ordering associated with the Petri/stoichiometric representation.
|
|
52
|
+
:type transition_order: List[str]
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
p_semiflows: np.ndarray
|
|
56
|
+
t_semiflows: np.ndarray
|
|
57
|
+
siphons: List[Set[str]]
|
|
58
|
+
traps: List[Set[str]]
|
|
59
|
+
persistence_ok: bool
|
|
60
|
+
place_order: List[str]
|
|
61
|
+
transition_order: List[str]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class PetriAnalyzer:
|
|
65
|
+
"""OOP wrapper for Petri-net style analysis on SynCRN-like inputs.
|
|
66
|
+
|
|
67
|
+
Accepted inputs are canonical SynCRN objects, SynCRN bipartite digraphs,
|
|
68
|
+
and :class:`PetriNet` objects.
|
|
69
|
+
|
|
70
|
+
The analyzer caches computed results so repeated access to already computed
|
|
71
|
+
diagnostics does not trigger recomputation.
|
|
72
|
+
|
|
73
|
+
:param crn:
|
|
74
|
+
SynCRN-like object or :class:`PetriNet`.
|
|
75
|
+
:type crn: Any
|
|
76
|
+
|
|
77
|
+
:param rtol:
|
|
78
|
+
Relative tolerance used in numerical nullspace calculations.
|
|
79
|
+
:type rtol: float
|
|
80
|
+
|
|
81
|
+
:param max_siphon_size:
|
|
82
|
+
Optional maximum siphon/trap size considered during enumeration.
|
|
83
|
+
:type max_siphon_size: Optional[int]
|
|
84
|
+
|
|
85
|
+
.. rubric:: Examples
|
|
86
|
+
|
|
87
|
+
.. code-block:: python
|
|
88
|
+
|
|
89
|
+
analyzer = PetriAnalyzer(crn, rtol=1e-12, max_siphon_size=4)
|
|
90
|
+
analyzer.compute_all()
|
|
91
|
+
|
|
92
|
+
print(analyzer.summary)
|
|
93
|
+
print(analyzer.as_dict())
|
|
94
|
+
print(analyzer.explain())
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
def __init__(
|
|
98
|
+
self,
|
|
99
|
+
crn: Any,
|
|
100
|
+
*,
|
|
101
|
+
rtol: float = 1e-12,
|
|
102
|
+
max_siphon_size: Optional[int] = None,
|
|
103
|
+
backend: str = "auto",
|
|
104
|
+
library_path=None,
|
|
105
|
+
) -> None:
|
|
106
|
+
"""
|
|
107
|
+
Initialize the Petri analyzer.
|
|
108
|
+
|
|
109
|
+
:param crn:
|
|
110
|
+
SynCRN-like object or :class:`PetriNet`.
|
|
111
|
+
:type crn: Any
|
|
112
|
+
|
|
113
|
+
:param rtol:
|
|
114
|
+
Relative tolerance used in numerical nullspace calculations.
|
|
115
|
+
:type rtol: float
|
|
116
|
+
|
|
117
|
+
:param max_siphon_size:
|
|
118
|
+
Optional maximum siphon/trap size considered during enumeration.
|
|
119
|
+
:type max_siphon_size: Optional[int]
|
|
120
|
+
"""
|
|
121
|
+
self._crn = crn
|
|
122
|
+
self._petri = crn if isinstance(crn, PetriNet) else PetriNet.from_syncrn(crn)
|
|
123
|
+
self._rtol = float(rtol)
|
|
124
|
+
self._max_siphon_size = max_siphon_size
|
|
125
|
+
from ..backend import resolve_backend
|
|
126
|
+
|
|
127
|
+
backend, library_path = resolve_backend(backend, library_path)
|
|
128
|
+
self._backend_options = {"backend": backend, "library_path": library_path}
|
|
129
|
+
self._siphon_ids = None
|
|
130
|
+
|
|
131
|
+
self._p_semiflows: Optional[np.ndarray] = None
|
|
132
|
+
self._t_semiflows: Optional[np.ndarray] = None
|
|
133
|
+
self._siphons: Optional[List[Set[str]]] = None
|
|
134
|
+
self._traps: Optional[List[Set[str]]] = None
|
|
135
|
+
self._persistence_ok: Optional[bool] = None
|
|
136
|
+
self._persistence_details: Optional[PersistenceCheckResult] = None
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
def petri(self) -> PetriNet:
|
|
140
|
+
"""Return the internal Petri-net representation.
|
|
141
|
+
|
|
142
|
+
:return:
|
|
143
|
+
Internal Petri-net view used for structural analysis.
|
|
144
|
+
:rtype: PetriNet
|
|
145
|
+
"""
|
|
146
|
+
return self._petri
|
|
147
|
+
|
|
148
|
+
def _orders(self) -> Tuple[List[str], List[str]]:
|
|
149
|
+
"""Return place and transition orders from the stoichiometric view.
|
|
150
|
+
|
|
151
|
+
:return:
|
|
152
|
+
Tuple ``(place_order, transition_order)``.
|
|
153
|
+
:rtype: Tuple[List[str], List[str]]
|
|
154
|
+
"""
|
|
155
|
+
places, transitions, _ = stoichiometric_matrix(self._crn)
|
|
156
|
+
return places, transitions
|
|
157
|
+
|
|
158
|
+
def _ensure_persistence_computed(self) -> bool:
|
|
159
|
+
"""Check whether persistence has already been computed.
|
|
160
|
+
|
|
161
|
+
:return:
|
|
162
|
+
``True`` if persistence results are available.
|
|
163
|
+
:rtype: bool
|
|
164
|
+
"""
|
|
165
|
+
return self._persistence_ok is not None
|
|
166
|
+
|
|
167
|
+
def _persistence_details_as_dict(self) -> Optional[Dict[str, Any]]:
|
|
168
|
+
"""Convert cached persistence details into a serializable dictionary.
|
|
169
|
+
|
|
170
|
+
:return:
|
|
171
|
+
Dictionary form of persistence details, or ``None`` if unavailable.
|
|
172
|
+
:rtype: Optional[Dict[str, Any]]
|
|
173
|
+
"""
|
|
174
|
+
if self._persistence_details is None:
|
|
175
|
+
return None
|
|
176
|
+
return {
|
|
177
|
+
"persistence_ok": self._persistence_details.persistence_ok,
|
|
178
|
+
"siphons": [sorted(x) for x in self._persistence_details.siphons],
|
|
179
|
+
"semiflow_supports": [
|
|
180
|
+
sorted(x) for x in self._persistence_details.semiflow_supports
|
|
181
|
+
],
|
|
182
|
+
"uncovered_siphons": [
|
|
183
|
+
sorted(x) for x in self._persistence_details.uncovered_siphons
|
|
184
|
+
],
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
def _summary_ready(self) -> bool:
|
|
188
|
+
"""Check whether all ingredients required for :attr:`summary` are present.
|
|
189
|
+
|
|
190
|
+
:return:
|
|
191
|
+
``True`` if a full summary can be constructed.
|
|
192
|
+
:rtype: bool
|
|
193
|
+
"""
|
|
194
|
+
return (
|
|
195
|
+
self._p_semiflows is not None
|
|
196
|
+
and self._t_semiflows is not None
|
|
197
|
+
and self._siphons is not None
|
|
198
|
+
and self._traps is not None
|
|
199
|
+
and self._persistence_ok is not None
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
def compute_semiflows(self) -> "PetriAnalyzer":
|
|
203
|
+
"""Compute and cache P-semiflows and T-semiflows.
|
|
204
|
+
|
|
205
|
+
:return:
|
|
206
|
+
The analyzer itself, enabling method chaining.
|
|
207
|
+
:rtype: PetriAnalyzer
|
|
208
|
+
|
|
209
|
+
.. rubric:: Examples
|
|
210
|
+
|
|
211
|
+
.. code-block:: python
|
|
212
|
+
|
|
213
|
+
analyzer = PetriAnalyzer(crn).compute_semiflows()
|
|
214
|
+
print(analyzer.p_semiflows)
|
|
215
|
+
print(analyzer.t_semiflows)
|
|
216
|
+
"""
|
|
217
|
+
self._p_semiflows = find_p_semiflows(
|
|
218
|
+
self._crn, rtol=self._rtol, **self._backend_options
|
|
219
|
+
)
|
|
220
|
+
self._t_semiflows = find_t_semiflows(
|
|
221
|
+
self._crn, rtol=self._rtol, **self._backend_options
|
|
222
|
+
)
|
|
223
|
+
return self
|
|
224
|
+
|
|
225
|
+
def compute_siphons_traps(self) -> "PetriAnalyzer":
|
|
226
|
+
"""Compute and cache siphons and traps.
|
|
227
|
+
|
|
228
|
+
:return:
|
|
229
|
+
The analyzer itself, enabling method chaining.
|
|
230
|
+
:rtype: PetriAnalyzer
|
|
231
|
+
|
|
232
|
+
.. rubric:: Examples
|
|
233
|
+
|
|
234
|
+
.. code-block:: python
|
|
235
|
+
|
|
236
|
+
analyzer = PetriAnalyzer(crn).compute_siphons_traps()
|
|
237
|
+
print(analyzer.siphons)
|
|
238
|
+
print(analyzer.traps)
|
|
239
|
+
"""
|
|
240
|
+
backend = self._backend_options["backend"]
|
|
241
|
+
use_cpp = backend == "cpp" or (
|
|
242
|
+
backend == "auto" and self._backend_options["library_path"] is not None
|
|
243
|
+
)
|
|
244
|
+
if use_cpp:
|
|
245
|
+
from ..native import enumerate_structural_sets
|
|
246
|
+
from .siphon_search import SiphonSearchLimit
|
|
247
|
+
|
|
248
|
+
groups = []
|
|
249
|
+
for kind in ("siphon", "trap"):
|
|
250
|
+
result = enumerate_structural_sets(
|
|
251
|
+
self._petri, kind=kind, **self._backend_options
|
|
252
|
+
)
|
|
253
|
+
if not result.complete:
|
|
254
|
+
error = SiphonSearchLimit(result.termination_reason)
|
|
255
|
+
error.result = result
|
|
256
|
+
raise error
|
|
257
|
+
groups.append([set(s) for s in result.value["sets"]])
|
|
258
|
+
self._siphon_ids, trap_ids = groups
|
|
259
|
+
else:
|
|
260
|
+
self._siphon_ids = find_siphons(self._petri, names="id", strict_limit=True)
|
|
261
|
+
trap_ids = find_traps(self._petri, names="id", strict_limit=True)
|
|
262
|
+
|
|
263
|
+
def rendered(groups):
|
|
264
|
+
return [
|
|
265
|
+
{self._petri.place_name(p) for p in group}
|
|
266
|
+
for group in groups
|
|
267
|
+
if self._max_siphon_size is None or len(group) <= self._max_siphon_size
|
|
268
|
+
]
|
|
269
|
+
|
|
270
|
+
self._siphons = rendered(self._siphon_ids)
|
|
271
|
+
self._traps = rendered(trap_ids)
|
|
272
|
+
return self
|
|
273
|
+
|
|
274
|
+
def check_persistence(self) -> "PetriAnalyzer":
|
|
275
|
+
"""Evaluate and cache the siphon-based persistence condition.
|
|
276
|
+
|
|
277
|
+
Both the boolean persistence condition and the detailed explanation
|
|
278
|
+
structure are computed and stored.
|
|
279
|
+
|
|
280
|
+
:return:
|
|
281
|
+
The analyzer itself, enabling method chaining.
|
|
282
|
+
:rtype: PetriAnalyzer
|
|
283
|
+
|
|
284
|
+
.. rubric:: Examples
|
|
285
|
+
|
|
286
|
+
.. code-block:: python
|
|
287
|
+
|
|
288
|
+
analyzer = PetriAnalyzer(crn).check_persistence()
|
|
289
|
+
print(analyzer.persistence_ok)
|
|
290
|
+
print(analyzer.persistence_details)
|
|
291
|
+
"""
|
|
292
|
+
if self._siphon_ids is None:
|
|
293
|
+
self.compute_siphons_traps()
|
|
294
|
+
if self._p_semiflows is None:
|
|
295
|
+
self._p_semiflows = find_p_semiflows(
|
|
296
|
+
self._crn, rtol=self._rtol, **self._backend_options
|
|
297
|
+
)
|
|
298
|
+
self._persistence_details = siphon_persistence_details(
|
|
299
|
+
self._crn,
|
|
300
|
+
rtol=self._rtol,
|
|
301
|
+
max_siphon_size=self._max_siphon_size,
|
|
302
|
+
p_semiflows=self._p_semiflows,
|
|
303
|
+
_complete_siphons=self._siphon_ids,
|
|
304
|
+
)
|
|
305
|
+
self._persistence_ok = self._persistence_details.persistence_ok
|
|
306
|
+
return self
|
|
307
|
+
|
|
308
|
+
def compute_all(self) -> "PetriAnalyzer":
|
|
309
|
+
"""Compute all supported Petri-style diagnostics.
|
|
310
|
+
|
|
311
|
+
This is equivalent to calling :meth:`compute_semiflows`,
|
|
312
|
+
:meth:`compute_siphons_traps`, and :meth:`check_persistence` in sequence.
|
|
313
|
+
|
|
314
|
+
:return:
|
|
315
|
+
The analyzer itself, enabling method chaining.
|
|
316
|
+
:rtype: PetriAnalyzer
|
|
317
|
+
|
|
318
|
+
.. rubric:: Examples
|
|
319
|
+
|
|
320
|
+
.. code-block:: python
|
|
321
|
+
|
|
322
|
+
analyzer = PetriAnalyzer(crn).compute_all()
|
|
323
|
+
print(analyzer.summary)
|
|
324
|
+
"""
|
|
325
|
+
return self.compute_semiflows().compute_siphons_traps().check_persistence()
|
|
326
|
+
|
|
327
|
+
@property
|
|
328
|
+
def p_semiflows(self) -> Optional[np.ndarray]:
|
|
329
|
+
"""Return cached P-semiflows.
|
|
330
|
+
|
|
331
|
+
:return:
|
|
332
|
+
Cached P-semiflow basis, or ``None`` if not yet computed.
|
|
333
|
+
:rtype: Optional[numpy.ndarray]
|
|
334
|
+
"""
|
|
335
|
+
return self._p_semiflows
|
|
336
|
+
|
|
337
|
+
@property
|
|
338
|
+
def t_semiflows(self) -> Optional[np.ndarray]:
|
|
339
|
+
"""Return cached T-semiflows.
|
|
340
|
+
|
|
341
|
+
:return:
|
|
342
|
+
Cached T-semiflow basis, or ``None`` if not yet computed.
|
|
343
|
+
:rtype: Optional[numpy.ndarray]
|
|
344
|
+
"""
|
|
345
|
+
return self._t_semiflows
|
|
346
|
+
|
|
347
|
+
@property
|
|
348
|
+
def siphons(self) -> Optional[List[Set[str]]]:
|
|
349
|
+
"""Return cached siphons.
|
|
350
|
+
|
|
351
|
+
:return:
|
|
352
|
+
Cached siphons, or ``None`` if not yet computed.
|
|
353
|
+
:rtype: Optional[List[Set[str]]]
|
|
354
|
+
"""
|
|
355
|
+
return self._siphons
|
|
356
|
+
|
|
357
|
+
@property
|
|
358
|
+
def traps(self) -> Optional[List[Set[str]]]:
|
|
359
|
+
"""Return cached traps.
|
|
360
|
+
|
|
361
|
+
:return:
|
|
362
|
+
Cached traps, or ``None`` if not yet computed.
|
|
363
|
+
:rtype: Optional[List[Set[str]]]
|
|
364
|
+
"""
|
|
365
|
+
return self._traps
|
|
366
|
+
|
|
367
|
+
@property
|
|
368
|
+
def persistence_ok(self) -> Optional[bool]:
|
|
369
|
+
"""Return cached persistence status.
|
|
370
|
+
|
|
371
|
+
:return:
|
|
372
|
+
Cached persistence status, or ``None`` if not yet computed.
|
|
373
|
+
:rtype: Optional[bool]
|
|
374
|
+
"""
|
|
375
|
+
return self._persistence_ok
|
|
376
|
+
|
|
377
|
+
@property
|
|
378
|
+
def persistence_details(self) -> Optional[PersistenceCheckResult]:
|
|
379
|
+
"""Return cached detailed persistence analysis.
|
|
380
|
+
|
|
381
|
+
:return:
|
|
382
|
+
Cached persistence detail object, or ``None`` if not yet computed.
|
|
383
|
+
:rtype: Optional[PersistenceCheckResult]
|
|
384
|
+
"""
|
|
385
|
+
return self._persistence_details
|
|
386
|
+
|
|
387
|
+
@property
|
|
388
|
+
def summary(self) -> Optional[PetriSummary]:
|
|
389
|
+
"""Return a structured summary if all diagnostics are available.
|
|
390
|
+
|
|
391
|
+
:return:
|
|
392
|
+
A :class:`PetriSummary` if all components are computed, otherwise
|
|
393
|
+
``None``.
|
|
394
|
+
:rtype: Optional[PetriSummary]
|
|
395
|
+
"""
|
|
396
|
+
if not self._summary_ready():
|
|
397
|
+
return None
|
|
398
|
+
|
|
399
|
+
places, transitions = self._orders()
|
|
400
|
+
return PetriSummary(
|
|
401
|
+
p_semiflows=self._p_semiflows,
|
|
402
|
+
t_semiflows=self._t_semiflows,
|
|
403
|
+
siphons=self._siphons,
|
|
404
|
+
traps=self._traps,
|
|
405
|
+
persistence_ok=bool(self._persistence_ok),
|
|
406
|
+
place_order=places,
|
|
407
|
+
transition_order=transitions,
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
def as_dict(self) -> Dict[str, Any]:
|
|
411
|
+
"""Convert the current analyzer state into a serializable dictionary.
|
|
412
|
+
|
|
413
|
+
:return:
|
|
414
|
+
Dictionary containing cached analysis results and metadata.
|
|
415
|
+
:rtype: Dict[str, Any]
|
|
416
|
+
|
|
417
|
+
.. rubric:: Examples
|
|
418
|
+
|
|
419
|
+
.. code-block:: python
|
|
420
|
+
|
|
421
|
+
analyzer = PetriAnalyzer(crn).compute_all()
|
|
422
|
+
payload = analyzer.as_dict()
|
|
423
|
+
print(payload["persistence_ok"])
|
|
424
|
+
"""
|
|
425
|
+
places, transitions = self._orders()
|
|
426
|
+
return {
|
|
427
|
+
"place_order": places,
|
|
428
|
+
"transition_order": transitions,
|
|
429
|
+
"p_semiflows": (
|
|
430
|
+
None if self._p_semiflows is None else self._p_semiflows.tolist()
|
|
431
|
+
),
|
|
432
|
+
"t_semiflows": (
|
|
433
|
+
None if self._t_semiflows is None else self._t_semiflows.tolist()
|
|
434
|
+
),
|
|
435
|
+
"siphons": (
|
|
436
|
+
None if self._siphons is None else [sorted(x) for x in self._siphons]
|
|
437
|
+
),
|
|
438
|
+
"traps": None if self._traps is None else [sorted(x) for x in self._traps],
|
|
439
|
+
"persistence_ok": self._persistence_ok,
|
|
440
|
+
"persistence_details": self._persistence_details_as_dict(),
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
def explain(self) -> str:
|
|
444
|
+
"""Return a compact human-readable explanation of current results.
|
|
445
|
+
|
|
446
|
+
:return:
|
|
447
|
+
Summary string describing persistence and the number of computed
|
|
448
|
+
objects, or a message indicating that no computation has been run.
|
|
449
|
+
:rtype: str
|
|
450
|
+
|
|
451
|
+
.. rubric:: Examples
|
|
452
|
+
|
|
453
|
+
.. code-block:: python
|
|
454
|
+
|
|
455
|
+
analyzer = PetriAnalyzer(crn).compute_all()
|
|
456
|
+
print(analyzer.explain())
|
|
457
|
+
"""
|
|
458
|
+
if not self._ensure_persistence_computed():
|
|
459
|
+
return (
|
|
460
|
+
"No Petri computations performed yet. "
|
|
461
|
+
"Call compute_all() or individual compute_* methods."
|
|
462
|
+
)
|
|
463
|
+
|
|
464
|
+
n_siph = 0 if self._siphons is None else len(self._siphons)
|
|
465
|
+
n_trap = 0 if self._traps is None else len(self._traps)
|
|
466
|
+
kp = 0 if self._p_semiflows is None else self._p_semiflows.shape[1]
|
|
467
|
+
kt = 0 if self._t_semiflows is None else self._t_semiflows.shape[1]
|
|
468
|
+
return (
|
|
469
|
+
f"persistence_ok={self._persistence_ok}, "
|
|
470
|
+
f"p_semiflows={kp}, t_semiflows={kt}, "
|
|
471
|
+
f"siphons={n_siph}, traps={n_trap}"
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
def __repr__(self) -> str:
|
|
475
|
+
"""Return a concise developer-facing representation.
|
|
476
|
+
|
|
477
|
+
:return:
|
|
478
|
+
String representation of the analyzer status.
|
|
479
|
+
:rtype: str
|
|
480
|
+
"""
|
|
481
|
+
status = (
|
|
482
|
+
"NA"
|
|
483
|
+
if self._persistence_ok is None
|
|
484
|
+
else ("True" if self._persistence_ok else "False")
|
|
485
|
+
)
|
|
486
|
+
return f"<PetriAnalyzer persistence_ok={status}>"
|