Repository navigation
State Machine view: show a multi-set state error in the set that is wrong - #182
Conversation
In the State Machine view, when the call is rejected because of the state of another state set: - the call is red only in the diagram of the state set in a wrong state; in the others it is drawn as usual and its unmet condition is red, also with conditions collapsed - the diagram of the state set in a wrong state comes first, so focus mode fits it - a transition that keeps its state is drawn as a round loop instead of a curl as small as its arrowhead - a condition on other state sets is written as their states after the method, e.g. open [lockState: unlocked], with != on a two-state set as its other state - the summary line names the state sets (expected doorState closed, lockState unlocked · actual lockState locked) and leaves out those in which every state allows the call; unnamed state sets keep the current wording Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t in a wrong state Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…loops as far out as the curl Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dition Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es of the summary Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex review, round 1
Fixed in a00337d: the call keeps its red mark unless its condition is parsed as states and names the state set in a wrong state; a raw or unrelated condition is no longer coloured. Regression assertion added to the Door test. |
Codex review, round 2
Fixed in b532387: (1) a clause is marked only if some possible state of the rejecting set does not meet it (Door test now covers |
Codex review, round 3
Fixed in 5a5ec09: the decision is per transition — a transition of the call keeps its red mark unless it has its own unmet condition. |
Codex review, round 4
Fixed in 1d4d893: a state set that allows the call in every state is now left out of both the expected and the actual side (named and unnamed), so the two sides stay aligned. |
Codex review, round 5
Nothing to fix; loop ends here. |
Clean-code review (clean-code-principles), own diff
Nothing else relevant: no duplicated logic with existing helpers ( |
… the method A transition label reads [condition before] method [condition after] on one line, with each condition written as the spec writes it. The unmet clauses of a condition are marked, also next to clauses that are not about a state. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…arenthesised || Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Codex review, round 6 (after the change to conditions as in the spec,
|
… rejects the call Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Codex review, round 7
|
Closes #180. Based on main (#178 and #174 are merged there); not stacked on #172 (see below).
What changes, per proposal
When a call needs the states of several state sets (Door:
d.lock(); d.open();,openneedsdoorState(this) == closed && lockState(this) == unlocked):errorContextper diagram, not from message text: a set whoseinvalidStatesis not empty is in a wrong state; a set whose possible states are all accepted, with another set in a wrong state, is "right". In a right set, a transition of the call from the actual state whose condition names the wrong set is drawn as usual (white, normal arrow) and only the clause the actual state does not meet is red, also when conditions are collapsed. In the wrong set the call is red as before. Every other transition of the call stays red as now: when it has no condition on the wrong set, when the condition is not only states, when no set is wrong on its own (the verifier can only reject the combination), or when the state is unknown.orderStateMachinesputs the sets in a wrong state first, then the other sets of the error, then the rest. Focus mode fits the first diagram as before, so the ✕ state is now on screen (A1_38:markfirst, the case from the IDE review).%% lj-self-loops:comment like the existing dimmed-transitions one.[condition before] method [condition after]on one line, e.g.[lockState(this) == unlocked] open. Each condition is the spec text, so it reads like the Expected box and the spec, and a condition with other clauses stays readable: in[lockState(this) == unlocked && size(this) > 0] openonly the clause the actual state does not meet is red. Edge labels no longer wrap at Mermaid's 200px width, so a condition stays on the line of its method.closed, lockStateunlocked· actual lockStatelocked": expected in declaration order; actual lists only the sets in a wrong state (all known ones if none is). A set in which every state allows the call is left out of both sides, for named and unnamed sets (the A1_56 "(undoable or notUndoable) and redoable" case). Unnamed sets keep the current wording.Single-set classes are unchanged except for the round self-loops and the summary naming a named set (
expected phase open · actual phase closed).Ways to fix and #172
Not in this PR. Highlighting
unlockon the diagram needs to know which calls a hint suggests, andHintDTOonly haskindandmessage; getting the calls from the message text, or from paths in the diagram (judged unsound in #171), are both out. #172 lists the verifier's hints in a "Ways to fix" section and does not draw them; drawing a hint is #156, which needs a structured hint from the verifier first. So this PR does not depend on #172 and does not touch the hints; the two only meet infsm.ts/script.tscall sites and should rebase cleanly in either order.Screenshots
Headless VS Code, this branch's server (verifier 0.0.37, fsm 0.2.3). Focus mode is what opens from the error.
Door (the spec from #178,
d.lock(); d.open();):Study exercise A1_38 (BufferedInputStream, sets
streamandmark;buffered.reset()withoutmark(); proposal-D-task-types with liquidjava-api 0.0.8):The right set, scrolled down in focus mode (call drawn as usual, unmet condition red). These two and the A1_38 shots are from before the change to conditions as in the spec, which they still show as
[lockState: unlocked]; the Door shots above are current:doorStatestreamNot in this PR
closedindoorState,openinstream), as agreed.Reviews
Tests
npm run test:unit128 passed (5 new, each fails without the change: order, call/condition marks with!=and collapsed conditions, round loop, named summary without the any-state set; one existing expectation gains the self-loop comment),npm run test:typecheckandnpm run lintclean.mvn -B test39 passed.🤖 Generated with Claude Code