Skip to content

Add proof support for Pair and Either containers#923

Closed
saulshanabrook wants to merge 6 commits into
egraphs-good:mainfrom
saulshanabrook:codex/proof-containers-pair
Closed

Add proof support for Pair and Either containers#923
saulshanabrook wants to merge 6 commits into
egraphs-good:mainfrom
saulshanabrook:codex/proof-containers-pair

Conversation

@saulshanabrook

@saulshanabrook saulshanabrook commented Jun 7, 2026

Copy link
Copy Markdown
Member

Context

This is an initial proof-support slice for container-backed values. The motivating path is getting eggcc merge functions working without relying on datatype constructors by adding proof support for the Rust-level containers that those merge functions use.

Related PRs:

Design

This treats a first set of fixed-shape containers as constructor-like at the proof boundary. Pair and the constructor/projection pieces of Either expose metadata describing their proof-level constructor heads and field projections. The proof encoder consumes that metadata generically, rather than hard-coding Pair or Either in proof_encoding.rs.

For supported container constructors, proof instrumentation creates proof-carrying views and rebuild rules in the same spirit as constructor views. Rebuilds preserve enough constructor structure that extracted equality proofs lower to ordinary Congr/Trans/Sym proof terms over pair, either-left, or either-right, matching the shape reviewers would expect from equivalent user-land datatypes.

The branch also adds proof-normal-form handling so supported container constructors can remain constructor-shaped instead of being treated like arbitrary primitives, while projections such as pair-first and either-unwrap-left stay projection operations.

proof_encoding.rs Shape

The largest-looking core diff is in src/proofs/proof_encoding.rs, because that file is where proof mode lowers user commands into term/view/proof instrumentation. The conceptual change there is intentionally narrow:

  • query_fact_view factors the existing view-query/proof-composition path so constructors, custom functions, and container constructor views use the same machinery.
  • proof_container_encoding emits term/view, congruence, and rebuild rules from a generic ContainerProofSpec supplied by the sort.
  • instrument_fact_expr recognizes container constructor primitives and projection primitives through that metadata, rather than matching on Pair/Either names.
  • action instrumentation routes container constructor primitives through the same created-term/view path used for constructor-shaped proof terms.

So while the file diff is visible, the new behavior is mostly a small set of generic hooks into the existing term/view/rebuild pipeline. The Pair/Either-specific details live in the sort implementations and the RFC/tests, not in proof encoding.

Scope And TBD

This PR covers Pair and the constructor/projection pieces of Either through eq-sort wrapper use cases. Direct non-eq container globals remain out of scope.

The remaining proof-mode work for the eggcc direction is still support for the (primitive) macro and unstable functions in proofs.

@saulshanabrook

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@codspeed-hq

codspeed-hq Bot commented Jun 7, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 216 skipped benchmarks1


Comparing saulshanabrook:codex/proof-containers-pair (b944b1d) with main (a2da717)

Open in CodSpeed

Footnotes

  1. 216 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds proof-mode support for fixed-shape container sorts (Pair and Either): container proof metadata and hooks, Either implementation and Pair updates, generalized proof-view congruence/rebuild encoding, instrumentation for container constructors/projections, and integration with typechecking and presort registration.

Changes

Container Proof Support

Layer / File(s) Summary
RFC: Container Proof Design
rfcs/001-proof-containers.md
RFC 001 specifies proof-mode support for container sorts in eq-constructors, defining supported containers (Pair, Either), required metadata, proof-encoding workflow (views, congruence, rebuild rules), proof-normal-form exceptions, and acceptance criteria.
Sort/Presort Hooks & TypeInfo
src/sort/mod.rs, src/prelude.rs, src/typechecking.rs
Adds ContainerProofSpec and constructor/projection metadata; adds Sort::container_proof_spec() and Presort::supports_proof_encoding() hooks; records proof-supporting presorts in TypeInfo and forwards the hook through ContainerSortImpl.
Pair Container Proof Spec & Validators
src/sort/pair.rs
PairSort opts into proof encoding, exposes a container proof spec (constructor pair with pair-first/pair-second projections), and replaces pair primitives with validators enforcing term shapes.
Either Container Implementation
src/sort/either.rs
Implements EitherSort/EitherContainer, registers either-left/either-right constructors and either-unwrap-* projections, reconstructs termdag/serialization for Either values, and registers typed either-match primitives for compatible function sorts via a helper.
Proof Encoding Helpers
src/proofs/proof_encoding_helpers.rs
Adds proof_container_constructor helper to match primitives to container constructor specs and extends command support checks to accept presorts that enable proof encoding.
Proof Normal-Form Exception
src/proofs/proof_normal_form.rs
Special-cases container constructor primitives so their arguments are normalized but not extracted into fresh equality facts during proof-normal-form generation.
Proof Encoding: Views, Congruence, Rebuild
src/proofs/proof_encoding.rs
Refactors proof encoding around proof-view keys: generalizes congruence handling, introduces view-based rebuilding rules and canonical-sort checks, centralizes proof helpers (proof_for_value, query_fact_view), implements proof_container_encoding, and conditions UF/proof initialization on canonical sorts.
Fact & Action Instrumentation for Containers
src/proofs/proof_encoding.rs (partial)
Centralizes variable proof facts, routes fact queries through view helpers, detects container-proof constructor/projection primitives, and uses add_created_term_and_view for container term/action construction.
Integration: EGraph & FunctionSort
src/lib.rs, src/sort/fn.rs
Registers EitherSort in EGraph::default() and calls register_either_primitives_for_function from FunctionSort::register_primitives to publish either-match primitives.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested labels

