Skip to content

Fix for DepthFirstGoalChooser: Keep enabled sibling goals on a split#3886

Merged
unp1 merged 1 commit into
mainfrom
bubel/goalchooser-disabled-goal-fix
Jul 5, 2026
Merged

Fix for DepthFirstGoalChooser: Keep enabled sibling goals on a split#3886
unp1 merged 1 commit into
mainfrom
bubel/goalchooser-disabled-goal-fix

Conversation

@unp1

@unp1 unp1 commented Jul 3, 2026

Copy link
Copy Markdown
Member

Related Issue

Not related to a tracked issue. The bug surfaced while exercising proof caching and is reproducible on main.

Intended Change

Fix automatic proof search stopping with an open goal, and requiring the user to restart it, when proof caching is enabled.

How to reproduce (on current main):

  1. Load the example BinarySearch from the examples directory with proof caching on
  2. Close it automatically
  3. Reload the problem
  4. Start the strategies (Full automation)
  5. Proof stops at Body Preserves Invariant but should be closed by caching

Reason:
DepthFirstGoalChooser.updateGoalListHelp locates, in its work list, the goal a rule was applied to (the "split point") so it can replace that goal with the rule's new goals. A splitting rule reuses the applied-to goal object for one of its branches (advancing its node), so the split point is found by identity among the new goals rather than by node. That membership test, however, ran against the new goals after they had been filtered to automatic goals. When the reused goal had been disabled — proof caching disables a branch it can close by reference — it was filtered out, the split point was not found, newGoalsInserted stayed false, and the rule's other, still-enabled, new goals were never inserted into the work list. getNextGoal() then eventually returns null while those goals still have applicable rules, so automatic proof search stops with an open goal and the user has to restart it for it to continue.

The fix matches the split point against all new goals (so a disabled reused goal is still found) and inserts only the automatic ones. Behaviour is unchanged when no new goal is disabled, i.e. for all ordinary proof search.

This is a pre-existing bug in DepthFirstGoalChooser, independent of any recent work; it is triggered whenever proof caching disables one branch of a splitting rule.

Type of pull request

  • Bug fix (non-breaking change which fixes an issue)
  • There are changes to the (Java) code

Ensuring quality

  • I made sure that introduced/changed code is well documented (javadoc and inline comments).
  • I added new test case(s) for new functionality.
  • I have tested the feature as follows: added ProofCachingSingleRunTest, which proves a method, then proves a second copy with a reference-search listener that mirrors CachingExtension (disable cache-hit goals during the run, close them afterwards) and asserts the second proof closes in a single automatic run. It fails without the fix (an enabled goal is stranded, requiring a restart) and passes with it. I also verified the multi-core determinism regression test still yields bit-identical proofs (sequential == 4 workers), and that TestReferenceSearcher / TestGoal remain green.
  • I have checked that runtime performance has not deteriorated: the change is a no-op whenever no new goal is disabled (the membership set is then identical), so ordinary proof search is byte-identical; only the proof-caching interaction differs.

Additional information and contact(s)

The change is small (three lines of logic plus an explanatory comment) and self-contained in DepthFirstGoalChooser.

The contributions within this pull request are licensed under GPLv2 (only) for inclusion in KeY.

Created with AI support

…a split

DepthFirstGoalChooser.updateGoalListHelp locates, in its work list, the goal
a rule was applied to, so it can replace that goal with the rule's new goals.
A splitting rule reuses the goal object for one of its branches (advancing
its node), so the split point is found by identity among the new goals rather
than by node. That membership test ran against the new goals *after* they had
been filtered to automatic goals: when the reused goal was disabled -- proof
caching disables a branch it can close by reference -- it was filtered out,
the split point was not found, newGoalsInserted stayed false, and the rule's
other, still enabled, new goals were never inserted into the work list.
getNextGoal() then eventually returns null while those goals still have
applicable rules, so automatic proof search stops with an open goal and the
user has to restart it (the proof caching "stops the search, restart needed"
symptom).

Match the split point against all new goals, so a disabled reused goal is
still found, and insert only the automatic ones. Behaviour is unchanged when
no new goal is disabled, i.e. for all ordinary proof search.

Adds ProofCachingSingleRunTest: a proof cached against a closed copy of
itself must close in a single automatic run; it fails without this fix.
@unp1 unp1 changed the title Fix proof caching stopping the search: keep enabled sibling goals on a split Fix: Keep enabled sibling goals on a split Jul 3, 2026
@unp1 unp1 changed the title Fix: Keep enabled sibling goals on a split Fix for DepthFirstgoalChooser: Keep enabled sibling goals on a split Jul 3, 2026
@unp1 unp1 changed the title Fix for DepthFirstgoalChooser: Keep enabled sibling goals on a split Fix for DepthFirstGoalChooser: Keep enabled sibling goals on a split Jul 3, 2026
@unp1 unp1 self-assigned this Jul 3, 2026
@unp1 unp1 added the 🐞 Bug label Jul 3, 2026
@unp1 unp1 added this to the v3.0.0 milestone Jul 3, 2026
@unp1
unp1 requested a review from WolframPfeifer July 3, 2026 16:01
@unp1
unp1 enabled auto-merge July 4, 2026 10:08
@unp1
unp1 added this pull request to the merge queue Jul 5, 2026
Merged via the queue into main with commit 1431a91 Jul 5, 2026
36 checks passed
@unp1
unp1 deleted the bubel/goalchooser-disabled-goal-fix branch July 5, 2026 22:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants