High Level: egglog
#
The top level module contains the high level API for using e-graphs in Python.
The high level API is not documented yet, because adding supporting for our custom objects requires a custom AutoDoc extension.
The high level API builds on the low level API and is designed to:
Statically type check as much as possible with MyPy
Be concise to write
Feel “pythonic”
Here is the same example using the high level API:
from __future__ import annotations
from egglog import *
egraph = EGraph()
@egraph.class_
class Math(Expr):
def __init__(self, value: i64Like) -> None:
...
@classmethod
def var(cls, v: StringLike) -> Math:
...
def __add__(self, other: Math) -> Math:
...
def __mul__(self, other: Math) -> Math:
...
# expr1 = 2 * (x + 3)
expr1 = egraph.let("expr1", Math(2) * (Math.var("x") + Math(3)))
# expr2 = 6 + 2 * x
expr2 = egraph.let("expr2", Math(6) + Math(2) * Math.var("x"))
a, b, c = vars_("a b c", Math)
x, y = vars_("x y", i64)
egraph.register(
rewrite(a + b).to(b + a),
rewrite(a * (b + c)).to((a * b) + (a * c)),
rewrite(Math(x) + Math(y)).to(Math(x + y)),
rewrite(Math(x) * Math(y)).to(Math(x * y)),
)
egraph.run(10)
egraph.check(eq(expr1).to(expr2))
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[1], line 7
3 from egglog import *
5 egraph = EGraph()
----> 7 @egraph.class_
8 class Math(Expr):
9 def __init__(self, value: i64Like) -> None:
10 ...
AttributeError: 'EGraph' object has no attribute 'class_'
Package for creating e-graphs in Python.
- class egglog.Action(__egg_decls__, action)#
Bases:
object
A change to an EGraph, either unioning multiple expressions, setting the value of a function call, deleting an expression, or panicing.
- Parameters:
__egg_decls__ (
Declarations
)action (
LetDecl
|SetDecl
|ExprActionDecl
|ChangeDecl
|UnionDecl
|PanicDecl
)
- exception egglog.BuiltinEvalError#
Bases:
Exception
Raised when an builtin cannot be evaluated into a Python primitive because it is complex.
Try extracting this expression first.
- class egglog.EGraph(seminaive=True, save_egglog_string=False, _state_stack=<factory>, _token_stack=<factory>)#
Bases:
object
A collection of expressions where each expression is part of a distinct equivalence class.
Can run actions, check facts, run schedules, or extract minimal cost expressions.
- Parameters:
- check(*facts)#
Check if a fact is true in the egraph.
- check_bool(*facts)#
Returns true if the facts are true in the egraph.
- check_fail(*facts)#
Checks that one of the facts is not true
- display(graphviz=False, **kwargs)#
Displays the e-graph.
If in IPython it will display it inline, otherwise it will write it to a file and open it.
- Parameters:
graphviz (
bool
)kwargs (
Unpack
[GraphvizKwargs
])
- Return type:
- extract(expr, include_cost=False)#
Extract the lowest cost expression from the egraph.
- extract_multiple(expr, n)#
Extract multiple expressions from the egraph.
- let(name, expr)#
Define a new expression in the egraph and return a reference to it.
- push()#
Push the current state of the egraph, so that it can be popped later and reverted back.
- Return type:
- register(command_or_generator, *command_likes)#
Registers any number of rewrites or rules.
- Parameters:
command_or_generator (
Action
|BaseExpr
|RewriteOrRule
|Callable
[...
,Iterable
[RewriteOrRule
]])command_likes (
Action
|BaseExpr
|RewriteOrRule
)
- Return type:
- run(limit_or_schedule, /, *until, ruleset=None)#
Run the egraph until the given limit or until the given facts are true.
- saturate(schedule=None, *, expr=None, max=1000, visualize=True, **kwargs)#
Saturate the egraph, running the given schedule until the egraph is saturated. It serializes the egraph at each step and returns a widget to visualize the egraph.
If an expr is passed, it’s also extracted after each run and printed
- class egglog.Fact(__egg_decls__, fact)#
Bases:
object
A query on an EGraph, either by an expression or an equivalence between multiple expressions.
- Parameters:
__egg_decls__ (
Declarations
)fact (
EqDecl
|ExprFactDecl
)
- class egglog.Ruleset(name, _current_egg_decls=<factory>, deferred_rule_gens=<factory>)#
Bases:
Schedule
A collection of rules, which can be run as a schedule.
- Parameters:
- _update_egg_decls()#
To return the egg decls, we go through our deferred rules and add any we haven’t yet
- Return type:
Declarations
- append(rule)#
Register a rule with the ruleset.
- Parameters:
rule (
RewriteOrRule
)- Return type:
- register(rule_or_generator, *rules, _increase_frame=False)#
Register rewrites or rules, either as a function or as values.
- Parameters:
rule_or_generator (
RewriteOrRule
|Callable
[...
,Iterable
[RewriteOrRule
]])rules (
RewriteOrRule
)_increase_frame (
bool
)
- Return type:
- class egglog.Schedule(__egg_decls_thunk__, schedule)#
Bases:
DelayedDeclerations
A composition of some rulesets, either composing them sequentially, running them repeatedly, running them till saturation, or running until some facts are met
- Parameters:
__egg_decls_thunk__ (
Callable
[[],Declarations
])schedule (
SaturateDecl
|RepeatDecl
|SequenceDecl
|RunDecl
)
- class egglog._EqBuilder(expr)#
Bases:
Generic
[BASE_EXPR
]- Parameters:
expr (
TypeVar
(BASE_EXPR
, bound= BaseExpr))
- class egglog._NeBuilder(lhs)#
Bases:
Generic
[BASE_EXPR
]- Parameters:
lhs (
TypeVar
(BASE_EXPR
, bound= BaseExpr))
- class egglog._SetBuilder(lhs)#
Bases:
Generic
[BASE_EXPR
]- Parameters:
lhs (
TypeVar
(BASE_EXPR
, bound= BaseExpr))
- egglog.birewrite(lhs, ruleset=None)#
Rewrite the given expression to a new expression and vice versa.
- Parameters:
- Return type:
_BirewriteBuilder
[TypeVar
(EXPR
, bound= Expr)]
- egglog.check(x, schedule=None, *given)#
Verifies that the fact is true given some assumptions and after running the schedule.
- egglog.check_eq(x, y, schedule=None, *, add_second=True, display=False)#
Verifies that two expressions are equal after running the schedule.
If add_second is true, then the second expression is added to the egraph before running the schedule.
- egglog.constant(name, tp, default_replacement=None, /, *, egg_name=None, ruleset=None)#
A “constant” is implemented as the instantiation of a value that takes no args. This creates a function with name and return type tp and returns a value of it being called.
- egglog.convert(source, target)#
Convert a source object to a target type.
- egglog.converter(from_type, to_type, fn, cost=1)#
Register a converter from some type to an egglog type.
- egglog.eq(expr)#
Check if the given expression is equal to the given value.
- Parameters:
expr (
TypeVar
(BASE_EXPR
, bound= BaseExpr))- Return type:
_EqBuilder
[TypeVar
(BASE_EXPR
, bound= BaseExpr)]
- egglog.expr_parts(expr)#
Returns the underlying type and decleration of the expression. Useful for testing structural equality or debugging.
- Parameters:
expr (
BaseExpr
)- Return type:
TypedExprDecl
- egglog.function(*args, **kwargs)#
Decorate a function typing stub to create an egglog function for it.
If a body is included, it will be added to the ruleset passed in as a default rewrite.
This will default to creating a “constructor” in egglog, unless a merge function is passed in or the return type is a primtive, then it will be a “function”.
- Return type:
- egglog.get_type_args()#
Get the type args for the type being converted.
- egglog.let(name, expr)#
Create a let binding.
- egglog.method(*, egg_fn=None, cost=None, merge=None, preserve=False, mutates_self=False, unextractable=False, subsume=False, reverse_args=False)#
Any method can be decorated with this to customize it’s behavior. This is only supported in classes which subclass
Expr
.
- egglog.ne(expr)#
Check if the given expression is not equal to the given value.
- Parameters:
expr (
TypeVar
(BASE_EXPR
, bound= BaseExpr))- Return type:
_NeBuilder
[TypeVar
(BASE_EXPR
, bound= BaseExpr)]
- egglog.panic(message)#
Raise an error with the given message.
- egglog.py_eval_fn(fn)#
Takes a python callable and maps it to a callable which takes and returns PyObjects.
It translates it to a call which uses py_eval to call the function, passing in the args as locals, and using the globals from function.
- Parameters:
fn (
Callable
)- Return type:
PyObjectFunction
- egglog.relation(name, /, *tps, egg_fn=None)#
Creates a function whose return type is Unit and has a default value.
- egglog.rewrite(lhs, ruleset=None, *, subsume=False)#
Rewrite the given expression to a new expression.
- Parameters:
- Return type:
_RewriteBuilder
[TypeVar
(EXPR
, bound= Expr)]
- egglog.rule(*facts, ruleset=None, name=None)#
Create a rule with the given facts.
- egglog.ruleset(rule_or_generator=None, *rules, name=None)#
Creates a ruleset with the following rules.
If no name is provided, try using the name of the funciton.
- Parameters:
rule_or_generator (
RewriteOrRule
|Callable
[...
,Iterable
[RewriteOrRule
]] |None
)rules (
RewriteOrRule
)
- Return type:
- egglog.run(ruleset=None, *until)#
Create a run configuration.
- egglog.seq(*schedules)#
Run a sequence of schedules.
- egglog.set_(lhs)#
Create a set of the given expression.
- Parameters:
lhs (
TypeVar
(BASE_EXPR
, bound= BaseExpr))- Return type:
_SetBuilder
[TypeVar
(BASE_EXPR
, bound= BaseExpr)]
- egglog.simplify(x, schedule=None)#
Simplify an expression by running the schedule.
- egglog.subsume(expr)#
Subsume an expression so it cannot be matched against or extracted
- egglog.union(lhs)#
Create a union of the given expression.
- Parameters:
lhs (
TypeVar
(EXPR
, bound= Expr))- Return type:
_UnionBuilder
[TypeVar
(EXPR
, bound= Expr)]
- egglog.unstable_combine_rulesets(*rulesets, name=None)#
Combine multiple rulesets into a single ruleset.
- egglog.var(name, bound)#
Create a new variable with the given name and type.