status:needs decision

Suggested reviewers

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

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 52.38% 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 concisely summarizes the main objective: adding proof support for Pair and Either container types, which is exactly what the changeset accomplishes.
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 pull request description clearly describes the changeset, explaining the motivation (eggcc merge functions), design (container-backed values as constructor-like at proof boundary), scope (Pair and Either containers), and implementation approach.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/proofs/proof_encoding_helpers.rs (1)

551-565: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't let proof-capable presorts bypass reserved sort-annotation checks.

Line 554 returns Ok(()) for supported presorts before Lines 559-565 reject user-specified uf / proof_func annotations. That means a Pair/Either sort can now slip through with internal annotations that the encoder assumes it owns, which breaks the sort-command contract for proof mode.

Suggested fix
-        GenericCommand::Sort {
-            presort_and_args: Some((presort, _)),
-            ..
-        } if type_info.presort_supports_proof_encoding(presort) => Ok(()),
-        GenericCommand::Sort {
-            presort_and_args: Some(_),
-            ..
-        } => Err(ProofEncodingUnsupportedReason::SortWithPresort),
         GenericCommand::Sort { uf: Some(_), .. } => {
             Err(ProofEncodingUnsupportedReason::SortWithUfAnnotation)
         }
         GenericCommand::Sort {
             proof_func: Some(_),
             ..
         } => Err(ProofEncodingUnsupportedReason::SortWithProofFuncAnnotation),
+        GenericCommand::Sort {
+            presort_and_args: Some((presort, _)),
+            ..
+        } if type_info.presort_supports_proof_encoding(presort) => Ok(()),
+        GenericCommand::Sort {
+            presort_and_args: Some(_),
+            ..
+        } => Err(ProofEncodingUnsupportedReason::SortWithPresort),
🤖 Prompt for 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.

In `@src/proofs/proof_encoding_helpers.rs` around lines 551 - 565, The match arm
for GenericCommand::Sort currently returns Ok(()) when presort_and_args:
Some((presort, _)) and type_info.presort_supports_proof_encoding(presort) is
true, which short-circuits later checks that reject user-provided uf or
proof_func annotations; update the logic so that even when a presort is
proof-capable you still verify that uf and proof_func are None before accepting
the sort. Concretely, in the GenericCommand::Sort handling (presort_and_args,
presort, type_info.presort_supports_proof_encoding, uf, proof_func, and the
ProofEncodingUnsupportedReason variants SortWithUfAnnotation and
SortWithProofFuncAnnotation), ensure you check uf and proof_func first (or add
an additional guard) and return the appropriate Err if they are present, only
returning Ok(()) if no user annotations exist.
🤖 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 `@src/proofs/proof_encoding.rs`:
- Around line 865-899: The projection branch currently drops the container/view
justification and arg_proofs[0] and returns only proof_for_value(selected);
instead, preserve and include the view/query proof and the original container
argument proof when building the returned proof: after calling
self.query_view_and_get_proof(&view_key, &field_vars) append the returned
view/query proof variable (and also ensure arg_proofs[0] is pushed into res)
before calling self.proof_for_value so that the resulting proof chain includes
the container/view justification for the projection; locate this logic around
the projection closure handling (symbols: projection, specialized_primitive,
container_view_key, query_view_and_get_proof, proof_for_value, res, arg_proofs)
and modify the res population and proof creation accordingly.

