Skip to content

fix(engine): exact-species pattern methods are component-order-insensitive (issue #13)#14

Merged
wshlavacek merged 1 commit into
mainfrom
fix/issue-13-component-order-insensitive
May 23, 2026
Merged

fix(engine): exact-species pattern methods are component-order-insensitive (issue #13)#14
wshlavacek merged 1 commit into
mainfrom
fix/issue-13-component-order-insensitive

Conversation

@wshlavacek
Copy link
Copy Markdown
Collaborator

@wshlavacek wshlavacek commented May 23, 2026

Summary

Fixes #13. The exact-species session methods from #9get_species_count / remove_species / set_species_count — matched a live species only when the caller wrote its components in RuleMonkey's own canonical order. A semantically identical pattern with components swapped (e.g. X(p~0,y) for the canonical X(y,p~0)) silently matched nothing and returned 0.

add_species, by contrast, placed components by molecule-type declaration index (comp_type_index) via instantiate_pattern_complex, so it already canonicalized. That asymmetry made set_species_count with a non-canonical pattern diff against a wrong baseline of 0 and overshoot its target — silently.

Root cause

pattern_to_complex_graph (the parse-side bridge to the canonical labeler) fed each molecule's components to canonical::ComplexGraph in the pattern's listed order, whereas extract_complex (the live-pool side) feeds them in molecule-type declaration order. canonical_label preserves the input's component-name slot layout (canonical.cpp §3.3 "component-order contract") and only reorders same-name components — so the two sides produced different labels for the same physical species, and the byte-equal species_count lookup missed.

Fix

pattern_to_complex_graph now places each component at the slot given by its comp_type_index (declaration order) and remaps bond endpoints to the reordered slots — matching extract_complex and NFsim's order-insensitive exact-species matcher. The fix is localized to that one function; the parser already resolves comp_type_index and verifies the pattern is fully specified, so the slot mapping is a bijection.

Test

New tests/cpp/species_order_model.xml — molecule X with a stateful p~0~1 and a stateless y, seeded with 5000 X(p~0,y) and a state-change rule X(p~0) -> X(p~1). species_methods_test gains test_component_order_insensitive, driving get/add/set/remove through both component orders. Without the engine fix it reports four mismatches and an over-removal exception; with it, all assertions pass.

Full ctest suite (23 tests) green under the ASan preset, which cross-checks every canonical label against a from-scratch recompute.

Bumps version to 3.2.1 and adds a CHANGELOG Fixed entry.

…h path — issue #13

The #9 session methods get_species_count / remove_species /
set_species_count matched a live species only when the caller wrote its
components in RuleMonkey's own canonical order: a swapped-order pattern
(e.g. X(p~0,y) for the canonical X(y,p~0)) silently matched nothing and
returned 0. add_species, by contrast, placed components by molecule-type
declaration index (comp_type_index) and so already canonicalized —
leaving set_species_count with a non-canonical pattern diffing against a
wrong baseline of 0 and overshooting its target.

pattern_to_complex_graph fed components to the canonical labeler in the
pattern's *listed* order, while extract_complex (the live-pool side)
feeds them in molecule-type declaration order, and canonical_label
preserves the input's component-name slot layout — so the two produced
different labels for the same physical species. Place pattern components
by comp_type_index and remap bond endpoints to the new slots, matching
extract_complex and NFsim's order-insensitive exact-species matcher.

Regression test: tests/cpp/species_order_model.xml (X with stateful p~0~1
plus stateless y) drives get/add/set/remove through both component
orders; without the fix it reports four mismatches and an over-removal.
@wshlavacek wshlavacek merged commit 286e868 into main May 23, 2026
6 checks passed
@wshlavacek wshlavacek deleted the fix/issue-13-component-order-insensitive branch May 23, 2026 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Exact-species pattern methods are component-order-sensitive (get/match doesn't canonicalize like add/set)

1 participant