Make custom schedulers compose with the term/proof encoding#944
Draft
oflatt-claude wants to merge 1 commit into
Draft
Make custom schedulers compose with the term/proof encoding#944oflatt-claude wants to merge 1 commit into
oflatt-claude wants to merge 1 commit into
Conversation
Custom schedulers such as egglog-experimental's backoff scheduler drive a ruleset through `step_rules_with_scheduler`, but that path never ran the term-encoding maintenance rulesets (rebuilding, congruence, path compression, deferred deletion). Scheduled steps therefore queried stale, un-canonicalized view tables under term/proof encoding. Record the maintenance schedule in the program via a new internal `(internal-rebuild-schedule ...)` command and run it to fixpoint inside `step_rules` and `step_rules_with_scheduler` after each step. Because the schedule travels with the desugared program, the desugared output stays self-contained and runnable without term encoding. Only the user's ruleset is scheduled; maintenance always runs unscheduled. Add tests for term encoding + scheduler, proof mode, the real backoff algorithm (saturation-equivalence on a benchmark), and a fractional scheduler (residual-match soundness). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Custom schedulers — e.g. egglog-experimental's backoff scheduler — drive a ruleset through
EGraph::step_rules_with_scheduler. Under the term/proof encoding, the e-graph's invariants (canonical representatives, congruence closure, deferred deletion) are maintained by generated maintenance rulesets rather than the backend union-find, and those rulesets must be run to fixpoint between steps.step_rules_with_schedulernever ran them, so a scheduled step queried stale, un-canonicalized view tables — schedulers and term/proof mode did not compose.Approach
Record the maintenance schedule in the program itself via a new internal command
(internal-rebuild-schedule <schedule>), emitted once by the term-encoding pass.step_rulesandstep_rules_with_schedulerthen run that schedule to fixpoint after each step. Runs are no longer wrapped with an inline rebuild in the desugared schedule; non-run commands keep their existing per-command rebuild.Because the schedule travels with the desugared program (as data), the desugared output stays self-contained — it still runs correctly when replayed on a plain e-graph without term encoding (the
desugartest mode), which is why the schedule is carried in the program rather than gated on a runtime flag.Only the user's ruleset is scheduled; maintenance always runs unscheduled. The command is named
internal-rebuild-scheduleto signal it is not for direct use.Tests
choose_allsaturation-equivalenceFull
.eggsuite (744, across term-encoding / proofs / proof-testing / desugar modes) and lib tests pass;make nitsclean.Follow-up
The per-command rebuild for non-run commands is still injected into the desugared program. Moving it to a lazy rebuild-before-observe runtime model (mutations mark the e-graph dirty; maintenance runs only before
check/extract/print/queries) would remove that injection too. An eager "rebuild after each mutating command" does not work: a single userseton a:mergefunction desugars into multiple commands that must rebuild as a unit, and the flat desugared list has lost those boundaries — so this needs the lazy model, left as follow-up.🤖 Generated with Claude Code