In `@src/sort/either.rs`:
- Around line 79-101: Replace the panic in make_sort with a Result::Err
returning a TypeError variant so callers can handle the error: instead of
panic!("Either sort requires exactly two arguments"), return
Err(TypeError::InvalidSortArity(name.clone(), args.len())) (or add a new
TypeError variant such as InvalidSortArguments/InvalidSortArity) and construct
the error with the sort name and actual arg count (optionally include spans from
args if your TypeError carries span info); update the TypeError enum to include
that new variant if necessary and use it in make_sort where the arg pattern
fails.

In `@src/sort/mod.rs`:
- Around line 30-47: The projection method on ContainerProofSpec assumes
projection primitive names are unique across all constructors but doesn't
document this; add a doc comment on the ContainerProofSpec::projection method
(or on the ContainerProofSpec type) stating that projection primitive names must
be globally unique within a ContainerProofSpec and that the method returns the
first matching (constructor, projection) pair when duplicates exist, so callers
or implementers must ensure uniqueness or handle ambiguity accordingly
(reference symbols: ContainerProofSpec, projection, constructors, projections,
primitive).

---

Outside diff comments:
In `@src/proofs/proof_encoding_helpers.rs`:
- Around line 551-565: The match arm for GenericCommand::Sort currently returns
Ok(()) when presort_and_args: Some((presort, _)) and
type_info.presort_supports_proof_encoding(presort) is true, which short-circuits
later checks that reject user-provided uf or proof_func annotations; update the
logic so that even when a presort is proof-capable you still verify that uf and
proof_func are None before accepting the sort. Concretely, in the
GenericCommand::Sort handling (presort_and_args, presort,
type_info.presort_supports_proof_encoding, uf, proof_func, and the
ProofEncodingUnsupportedReason variants SortWithUfAnnotation and
SortWithProofFuncAnnotation), ensure you check uf and proof_func first (or add
an additional guard) and return the appropriate Err if they are present, only
returning Ok(()) if no user annotations exist.
🪄 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: 20f07def-05ca-40d3-93c4-a039e88527cf

📥 Commits

Reviewing files that changed from the base of the PR and between a2da717 and 88270b5.

⛔ Files ignored due to path filters (8)
  • tests/proofs/either-proof.egg is excluded by !**/*.egg
  • tests/proofs/either-userland-proof.egg is excluded by !**/*.egg
  • tests/proofs/pair-proof.egg is excluded by !**/*.egg
  • tests/proofs/pair-userland-proof.egg is excluded by !**/*.egg
  • tests/snapshots/files__shared_snapshot_either_proof.snap is excluded by !**/*.snap
  • tests/snapshots/files__shared_snapshot_either_userland_proof.snap is excluded by !**/*.snap
  • tests/snapshots/files__shared_snapshot_pair_proof.snap is excluded by !**/*.snap
  • tests/snapshots/files__shared_snapshot_pair_userland_proof.snap is excluded by !**/*.snap
📒 Files selected for processing (11)
  • rfcs/001-proof-containers.md
  • src/lib.rs
  • src/prelude.rs
  • src/proofs/proof_encoding.rs
  • src/proofs/proof_encoding_helpers.rs
  • src/proofs/proof_normal_form.rs
  • src/sort/either.rs
  • src/sort/fn.rs
  • src/sort/mod.rs
  • src/sort/pair.rs
  • src/typechecking.rs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
  • GitHub Check: benchmark (ubuntu-latest, rectangle)
  • GitHub Check: benchmark (ubuntu-latest, stresstest_large_expr)
  • GitHub Check: benchmark (ubuntu-latest, conv1d_32)
  • GitHub Check: benchmark (ubuntu-latest, luminal-llama)
  • GitHub Check: benchmark (ubuntu-latest, conv1d_128)
  • GitHub Check: benchmark (ubuntu-latest, rust_rule_insert_loop)
  • GitHub Check: benchmark (ubuntu-latest, eggcc-2mm)
  • GitHub Check: benchmark (ubuntu-latest, proof_testing_typecheck)
  • GitHub Check: benchmark (ubuntu-latest, repro-665-set-union)
  • GitHub Check: benchmark (ubuntu-latest, herbie)
  • GitHub Check: benchmark (ubuntu-latest, taylor51)
  • GitHub Check: benchmark (ubuntu-latest, rust_rule_fib)
  • GitHub Check: benchmark (ubuntu-latest, factoring-multisets)
  • GitHub Check: benchmark (ubuntu-latest, eggcc-extraction)
  • GitHub Check: coverage
  • GitHub Check: test
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{md,txt,rs}

