Skip to content

Add primitive command support#46

Merged
saulshanabrook merged 16 commits into
mainfrom
codex/experimental-body-primitive
Jun 17, 2026
Merged

Add primitive command support#46
saulshanabrook merged 16 commits into
mainfrom
codex/experimental-body-primitive

Conversation

@saulshanabrook

@saulshanabrook saulshanabrook commented May 18, 2026

Copy link
Copy Markdown
Member

Context

Adds the experimental (primitive name (InputSort*) OutputSort body) command for defining primitives from egglog expressions.

Depends on: egraphs-good/egglog#881, currently pinned in Cargo.lock to egglog commit a80b23515d172d95cfbf84d9b90ee154e03a9e7d on codex/split-primitive-body-runtime-apis.

This PR intentionally does not include the unrelated core-relations ordering fix from egraphs-good/egglog#899. That bug is already present in the current egglog-experimental main dependency: main pins an egglog commit descended from egglog PR #862, whose cleanup commit changed multi-column column-index rebuild ordering. The issue only trips a debug_assert! in debug builds; egglog-experimental CI currently runs make test, which uses release-mode nextest/doc tests, so math_backoff still passes in CI. PR #899 isolates that fix on egglog main with its own regression test.

Current shape

  • Registers a primitive user-defined command in new_experimental_egraph.
  • Typechecks primitive bodies with explicit positional bindings and an expected output sort.
  • Infers the minimum primitive capability needed by the body (Pure, Read, Write, or Full) and registers the primitive in the matching runtime context.
  • Evaluates primitive bodies through egglog Core::eval_resolved_expr rather than duplicating expression evaluation locally.
  • Calls egglog EGraph::prepare_unstable_fn_targets_for_eval before registration so direct literal (unstable-fn "...") targets work in primitive bodies using the same hidden ResolvedFunction value as backend rule lowering.
  • Accounts for direct literal unstable-fn targets during capability inference, so custom-function targets require read-capable contexts, constructor targets require write-capable contexts, and primitive targets use the minimum compatible primitive runtime context.
  • Supports direct table-backed function calls, constructor calls, primitive calls, function-container input/output sorts, and global references, subject to the inferred runtime context.
  • Treats global references as read-capable because egglog lowers globals to zero-argument custom-function lookups.
  • Keeps seminaive safety by making read-dependent bodies unavailable from pure/write-only seminaive contexts unless the surrounding rule is :naive.
  • Adds positive and fail-typecheck coverage for primitive bodies, overload output context, map output context, hidden table dependencies, read-capability bodies, global-reference bodies, direct unstable-fn targets, missing direct targets, function-container bodies, table-backed function bodies, and constructor bodies.
  • Updates the local Rule initializer for egglog no_decomp and adapts user-defined commands to egglog's current Vec<CommandOutput> return shape.

Tried and decided against

  • Initially tried a broader egglog PreparedResolvedExpr / core-action preparation API. Replaced it with the narrower core helper plus direct Core::eval_resolved_expr, which keeps the experimental command simpler and avoids exposing a general prepared-action abstraction.
  • Considered implementing a separate expression evaluator in egglog-experimental. Dropped that in favor of using egglog execution-state evaluation so primitive calls and table-backed calls share the core runtime behavior.
  • Considered migrating top-level egglog eval to the same direct execution-state path and considered an IR refactor where resolved unstable-fn targets live in atom terms. Those were parked as larger cleanup directions and are not needed for this PR.
  • Does not include the core-relations math_backoff debug assertion fix; that remains isolated in egglog PR #899.

Validation

  • Latest against egglog commit a80b23515d172d95cfbf84d9b90ee154e03a9e7d:
    • cargo fmt
    • cargo test --test files -- primitive --nocapture
    • cargo check
    • git diff --check
  • Earlier on this PR:
    • cargo check --locked --lib
    • cargo test --locked --lib --quiet
    • cargo test --locked --test files -- primitive
    • With the local egglog patch before the final lockfile pin, cargo test --test files -- primitive_function_container passed.
    • With the local egglog patch before the final lockfile pin, full debug cargo test --test files --quiet reported 34 passing file tests and the known unrelated math_backoff sorted-slice debug assertion.
    • Separate review agent over this PR plus the dependent egglog PR: no remaining findings after the dependency pin was updated.

Known unrelated debug-only failure:

@saulshanabrook saulshanabrook force-pushed the codex/experimental-body-primitive branch 2 times, most recently from d29f02c to 24a1e85 Compare May 18, 2026 20:56
@saulshanabrook saulshanabrook force-pushed the codex/experimental-body-primitive branch from 24a1e85 to dda35a0 Compare May 20, 2026 19:10
@saulshanabrook saulshanabrook moved this to This Week in Saul Shanabrook May 26, 2026
@saulshanabrook saulshanabrook moved this from This Week to In Progress in Saul Shanabrook May 26, 2026
Comment thread src/primitive.rs Outdated
Comment thread src/primitive.rs Outdated
Comment thread src/primitive.rs Outdated
Comment thread src/lib.rs Outdated
Comment thread src/lib.rs Outdated
Comment thread src/primitive.rs Outdated
Comment thread src/primitive.rs Outdated
Comment thread src/primitive.rs Outdated
Comment thread src/primitive.rs Outdated
Comment thread src/primitive.rs Outdated
Comment thread src/primitive.rs
Comment thread src/primitive.rs Outdated
@saulshanabrook

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown
✅ Actions performed

Full review triggered.

