type Strategy[P] = P => RewriteResult[P]
RewriteResult[P] = Success[P](P)
| Failure[P](Strategy[P])
type Traversal[P] = Strategy[P] => Strategy[P]
def ‘@‘[P](s: Strategy[P], t: Traversal[P]) = t(s)
def outermost: Strategy[Rise] => Traversal[Rise] =
pred => s => topDown(pred ‘;‘ s)
// tiling 32x32, nest level 2 in ELEVATE
(tile(32,32) ‘@‘ outermost(mapNest(2)))(mm)
QF-EUF: quantifier-free equality with uninterpreted functions
An e-graph is a tuple
add: takes an e-node, (insert an e-class if not exist)merge: unions two e-class ids;find: canonicalizes e-class id with union-find;ematch: performs e-matching for finding patterns in the e-graph.for e-class c in e-graph E:
for f-node n1 in c:
subst = {root ↦ c, α ↦ n1.child1}
for g-node n2 in n1.child2:
if subst[α] = n2.child1:
yield subst
ematch merge(add((Div (Mul a two) two)
(Div (Shl a (Num 1)) two)
; (Div (Mul a two) two) still exists
def equality_saturation(expr, rewrites):
egraph = initial_egraph(expr)
while not egraph.is_saturated_or_timeout():
for rw in rewrites:
for (subst, eclass) in egraph.ematch(rw.lhs):
eclass2 = egraph.add(rw.rhs.subst(subst))
egraph.merge(eclass, eclass2)
return egraph.extract_best()
(rewrite (Mul a two)
(Shl a (Num 1)))
(rewrite (Div (Mul %x %y) %z)
(Mul %x (Div %y %z)))
(rewrite (Div %x %x) one)
(rewrite (Mul %x one) %x)
(extract (Div (Mul a two) two))
; outputs:
; (Var "a")
first general-purpose, reusable implementation of e-graphs and equality saturation
MAKES E-GRAPH GREAT AGAIN
What's new?
Herbie uses e-graphs for algebraic simplification of mathematical expressions
The egg backend is over 3000× faster than Herbie’s initial simplifier
Find and fix floating-point problems:
sqrt(x+1) - sqrt(x)
-> 1/(sqrt(x+1) + sqrt(x))
accuracy: 53.1% -> 99.7%
Abstract domain:
Constraint? Context!
Colored e-graph
The target e-class represents
which one to extract?
pick the smallest (cheapest) one
Variables:
Objective:
Constraints:
for each child
Intuition:
when treewidth is small, every bag is small,
and we can enumerate extraction within each bag;
and thanks to the cut property,
we can conduct dynamic programming over bags.

But, decomposition is slow!
E-GRAPH REWRITING FOR LOGIC SYNTHESIS
Phase ordering problem is SEVERE! CF is HARD!
- Strategies encode program transformations - Rewrite rules are strategies - Strategies as compositions - Use traversals to describe at which exact location a strategy is applied
Suppose $\mathcal{A}[x]=[-3,3]$, then $\mathcal{A}[\texttt{ASSUME}(x,x>0)]=[1,3]$

[Babble](https://dl.acm.org/doi/10.1145/3571207): library learning modulo theories
### What we need? > instruction finding from domain of applications - program rewrites: [eggcc](https://github.com/egraphs-good/eggcc)? [jlm](https://github.com/phate/jlm)? what else? - tractable EqSat: - pruning ([Isaria](https://dl.acm.org/doi/10.1145/3617232.3624873))? guiding ([egg-sketch](https://dl.acm.org/doi/10.1145/3632900))? - learn instruction: - what to learn? acceptable instr.? cost model? - how to learn? [Babble](https://dl.acm.org/doi/10.1145/3571207)? - more efficient extraction?