📄 CodeRabbit inference engine (CLAUDE.md)

Keep documentation concise and avoid duplicate information

Files:

  • src/lib.rs
  • src/sort/fn.rs
  • src/typechecking.rs
  • src/proofs/proof_encoding_helpers.rs
  • src/sort/mod.rs
  • src/prelude.rs
  • src/proofs/proof_normal_form.rs
  • src/sort/pair.rs
  • rfcs/001-proof-containers.md
  • src/sort/either.rs
  • src/proofs/proof_encoding.rs
🧠 Learnings (1)
📚 Learning: 2026-05-31T20:06:45.343Z
Learnt from: saulshanabrook
Repo: egraphs-good/egglog PR: 881
File: src/exec_state.rs:114-129
Timestamp: 2026-05-31T20:06:45.343Z
Learning: In `src/exec_state.rs` (egglog crate, Rust), `Internal::apply_table_function` and related helpers deliberately gate authorization via `self.ctx()` (the stamped call-site context) rather than a per-wrapper capability type check. The potential capability escalation (a less-capable wrapper running under a wider Context invoking wider operations) is intentionally prevented by the experimental call site that prepares and registers primitives, not by a Rust type-level capability guard. The design decision is documented in the `Core::apply_primitive` and `Core::eval_resolved_expr` doc comments rather than enforced structurally. This is an accepted trade-off to keep the PR minimal.

Applied to files:

  • src/proofs/proof_normal_form.rs
🔇 Additional comments (11)
rfcs/001-proof-containers.md (1)

1-208: LGTM!

src/sort/mod.rs (1)

22-68: LGTM!

Also applies to: 137-141, 208-212, 94-95

src/prelude.rs (1)

860-862: LGTM!

Also applies to: 927-929

src/typechecking.rs (1)

201-201: LGTM!

Also applies to: 606-608, 615-617

src/sort/either.rs (5)

1-15: LGTM!


17-58: LGTM!


104-273: LGTM!


317-365: LGTM!


290-315: Verify name-based sort comparison in try_registering_either_match is safe.
left_fn.inputs()[0].name()/right_fn.inputs()[0].name()/left_fn.output().name() comparisons are sufficient because an EGraph interns sorts in TypeInfo.sorts: HashMap<String, Arc<dyn Sort>> keyed by sort.name(), and EGraph::add_arcsort rejects duplicates with TypeError::SortAlreadyBound. So two incompatible sorts can’t share the same name in the same graph, making name-equality effectively equivalent to sort identity here.

src/lib.rs (1)

420-420: LGTM!

src/sort/fn.rs (1)

220-220: LGTM!

Comment thread src/proofs/proof_encoding.rs
Comment thread src/sort/either.rs
Comment thread src/sort/mod.rs
@saulshanabrook

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@saulshanabrook saulshanabrook marked this pull request as ready for review June 7, 2026 19:29
@saulshanabrook saulshanabrook requested a review from a team as a code owner June 7, 2026 19:29
@saulshanabrook saulshanabrook requested review from ezrosent and removed request for a team June 7, 2026 19:29
@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@saulshanabrook saulshanabrook requested review from oflatt and removed request for ezrosent June 7, 2026 19:29

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (1)
src/proofs/proof_encoding.rs (1)

865-899: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve the projection/view proof instead of returning only the field proof.

This branch still drops the proof returned by query_view_and_get_proof(...) and returns only proof_for_value(selected). That proves the extracted field value in isolation, but it no longer proves that the matched expression was the projection term being queried, so facts like =(pair-first (pair a b)) x lose the justification that connects pair-first(...) back to the container view and its input proof.

🤖 Prompt for 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.

In `@src/proofs/proof_encoding.rs` around lines 865 - 899, The code drops the view
proof from query_view_and_get_proof(...) and only returns the field's proof;
capture the view proof variable returned by query_view_and_get_proof (instead of
_view_proof_var), ensure that that view proof (or its proof variable) is
appended to res (or otherwise combined) before calling self.proof_for_value(...)
so the resulting proof chain includes both the container/view proof and the
extracted field proof; update the tuple binding from let (query,
_view_proof_var) = self.query_view_and_get_proof(...) to capture the view proof
and include it in res so facts like the projection are justified.
🤖 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 `@src/proofs/proof_encoding_helpers.rs`:
- Around line 558-565: The rejection branch for GenericCommand::Sort with
presort_and_args should report that the specific presort does not advertise
proof-encoding support instead of the generic
ProofEncodingUnsupportedReason::SortWithPresort; update the Err returned in the
arm that matches presort_and_args: Some(_) (the arm guarded by
!type_info.presort_supports_proof_encoding) to return a more specific diagnostic
(either a new enum variant like
ProofEncodingUnsupportedReason::PresortNotSupported or include the presort
identifier/name from presort_and_args in the error message) and use
type_info.presort_supports_proof_encoding(presort) and the presort value to
populate the new message so users see which presort lacks support.

