Skip to content

Fix lookup of value in cost model#401

Merged
saulshanabrook merged 2 commits intomainfrom
fix-cost-function
Mar 3, 2026
Merged

Fix lookup of value in cost model#401
saulshanabrook merged 2 commits intomainfrom
fix-cost-function

Conversation

@saulshanabrook
Copy link
Member

No description provided.

Copilot AI review requested due to automatic review settings March 3, 2026 22:02
@saulshanabrook saulshanabrook enabled auto-merge March 3, 2026 22:02
@saulshanabrook
Copy link
Member Author

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Mar 3, 2026

✅ Actions performed

Full review triggered.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a bug where custom extraction cost models (and related APIs like lookup_function_value) could fail when operating on subexpressions represented as already-interned egglog values.

Changes:

  • Fix typed_expr_to_value to directly return the underlying bindings.Value for ValueDecl instead of attempting to translate/evaluate it.
  • Add a regression test covering cost-model lookup of function values on subtree values.
  • Document the fix in the changelog.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
python/tests/test_high_level.py Adds regression test exercising lookup_function_value inside a custom cost model when subtree args are ValueDecls.
python/egglog/egraph_state.py Fixes conversion of TypedExprDecl to bindings.Value by special-casing ValueDecl.
docs/changelog.md Adds an UNRELEASED changelog entry for the fix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coderabbitai
Copy link

coderabbitai bot commented Mar 3, 2026

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Fixed cost model lookup based on value

Walkthrough

These changes enhance the cost model evaluation system with a performance optimization and test coverage. The egraph_state module now short-circuits ValueDecl expression evaluation, a changelog entry documents a cost model lookup fix, and a new test validates custom cost model functionality with expression subtree inspection.

Changes

Cohort / File(s) Summary
Cost Model Optimization
python/egglog/egraph_state.py
Enhanced typed_expr_to_value to short-circuit when input is already a ValueDecl, returning the underlying value directly and bypassing standard egg evaluation for such cases.
Test Coverage & Documentation
python/tests/test_high_level.py, docs/changelog.md
Added test_custom_cost_model_size to validate custom cost models that inspect KAT expression subtrees and aggregate costs. Changelog entry documents the cost model lookup fix.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.22% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to evaluate whether the description relates to the changeset. Add a description explaining the fix for value lookup in the cost model, what problem it solves, and why the changes in typed_expr_to_value and the new test are necessary.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix lookup of value in cost model' clearly and specifically summarizes the main change in the changeset, which involves enhancing typed_expr_to_value to properly handle ValueDecl lookups and adding a test for the custom cost model.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-cost-function

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@python/egglog/egraph_state.py`:
- Around line 686-687: The isinstance check uses ValueDecl but ValueDecl is only
coming from a star import, causing Ruff F405; update the module imports to
explicitly import ValueDecl (add ValueDecl to the from ... import (...) list
where other AST/decl types are imported) so the isinstance(typed_expr.expr,
ValueDecl) line in egraph_state (around the check on typed_expr.expr) resolves
without a star import warning.

In `@python/tests/test_high_level.py`:
- Around line 1597-1600: The conv_cost function must guard against
get_callable_args returning None and avoid the unused-argument warning for
child_costs: update conv_cost (handling KAT) to call get_callable_args(expr),
treat a None result as an empty sequence before iterating (e.g., if args is
None: args = ()), and explicitly mark child_costs as intentionally unused (for
example by assigning it to _ or using del child_costs) so linters stop warning;
keep the existing sum over cast("KAT", a).size() for each arg.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a19aa86 and b18d3e7.

📒 Files selected for processing (3)
  • docs/changelog.md
  • python/egglog/egraph_state.py
  • python/tests/test_high_level.py
📜 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). (9)
  • GitHub Check: Agent
  • GitHub Check: benchmark (ubuntu-latest)
  • GitHub Check: benchmark (codspeed-macro)
  • GitHub Check: docs
  • GitHub Check: build linux (aarch64)
  • GitHub Check: build linux (ppc64)
  • GitHub Check: build linux
  • GitHub Check: build macos
  • GitHub Check: build windows
🧰 Additional context used
🧬 Code graph analysis (2)
python/tests/test_high_level.py (4)
python/egglog/bindings.pyi (1)
  • size (744-744)
src/termdag.rs (1)
  • size (18-20)
python/egglog/examples/jointree.py (1)
  • size (24-24)
python/egglog/deconstruct.py (3)
  • get_callable_args (117-117)
  • get_callable_args (121-121)
  • get_callable_args (124-153)
python/egglog/egraph_state.py (1)
python/egglog/declarations.py (1)
  • ValueDecl (727-728)
🪛 Ruff (0.15.2)
python/tests/test_high_level.py

[error] 1578-1578: Expr may be undefined, or defined from star imports

(F405)


[error] 1587-1587: i64 may be undefined, or defined from star imports

(F405)


[error] 1591-1591: EGraph may be undefined, or defined from star imports

(F405)


[error] 1594-1594: set_ may be undefined, or defined from star imports

(F405)


[error] 1595-1595: set_ may be undefined, or defined from star imports

(F405)


[warning] 1597-1597: Unused function argument: child_costs

(ARG001)


[error] 1599-1599: get_callable_args may be undefined, or defined from star imports

(F405)

python/egglog/egraph_state.py

[error] 686-686: ValueDecl may be undefined, or defined from star imports

(F405)

🔇 Additional comments (1)
docs/changelog.md (1)

16-16: Changelog entry is clear and appropriately scoped.

The new UNRELEASED note accurately captures the behavior fix and links to discussion context.

Comment on lines +686 to +687
if isinstance(typed_expr.expr, ValueDecl):
return typed_expr.expr.value
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
ruff check python/egglog/egraph_state.py --select F405
rg -n "from \.declarations import" python/egglog/egraph_state.py

Repository: egraphs-good/egglog-python

Length of output: 50383


🏁 Script executed:

#!/bin/bash
# Check lines 686-687 and surrounding context
sed -n '680,695p' python/egglog/egraph_state.py | cat -n

# Check the declarations import specifically
rg -n "^from \.declarations import|^from \.declarations import.*ValueDecl|^from \*" python/egglog/egraph_state.py | head -20

Repository: egraphs-good/egglog-python

Length of output: 888


🏁 Script executed:

#!/bin/bash
# Check exact import line and context
sed -n '15,20p' python/egglog/egraph_state.py | cat -n

# Run Ruff check focused on the region around lines 686-687
ruff check python/egglog/egraph_state.py --select F405 2>&1 | grep -A2 -B2 "686\|687"

Repository: egraphs-good/egglog-python

Length of output: 1176


Add explicit import of ValueDecl to fix Ruff F405.

The new isinstance(typed_expr.expr, ValueDecl) check at line 686 triggers Ruff F405 since ValueDecl is only available through the star import. Add it to the explicit imports to keep the codebase lint-clean.

Suggested patch
-from .declarations import ConstructorDecl
+from .declarations import ConstructorDecl, ValueDecl
🧰 Tools
🪛 Ruff (0.15.2)

[error] 686-686: ValueDecl may be undefined, or defined from star imports

(F405)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@python/egglog/egraph_state.py` around lines 686 - 687, The isinstance check
uses ValueDecl but ValueDecl is only coming from a star import, causing Ruff
F405; update the module imports to explicitly import ValueDecl (add ValueDecl to
the from ... import (...) list where other AST/decl types are imported) so the
isinstance(typed_expr.expr, ValueDecl) line in egraph_state (around the check on
typed_expr.expr) resolves without a star import warning.

