-
Notifications
You must be signed in to change notification settings - Fork 0
Add documentation for egg subpackage #159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3e0c879
d1b62cc
837a2bf
2ca7157
325eb2f
c2c9475
de8116b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,123 @@ | ||||||
| # E-Graph Support Package | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个文件依然没有检查, 请对照对readme的评论
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated docs/support-packages/egg.md with the same "Inspired by" wording in de8116b. The file already had all the simplifications from the README (no Union-Find/E-Nodes sections in Core Concepts, no UnionFind/ENode/EClassId in API Reference). |
||||||
|
|
||||||
| The E-Graph support package provides efficient management and manipulation of equivalence classes of terms for the DS deductive system. | ||||||
|
|
||||||
| An E-Graph (Equality Graph) is a data structure that efficiently represents equivalence classes of terms and automatically maintains congruence closure. This implementation follows the egg-style approach with deferred rebuilding for optimal performance. Inspired by the [egg library](https://egraphs-good.github.io/). | ||||||
|
|
||||||
| ## Installation | ||||||
|
|
||||||
| ### Python | ||||||
|
|
||||||
| ```bash | ||||||
| pip install apyds-egg | ||||||
| ``` | ||||||
|
|
||||||
| Requires Python 3.11-3.14. | ||||||
|
|
||||||
| ## Usage | ||||||
|
|
||||||
| ### Basic Example | ||||||
|
|
||||||
| ```python | ||||||
| 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) | ||||||
| ``` | ||||||
|
|
||||||
| ### Congruence Closure | ||||||
|
|
||||||
| The E-Graph automatically maintains congruence closure. When two E-classes are merged, the `rebuild()` method ensures that all congruent terms remain in the same E-class: | ||||||
|
|
||||||
| ```python | ||||||
| eg = EGraph() | ||||||
|
|
||||||
| # Add terms with nested structure | ||||||
| fa = eg.add(apyds.Term("(f a)")) | ||||||
| fb = eg.add(apyds.Term("(f b)")) | ||||||
| gfa = eg.add(apyds.Term("(g (f a))")) | ||||||
| gfb = eg.add(apyds.Term("(g (f b))")) | ||||||
|
|
||||||
| # Merge a and b | ||||||
| a = eg.add(apyds.Term("a")) | ||||||
| b = eg.add(apyds.Term("b")) | ||||||
| eg.merge(a, b) | ||||||
|
|
||||||
| # Rebuild propagates equivalence | ||||||
| eg.rebuild() | ||||||
|
|
||||||
| # Now all derived terms are equivalent | ||||||
| assert eg.find(fa) == eg.find(fb) | ||||||
| assert eg.find(gfa) == eg.find(gfb) | ||||||
| ``` | ||||||
|
|
||||||
| ## Core Concepts | ||||||
|
|
||||||
| ### E-Graph Structure | ||||||
|
|
||||||
| An E-Graph consists of several key components: | ||||||
|
|
||||||
| - **E-Nodes**: Represent terms with an operator and children | ||||||
| - **E-classes**: Equivalence classes of E-Nodes | ||||||
| - **Hash-consing (Hashcons)**: Ensures uniqueness of E-Nodes by mapping identical nodes to the same E-class | ||||||
| - **Union-Find**: Manages E-class equivalence relationships | ||||||
| - **Parents**: Tracks which terms depend on each E-class | ||||||
| - **Worklist**: Manages deferred congruence rebuilding | ||||||
|
|
||||||
| ### Deferred Rebuilding | ||||||
|
|
||||||
| The implementation uses egg-style deferred rebuilding: | ||||||
|
|
||||||
| 1. **Merge**: Combine two E-classes and add to worklist | ||||||
| 2. **Rebuild**: Process worklist to restore congruence | ||||||
| 3. **Repair**: Re-canonicalize parent nodes and merge congruent ones | ||||||
|
|
||||||
| This approach provides better performance than immediate rebuilding by batching congruence updates. | ||||||
|
|
||||||
| ### Adding Terms | ||||||
|
|
||||||
| Terms are converted to E-Nodes and added to the E-Graph: | ||||||
|
|
||||||
| - **Items (constants/functors) and Variables**: Atomic terms like `a`, `b`, or backtick-prefixed variables like `x` are represented as E-Nodes with no children | ||||||
|
||||||
| - **Items (constants/functors) and Variables**: Atomic terms like `a`, `b`, or backtick-prefixed variables like `x` are represented as E-Nodes with no children | |
| - **Items (constants/functors) and Variables**: Atomic terms like `a`, `b`, or backtick-prefixed variables like `` `x `` are represented as E-Nodes with no children |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| # 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](https://egraphs-good.github.io/). | ||
|
|
||
| ## 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) | ||
|
|
||
| ```bash | ||
| pip install apyds-egg | ||
| ``` | ||
|
|
||
| Requires Python 3.11-3.14. | ||
|
|
||
| ## Quick Start | ||
|
|
||
| ### Python Example | ||
|
|
||
| ```python | ||
| 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: | ||
|
|
||
| ```python | ||
| 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 | ||
|
|
||
| ```bash | ||
| 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 | ||
|
|
||
| - **GitHub**: [USTC-KnowledgeComputingLab/ds](https://github.com/USTC-KnowledgeComputingLab/ds) (in `/egg` directory) | ||
| - **Python Package**: [apyds-egg](https://pypi.org/project/apyds-egg/) | ||
|
|
||
| ## Author | ||
|
|
||
| Hao Zhang <hzhangxyz@outlook.com> | ||
|
|
||
| ## Related | ||
|
|
||
| This package is a support library for the [DS (Deductive System)](https://github.com/USTC-KnowledgeComputingLab/ds) project. For the main DS library with C++ core and bindings, see the [main repository](https://github.com/USTC-KnowledgeComputingLab/ds). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个文件还没检查, 但是参考我对README的评论先修改一版
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Applied similar changes to docs/support-packages/egg.md in c2c9475: removed Union-Find example, removed UnionFind/ENode/EClassId API sections, and added egg library reference.