In `@src/proofs/proof_normal_form.rs`:
- Around line 121-129: Update the module's documented normal-form invariant to
mention the new exception: when a ResolvedCall::Primitive is recognized by
proof_container_constructor(...) as a container constructor, its call arguments
are intentionally preserved (handled by proof_form_expr and returned as
ResolvedExpr::Call). Find the comment that currently states "primitives cannot
keep constructor/function-call arguments" and revise it to explicitly allow this
container-constructor exception and briefly note proof_container_constructor,
ResolvedCall::Primitive, proof_form_expr, and ResolvedExpr::Call as the relevant
implementation points.

In `@src/sort/either.rs`:
- Around line 36-39: The code is matching self.data (and either.data) by value
which moves the non-Copy EitherData out of a borrowed context; change the
matches in the iter method (impl for Either::iter) and in
ContainerValues::get_val to match on &self.data / &either.data and then copy or
clone the inner Value when returning it (e.g. match &self.data {
EitherData::Left(v) => Some(v.clone()).into_iter(), ... }), ensuring you only
borrow the enum and duplicate the contained Value rather than moving the enum
itself.

In `@src/sort/pair.rs`:
- Around line 61-63: The supports_proof_encoding() implementation in PairSort
currently returns true unconditionally which lets
command_supports_proof_encoding() accept (Pair ...) in proof mode even when
inner sorts are non-eq; update the admission check so proof support is
instance-aware: change supports_proof_encoding() (and the analogous EitherSort
method) to inspect the instantiated inner sorts and return true only when both
inner sorts satisfy is_eq_container_sort() (or otherwise meet the per-sort proof
criteria), or alternatively perform the check inside
command_supports_proof_encoding() by querying the instantiated Pair/Either sort
parameters and rejecting non-eq instantiations during typechecking/proof-mode
admission.

---

Duplicate comments:
In `@src/proofs/proof_encoding.rs`:
- Around line 865-899: The code drops the view proof from
query_view_and_get_proof(...) and only returns the field's proof; capture the
view proof variable returned by query_view_and_get_proof (instead of
_view_proof_var), ensure that that view proof (or its proof variable) is
appended to res (or otherwise combined) before calling self.proof_for_value(...)
so the resulting proof chain includes both the container/view proof and the
extracted field proof; update the tuple binding from let (query,
_view_proof_var) = self.query_view_and_get_proof(...) to capture the view proof
and include it in res so facts like the projection are justified.
🪄 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: a6eca469-f7cf-4a2a-bfdd-538fb204e6fb

📥 Commits

Reviewing files that changed from the base of the PR and between a2da717 and 9709cca.

⛔ Files ignored due to path filters (10)
  • tests/fail-typecheck/either-invalid-arity.egg is excluded by !**/*.egg
  • tests/proofs/either-proof.egg is excluded by !**/*.egg
  • tests/proofs/either-userland-proof.egg is excluded by !**/*.egg
  • tests/proofs/pair-proof.egg is excluded by !**/*.egg
  • tests/proofs/pair-userland-proof.egg is excluded by !**/*.egg
  • tests/snapshots/files__fail-typecheck__either_invalid_arity.snap is excluded by !**/*.snap
  • tests/snapshots/files__shared_snapshot_either_proof.snap is excluded by !**/*.snap
  • tests/snapshots/files__shared_snapshot_either_userland_proof.snap is excluded by !**/*.snap
  • tests/snapshots/files__shared_snapshot_pair_proof.snap is excluded by !**/*.snap
  • tests/snapshots/files__shared_snapshot_pair_userland_proof.snap is excluded by !**/*.snap
