Skip to content

Fix rules engine treating behavior/signal synonyms as separate entries - #423

Open
heberlr wants to merge 1 commit into
MathCancer:developmentfrom
heberlr:fix-rules-with-synonyms
Open

Fix rules engine treating behavior/signal synonyms as separate entries#423
heberlr wants to merge 1 commit into
MathCancer:developmentfrom
heberlr:fix-rules-with-synonyms

Conversation

@heberlr

@heberlr heberlr commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Rules that reference the same behavior or signal via different synonyms
    (e.g. cycle entry vs exit from cycle phase 0) were being stored as two
    separate Hypothesis_Rule entries instead of one merged multivariate Hill
    response, because the rules engine keyed its internal maps by the raw
    string from the CSV/XML rule instead of the canonical, synonym-resolved
    name. Whichever rule applied last at runtime silently overwrote the other's
    contribution to the phenotype parameter.
  • Canonicalize behavior/signal names at the points they're used as map keys
    or compared by name (add_behavior, find_behavior, add_signal,
    find_signal, set_half_max, set_hill_power, set_response).
  • Fix a related latent bug where signals_map[signal] = signals_map.size()
    used map size as a stand-in for vector index; this diverges (and can
    collide with another signal's index) when the same signal is added twice
    with opposite responses in one rule.
  • Remove a dead code path in add_rule that reassigned a rule's canonical
    behavior field back to the caller's raw synonym string, which would have
    undone the canonicalization above.
  • Signals as rule inputs were not affected by the overwrite bug (each is
    evaluated independently and summed into the Hill function, not merged into
    a shared per-name structure), but did share the raw-string lookup, which is
    now fixed consistently for both.

How test it

See the attached example model in the comments below (template project, using
two rules for the same behavior via different synonyms — pressure decreases cycle entry and substrate increases exit from phase 0) demonstrating the
bug before this fix and the corrected merged behavior after it.

Hypothesis_Ruleset::add_behavior/find_behavior and Hypothesis_Rule::add_signal/
find_signal keyed their maps by the raw string from the rules file instead of
the canonical, synonym-resolved name, even though find_behavior_index()/
find_signal_index() were already computing the canonical index just to
validate it. Two rules for the same behavior spelled with different synonyms
(e.g. "cycle entry" vs "exit from cycle phase 0") produced two separate
Hypothesis_Rule objects instead of one merged multivariate Hill response, so
whichever rule was applied last silently overwrote the other's contribution.

Canonicalize behavior/signal names before they're used as map keys or
compared by name, in add_behavior, find_behavior, add_signal, find_signal,
set_half_max, set_hill_power, and set_response. Also fix
signals_map[signal] = signals_map.size(), which used map size as a proxy for
vector index and could collide when the same signal was added twice with
opposite responses in one rule; and drop a dead code path in add_rule that
would have fought the new canonicalization.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@heberlr

heberlr commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

Attached is the template model to demonstrate the bug.

cell_rules.csv
cells.csv
PhysiCell_settings.xml

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.

1 participant