Comment on lines +1597 to +1600
def conv_cost(eg, expr, child_costs):
if isinstance(expr, KAT):
args = get_callable_args(expr)
return sum(int(eg.lookup_function_value(cast("KAT", a).size())) for a in args)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for linting issues and find get_callable_args definition
ruff check python/tests/test_high_level.py --select ARG001,F405
echo "---"
rg -n "def get_callable_args|from \.deconstruct import get_callable_args|__all__" python/egglog/deconstruct.py python/egglog/__init__.py

Repository: egraphs-good/egglog-python

Length of output: 50383


🏁 Script executed:

#!/bin/bash
# Read the full function and surrounding context
sed -n '1590,1610p' python/tests/test_high_level.py

Repository: egraphs-good/egglog-python

Length of output: 542


🏁 Script executed:

#!/bin/bash
# Find the definition of get_callable_args to check return type
rg -A 10 "^def get_callable_args" python/egglog/

Repository: egraphs-good/egglog-python

Length of output: 1276


Harden conv_cost against None args and silence unused-arg warning.

get_callable_args can return None; iterating that would raise TypeError. Also, child_costs is intentionally unused here.

Suggested patch
-def conv_cost(eg, expr, child_costs):
+def conv_cost(eg, expr, _child_costs):
     if isinstance(expr, KAT):
-        args = get_callable_args(expr)
+        args = get_callable_args(expr) or ()
         return sum(int(eg.lookup_function_value(cast("KAT", a).size())) for a in args)
🧰 Tools
🪛 Ruff (0.15.2)

[warning] 1597-1597: Unused function argument: child_costs

(ARG001)


[error] 1599-1599: get_callable_args may be undefined, or defined from star imports

(F405)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@python/tests/test_high_level.py` around lines 1597 - 1600, The conv_cost
function must guard against get_callable_args returning None and avoid the
unused-argument warning for child_costs: update conv_cost (handling KAT) to call
get_callable_args(expr), treat a None result as an empty sequence before
iterating (e.g., if args is None: args = ()), and explicitly mark child_costs as
intentionally unused (for example by assigning it to _ or using del child_costs)
so linters stop warning; keep the existing sum over cast("KAT", a).size() for
each arg.

@saulshanabrook saulshanabrook disabled auto-merge March 3, 2026 22:15
@saulshanabrook saulshanabrook merged commit 89d0d82 into main Mar 3, 2026
18 of 21 checks passed
@saulshanabrook saulshanabrook deleted the fix-cost-function branch March 3, 2026 22:15
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