///|
pub struct Applier {
apply : (EGraph, Map[String, Id]) -> Id raise
}
///|
pub fn Applier::apply(
self : Applier,
egraph : EGraph,
subst : Map[String, Id],
) -> Id raise {
(self.apply)(egraph, subst)
}
///|
pub fn Applier::pattern(rhs : Pattern) -> Applier {
Applier::{ apply: (egraph, subst) => build_rhs(rhs, egraph, subst) }
}
///|
pub fn Applier::from_fn(f : (EGraph, Map[String, Id]) -> Id raise) -> Applier {
Applier::{ apply: f }
}
///|
pub fn build_rhs(
pat : Pattern,
egraph : EGraph,
subst : Map[String, Id],
) -> Id raise {
match pat {
Pattern::Var(name) | Pattern::VarIf(name, _) =>
match subst.get(name) {
Some(id) => egraph.find(id)
None => fail("missing variable in substitution")
}
Pattern::Sym(name) => egraph.add(make_symbol(name))
Pattern::Num(n) => egraph.add(make_number(n))
Pattern::Wild => fail("wildcard not allowed on RHS")
Pattern::Node(op, children) => {
let child_ids : Array[Id] = Array::new()
for child_pat in children {
child_ids.push(build_rhs(child_pat, egraph, subst.copy()))
}
egraph.add(make_enode(op, child_ids))
}
}
}