Skip to content

Migrate from egglog to apyds-egg support package - #8

Merged
hzhangxyz merged 3 commits into
mainfrom
copilot/use-apyds-egg-support-package
Dec 22, 2025
Merged

Migrate from egglog to apyds-egg support package#8
hzhangxyz merged 3 commits into
mainfrom
copilot/use-apyds-egg-support-package

Conversation

Copilot AI commented Dec 22, 2025

Copy link
Copy Markdown
Contributor

Replaces egglog with apyds-egg, the native E-Graph support package for the apyds deductive system.

Changes

pyproject.toml

  • Replace egglog~=12.0.0 dependency with apyds-egg~=0.0.11

ddss/egraph.py

  • Remove EGraphTerm class and custom term encoding logic (begin/pair pattern)
  • Direct apyds.Term to E-Graph mapping via add()
  • Explicit merge() + rebuild() for equality operations
  • find() for canonical E-class lookup
  • Fix get_equality() return type: Nonebool

Before/After

# Before: custom encoding, implicit operations
class EGraphTerm(egglog.Expr):
    def __init__(self, name: egglog.StringLike) -> None: ...
    @classmethod
    def begin(cls) -> EGraphTerm: ...
    @classmethod
    def pair(cls, lhs: EGraphTerm, rhs: EGraphTerm) -> EGraphTerm: ...

def _ast_from_term(self, data: Term) -> EGraphTerm:
    term = data.term
    if isinstance(term, List):
        result = EGraphTerm.begin()
        for i in range(len(term)):
            child = self._ast_from_term(term[i])
            result = EGraphTerm.pair(result, child)
        return result
    return EGraphTerm(str(term))

# After: direct term usage, explicit operations
def _get_or_add(self, data: str) -> EClassId:
    if data not in self.mapping:
        self.mapping[data] = self.core.add(Term(data))
    return self.mapping[data]

def set_equality(self, lhs: str, rhs: str) -> None:
    lhs_id = self._get_or_add(lhs)
    rhs_id = self._get_or_add(rhs)
    self.core.merge(lhs_id, rhs_id)
    self.core.rebuild()

Net -17 lines. No changes required to egg.py or Search class.

Original prompt

This section details on the original issue you should resolve

<issue_title>使用apyds的support package apyds-egg 而不是egglog.</issue_title>
<issue_description>apyds近期添加了一个支持库 apyds-egg , 现在我们可以使用他而不是egglog完成我们的 egg.py 和 egraph.py (主要是egraph.py)

下面是参考资料:

E-Graph Support Package for DS

An E-Graph (Equality Graph) implementation for the DS deductive system, providing efficient management and manipulation of equivalence classes of terms.

This package implements the egg-style E-Graph data structure with deferred congruence closure, enabling efficient equality reasoning. Inspired by the egg library.

Features

  • E-Graph Data Structure: Manage equivalence classes of terms efficiently
  • Union-Find: Path-compressed union-find for disjoint set management
  • Congruence Closure: Automatic maintenance of congruence relationships
  • Deferred Rebuilding: egg-style deferred rebuilding for performance
  • Python Integration: Seamless integration with apyds terms
  • Type-Safe: Full type hints for Python 3.11+

Installation

Python (pip)

pip install apyds-egg

Requires Python 3.11-3.14.

Quick Start

Python Example

import apyds
from apyds_egg import EGraph

# Create an E-Graph
eg = EGraph()

# Add terms to the E-Graph
a = eg.add(apyds.Term("a"))
b = eg.add(apyds.Term("b"))
x = eg.add(apyds.Term("x"))

# Add compound terms
ax = eg.add(apyds.Term("(+ a x)"))
bx = eg.add(apyds.Term("(+ b x)"))

# Initially, (+ a x) and (+ b x) are in different E-classes
assert eg.find(ax) != eg.find(bx)

# Merge a and b
eg.merge(a, b)

# Rebuild to restore congruence
eg.rebuild()

# Now (+ a x) and (+ b x) are in the same E-class
assert eg.find(ax) == eg.find(bx)

Core Concepts

E-Graph

An E-Graph is a data structure that efficiently represents and maintains equivalence classes of terms. It consists of:

  • E-Nodes: Nodes representing terms with an operator and children
  • E-classes: Equivalence classes of E-Nodes
  • Union-Find: Data structure for managing E-class equivalence
  • Congruence: Two terms are congruent if they have the same operator and their children are in equivalent E-classes

Congruence Closure

The E-Graph maintains congruence closure automatically. When two E-classes are merged, the E-Graph rebuilds to ensure that congruent terms remain in the same E-class:

eg = EGraph()

# Add terms
fa = eg.add(apyds.Term("(f a)"))
fb = eg.add(apyds.Term("(f b)"))

# Merge a and b
a = eg.add(apyds.Term("a"))
b = eg.add(apyds.Term("b"))
eg.merge(a, b)

# Rebuild maintains congruence
eg.rebuild()

# Now (f a) and (f b) are equivalent
assert eg.find(fa) == eg.find(fb)

API Overview

EGraph

  • __init__(): Create a new E-Graph
  • add(term: apyds.Term) -> EClassId: Add a term to the E-Graph
  • merge(a: EClassId, b: EClassId) -> EClassId: Merge two E-classes
  • rebuild() -> None: Restore congruence closure
  • find(eclass: EClassId) -> EClassId: Find canonical E-class representative

Building from Source

Prerequisites

  • Python 3.11-3.14
  • apyds package

Python Package

cd egg

# Install dependencies
uv sync --extra dev

# Build package
uv build

# Run tests
uv run pytest

# Run with coverage
uv run pytest --cov

License

This project is licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later).

Repository

Author

Hao Zhang hzhangxyz@outlook.com

Related

This package is a support library for the DS (Deductive System) project. For the main DS library with C++ core and bindings, see the main repository.
</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: hzhangxyz <11623447+hzhangxyz@users.noreply.github.com>
Copilot AI changed the title [WIP] Use apyds support package apyds-egg instead of egglog Migrate from egglog to apyds-egg support package Dec 22, 2025
Copilot AI requested a review from hzhangxyz December 22, 2025 12:07
@hzhangxyz
hzhangxyz marked this pull request as ready for review December 22, 2025 12:22
Copilot AI review requested due to automatic review settings December 22, 2025 12:22
@hzhangxyz
hzhangxyz merged commit 2b27c11 into main Dec 22, 2025
13 checks passed

Copilot AI 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.

Pull request overview

This PR successfully migrates the E-Graph implementation from the third-party egglog library to the native apyds-egg support package, simplifying the codebase and reducing dependencies.

Key changes:

  • Dependency migration: replaced egglog~=12.0.0 and cloudpickle~=3.1.2 with apyds-egg~=0.0.11
  • Removed custom EGraphTerm encoding class and begin/pair pattern in favor of direct apyds.Term usage
  • Explicit E-Graph operations: using add(), merge(), find(), and rebuild() methods directly

Reviewed changes

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

File Description
pyproject.toml Updated dependencies: replaced egglog and cloudpickle with apyds-egg, upgraded apyds packages to 0.0.11
uv.lock Dependency lock file updated to reflect new package versions and removed unused dependencies
ddss/egraph.py Removed EGraphTerm class; replaced with direct apyds.Term mapping; simplified API with explicit merge(), find(), and rebuild() calls; fixed get_equality() return type to bool
ddss/egg.py Renamed method call from build_pairs() to rebuild() to match updated API

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

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.

使用apyds的support package apyds-egg 而不是egglog.

3 participants