📒 Files selected for processing (11)
  • rfcs/001-proof-containers.md
  • src/lib.rs
  • src/prelude.rs
  • src/proofs/proof_encoding.rs
  • src/proofs/proof_encoding_helpers.rs
  • src/proofs/proof_normal_form.rs
  • src/sort/either.rs
  • src/sort/fn.rs
  • src/sort/mod.rs
  • src/sort/pair.rs
  • src/typechecking.rs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: benchmark (ubuntu-latest, eggcc-2mm)
  • GitHub Check: benchmark (ubuntu-latest, rust_rule_match_overhead)
  • GitHub Check: benchmark (ubuntu-latest, proof_testing_eqsat-basic)
  • GitHub Check: benchmark (ubuntu-latest, typeinfer)
  • GitHub Check: benchmark (ubuntu-latest, taylor51)
  • GitHub Check: benchmark (ubuntu-latest, rust_rule_insert_loop)
  • GitHub Check: benchmark (ubuntu-latest, proof_testing_typecheck)
  • GitHub Check: benchmark (ubuntu-latest, conv1d_128)
  • GitHub Check: benchmark (ubuntu-latest, stresstest_large_expr)
  • GitHub Check: benchmark (ubuntu-latest, proof_testing_unify)
  • GitHub Check: benchmark (ubuntu-latest, cykjson)
  • GitHub Check: benchmark (ubuntu-latest, repro-665-set-union)
  • GitHub Check: benchmark (ubuntu-latest, luminal-llama)
  • GitHub Check: benchmark (ubuntu-latest, python_array_optimize)
  • GitHub Check: benchmark (ubuntu-latest, eggcc-extraction)
  • GitHub Check: benchmark (ubuntu-latest, herbie)
  • GitHub Check: benchmark (ubuntu-latest, math-microbenchmark)
  • GitHub Check: benchmark (ubuntu-latest, extract-vec-bench)
  • GitHub Check: test
  • GitHub Check: coverage
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{md,txt,rs}

📄 CodeRabbit inference engine (CLAUDE.md)

Keep documentation concise and avoid duplicate information

Files:

  • src/lib.rs
  • src/proofs/proof_normal_form.rs
  • src/prelude.rs
  • src/proofs/proof_encoding_helpers.rs
  • src/sort/fn.rs
  • src/sort/pair.rs
  • src/typechecking.rs
  • rfcs/001-proof-containers.md
  • src/sort/mod.rs
  • src/sort/either.rs
  • src/proofs/proof_encoding.rs
🧠 Learnings (1)
📚 Learning: 2026-05-31T20:06:45.343Z
Learnt from: saulshanabrook
Repo: egraphs-good/egglog PR: 881
File: src/exec_state.rs:114-129
Timestamp: 2026-05-31T20:06:45.343Z
Learning: In `src/exec_state.rs` (egglog crate, Rust), `Internal::apply_table_function` and related helpers deliberately gate authorization via `self.ctx()` (the stamped call-site context) rather than a per-wrapper capability type check. The potential capability escalation (a less-capable wrapper running under a wider Context invoking wider operations) is intentionally prevented by the experimental call site that prepares and registers primitives, not by a Rust type-level capability guard. The design decision is documented in the `Core::apply_primitive` and `Core::eval_resolved_expr` doc comments rather than enforced structurally. This is an accepted trade-off to keep the PR minimal.

Applied to files:

  • src/proofs/proof_normal_form.rs
🪛 LanguageTool
rfcs/001-proof-containers.md

[grammar] ~170-~170: Use a hyphen to join words.
Context: ...s. That would make projection and unwrap proof objects more explicit and would re...

(QB_NEW_EN_HYPHEN)

🔇 Additional comments (4)
rfcs/001-proof-containers.md (1)

1-220: LGTM!

src/sort/mod.rs (1)

22-73: LGTM!

Also applies to: 98-99, 141-145, 212-216

src/prelude.rs (1)

860-862: LGTM!

Also applies to: 927-929

src/typechecking.rs (1)

201-201: LGTM!

Also applies to: 606-608, 615-617, 1132-1137

Comment thread src/proofs/proof_encoding_helpers.rs Outdated
Comment thread src/proofs/proof_normal_form.rs
Comment thread src/sort/either.rs
Comment thread src/sort/pair.rs
@saulshanabrook saulshanabrook moved this to Waiting for Review in Saul Shanabrook Jun 8, 2026
@saulshanabrook

Copy link
Copy Markdown
Member Author

Closing for now. @oflatt suggested we dont want a partial solution that doesn't work for other containers, I aggree

@github-project-automation github-project-automation Bot moved this from Waiting for Review to Done in Saul Shanabrook Jun 19, 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.

1 participant