Skip to content

fix(tla): action constraints go through the full evaluator (LanguageFeatureMatrix) - #184

Merged
zoratu merged 1 commit into
mainfrom
fix/action-constraint-full-eval
Jul 13, 2026
Merged

fix(tla): action constraints go through the full evaluator (LanguageFeatureMatrix)#184
zoratu merged 1 commit into
mainfrom
fix/action-constraint-full-eval

Conversation

@zoratu

@zoratu zoratu commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Problem

eval_action_constraint dispatched to a bespoke eval_transition_expr that — by its own source comment — "only support[ed] simple comparisons" (x' <op> y) and returned an error for any other shape. An ACTION_CONSTRAINT like LanguageFeatureMatrix's step' \in step..(step+1) (membership over a range, mixing unprimed step from the pre-state with primed step' from the post-state) hit the error path, which pruned every successor: ours explored 1 state where TLC v2.19 finds 21.

Fix

Route action-constraint evaluation through the same interpreter that generates successors:

  • build an EvalContext from the pre-state (current),
  • stage the post-state (next) variables into its locals as primes (var'),
  • call eval_expr.

This is exactly the staged-primes pattern the action-body evaluator already uses for guards, so \in, set/record expressions, and definition calls in constraints are now all handled uniformly instead of via an ad-hoc comparison parser. The obsolete eval_transition_expr / parse_simple_comparison / apply_comparison helpers are deleted; is_identifier (imported elsewhere) is retained.

Validation (on spot)

  • LanguageFeatureMatrix: 1 → 21 distinct states, matching TLC v2.19; violation=false.
  • New regression test action_constraint_membership_over_range (step' \in step..(step+1) satisfied in-range, pruned out-of-range).
  • scripts/diff_tlc.sh: 14/14 pass.
  • cargo test --release: 0 failures.

…eatureMatrix)

`eval_action_constraint` dispatched to a bespoke `eval_transition_expr`
that, by its own admission, "only support[ed] simple comparisons" — it
returned an error for anything that wasn't `x' <op> y`. An action
constraint like `step' \in step..(step+1)` (membership over a range,
mixing unprimed `step` from the pre-state and primed `step'` from the
post-state) fell into the error path, which pruned every successor:
LanguageFeatureMatrix explored 1 state where TLC finds 21.

Route action-constraint evaluation through the same interpreter that
generates successors: build an `EvalContext` from the pre-state and stage
the post-state's variables as primes (`var'`) into its locals, then call
`eval_expr`. This is exactly the staged-primes pattern the action-body
evaluator already uses for guards, so `\in`, set/record expressions, and
definition calls in constraints are all handled uniformly. The obsolete
`eval_transition_expr` / `parse_simple_comparison` / `apply_comparison`
helpers are deleted; `is_identifier` (used elsewhere) is retained.

LanguageFeatureMatrix now explores 21 distinct states, matching TLC v2.19.
@zoratu
zoratu merged commit 4965744 into main Jul 13, 2026
6 checks passed
@zoratu
zoratu deleted the fix/action-constraint-full-eval branch July 13, 2026 06:36
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