@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds user-defined primitive registration to egglog via a new primitive command. It updates dependencies to track a new branch, introduces the primitive module with registration and evaluation logic, and updates the for-macro rule structure for compatibility.

Changes

Body-defined primitives feature

Layer / File(s) Summary
Dependency branch update
Cargo.toml
Git dependencies for egglog, egglog-ast, and egglog-reports are updated to track the codex/split-primitive-body-runtime-apis branch.
Module introduction and command registration
src/lib.rs
Documentation describes body-defined primitives, runtime-context constraints, and how positional body variables are represented. The primitive module is introduced and the primitive command is registered into the experimental EGraph.
Primitive registration, type, and evaluation logic
src/primitive.rs
RegisterPrimitive command decodes primitive metadata and typechecks the body expression across Pure, Read, Write, and Full contexts, selecting the first compatible context. DefinedPrimitive stores the signature and typed body, implements Primitive trait with context-specific apply methods, and evaluates by building bindings from hidden bindings plus runtime arguments. Helper functions decode atoms, check for name collisions, resolve sort names, infer required context with unstable-fn handling, and format errors.
For-macro rule structure update
src/sugar/for.rs
The Rule struct constructed by the for macro now explicitly sets the no_decomp field to false.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Suggested reviewers

  • yihozhang
  • FTRobbin
  • oflatt
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and directly describes the main feature being added: primitive command support. It aligns with the primary changes across all files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description provides comprehensive detail about the experimental primitive command feature, dependency pins, implementation decisions, validation steps, and known issues.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/experimental-body-primitive

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Cargo.toml`:
- Around line 20-22: The Cargo.toml git dependencies for egglog, egglog-ast, and
egglog-reports should be pinned to the resolved commit to ensure reproducible
builds: replace branch = "codex/split-primitive-body-runtime-apis" with rev =
"cf4fe23e104c263e07b771f4a314cf0dac8be1c8" for the egglog, egglog-ast, and
egglog-reports entries and remove the branch key so the three dependencies
reference the exact commit instead of a moving branch.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 417e4089-4256-4049-8007-2bd808ed0124

📥 Commits

Reviewing files that changed from the base of the PR and between 08771f9 and a58a98f.

⛔ Files ignored due to path filters (17)
  • Cargo.lock is excluded by !**/*.lock
  • tests/fail-typecheck/primitive-bad-positional-var.egg is excluded by !**/*.egg
  • tests/fail-typecheck/primitive-direct-function-body-in-rule.egg is excluded by !**/*.egg
  • tests/fail-typecheck/primitive-hidden-table-dependency.egg is excluded by !**/*.egg
  • tests/fail-typecheck/primitive-malformed-input-sorts.egg is excluded by !**/*.egg
  • tests/fail-typecheck/primitive-missing-unstable-fn-target.egg is excluded by !**/*.egg
  • tests/fail-typecheck/primitive-output-context-eqsort-mismatch.egg is excluded by !**/*.egg
  • tests/fail-typecheck/primitive-output-context-mismatch.egg is excluded by !**/*.egg
  • tests/fail-typecheck/primitive-read-body-in-seminaive-rule.egg is excluded by !**/*.egg
  • tests/fail-typecheck/primitive-unresolved-body-symbol.egg is excluded by !**/*.egg
  • tests/primitive-constructor-body.egg is excluded by !**/*.egg
  • tests/primitive-function-container.egg is excluded by !**/*.egg
  • tests/primitive-map-empty-output-context.egg is excluded by !**/*.egg
  • tests/primitive-overload-output-context.egg is excluded by !**/*.egg
  • tests/primitive-read-body.egg is excluded by !**/*.egg
  • tests/primitive-table-backed-body.egg is excluded by !**/*.egg
  • tests/primitive.egg is excluded by !**/*.egg
📒 Files selected for processing (4)
  • Cargo.toml
  • src/lib.rs
  • src/primitive.rs
  • src/sugar/for.rs
📜 Review details
🔇 Additional comments (3)
src/lib.rs (1)

19-25: LGTM!

Also applies to: 47-47, 83-85

src/primitive.rs (1)

12-290: LGTM!

src/sugar/for.rs (1)

39-47: LGTM!

Comment thread Cargo.toml Outdated
@saulshanabrook saulshanabrook marked this pull request as ready for review June 1, 2026 13:47
@saulshanabrook saulshanabrook requested a review from a team as a code owner June 1, 2026 13:47
@saulshanabrook saulshanabrook requested review from a team, FTRobbin and yihozhang and removed request for a team and FTRobbin June 1, 2026 13:47
@saulshanabrook saulshanabrook moved this from In Progress to Done in Saul Shanabrook Jun 1, 2026
@saulshanabrook saulshanabrook moved this from Done to Waiting for Review in Saul Shanabrook Jun 1, 2026
@saulshanabrook saulshanabrook moved this from Waiting for Review to In Progress in Saul Shanabrook Jun 1, 2026
@saulshanabrook saulshanabrook moved this from In Progress to Waiting for Review in Saul Shanabrook Jun 2, 2026
@saulshanabrook saulshanabrook moved this from Waiting for Review to Blocked in Saul Shanabrook Jun 8, 2026
…dy-primitive

# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	src/lib.rs
#	src/scheduling.rs
#	src/set_cost.rs
@saulshanabrook saulshanabrook merged commit 6525a48 into main Jun 17, 2026
5 checks passed
@github-project-automation github-project-automation Bot moved this from Blocked to Done in Saul Shanabrook Jun 17, 2026
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.

2 participants