8000 feat(query): magic sets rewriting for demand-driven recursive rule evaluation (#289) by adityamukho · Pull Request #291 · project-minigraf/minigraf · GitHub
[go: up one dir, main page]

Skip to content

feat(query): magic sets rewriting for demand-driven recursive rule evaluation (#289) - #291

Merged
adityamukho merged 23 commits into
mainfrom
feat/magic-sets-289
Jun 4, 2026
Merged

adityamukho merged 23 commits into
mainfrom
feat/magic-sets-289

Conversation

@adityamukho
Copy link
Copy Markdown
Collaborator

Summary

  • Implements magic sets rewriting (Beeri & Ramakrishnan 1991) in a new src/query/datalog/magic_sets.rs module
  • Transforms positive recursive rules at query time to push bound query args back into the rules as magic predicates, reducing O(N²) derivations to O(N) for point queries over recursive rules
  • Wired into execute_query_with_rules in executor.rs — zero overhead for all-free queries (returns None, no registry copy)
  • Mixed rules containing not/not-join are left untouched; negation extension deferred to §9.6 in ROADMAP

Test Plan

  • 17 unit tests in magic_sets.rs covering adornment classification, seed fact generation, guard injection, propagation rules, SCC propagation, and the full rewrite() entry point
  • 5 integration tests in tests/magic_sets_test.rs asserting result correctness (transitive closure with bound start, all-free closure, bound ⊆ all-free subset check, multi-hop recursion, mutual even/odd recursion)
  • Full suite: 974 tests passing, 0 failures

🤖 Generated with Claude Code

adityamukho and others added 23 commits June 4, 2026 11:28
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove unused EdnValue and WhereClause imports from scaffold; they will
be added in Task 2 when implementing adornment classification. Keep
HashMap and HashSet imports with allow(unused_imports) since they'll be
used in Task 2. Add #[allow(dead_code)] to rewrite() which isn't called
until integration in Task 7.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…magic_guard (#289)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
)

- Add debug_assert_eq! to catch adornment/arity mismatch before silent filter_map drop
- Replace {:?} WhereClause debug format in test panic arms (CodeQL rust/cleartext-logging)
- Add inline comment explaining i+1 offset for predicate-name-skipping in head args

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…propagation_rules (#289)

- Fix 1: head now includes ALL bound args (not just first) for multi-bound adornments like bb
- Fix 2: skip all-free adorned predicates to avoid emitting malformed propagation rules
- Fix 3: rename inner loop variable `i` to `pos` to avoid shadowing outer loop's `i`
- Fix 4: add test_propagation_rule_bb_adornment verifying 3-element head for bb adornment

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements propagate_adornments() for fixed-point adornment propagation
through mutually-recursive SCCs, build_rewritten_registry() to assemble
the magic-transformed rule set, and replaces the rewrite() stub with the
full implementation. Adds 3 new unit tests (16 total, all passing).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
#289)

- Fix indexing_slicing: replace &rule.body[..i] with rule.body.iter().take(i)
- Add first-writer-wins comment in propagate_adornments for multi-call-site clarity
- Fix three collapsible_if warnings using let-chain syntax
- Remove spurious #[allow(dead_code)] from make_rule test helper
- Add test_rewritten_registry_has_magic_guard_in_rules for guard injection coverage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Also guard against all-bound (bb) adornments in rewrite() — the magic-guard
encoding does not support multi-bound seed facts, and fully-bound queries
gain nothing from magic sets; return None to fall through to the regular
evaluator unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…289)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Five tests covering bound-start transitive closure, all-free closure,
subset correctness, multi-hop recursion, and mutual recursion (even/odd
distance) — asserting magic sets rewriting never changes query results.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… test (#289)

Remove {:?} on Value in extract_refs (CodeQL rust/cleartext-logging); add two missing negative assertions for n2/n4 in test_mutual_recursion_even_odd_distance.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codecov
codecov Bot commented Jun 4, 2026
Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.29630% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/query/datalog/magic_sets.rs 96.07% 6 Missing ⚠️

📢 Thoughts on this report? Let us know!

@adityamukho
adityamukho merged commit e6cba8b into main Jun 4, 2026
17 checks passed
@adityamukho
adityamukho deleted the feat/magic-sets-289 branch June 4, 2026 10:37
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

0