[−][src]Macro egg::rewrite
A macro to easily make Rewrite
s.
The rewrite!
macro greatly simplifies creating simple, purely
syntactic rewrites while also allowing more complex ones.
The simplest form rewrite!(a; b => c)
creates a Rewrite
with name a
, Searcher
b
, and Applier
c
.
Note that in the b
and c
position, the macro only accepts a single
token tree (see the [macros reference][macros] for more info).
In short, that means you should pass in an identifier, literal, or
something surrounded by parentheses or braces.
If you pass in a literal to the b
or c
position, the macro will
try to parse it as a Pattern
which implements both Searcher
and Applier
.
The macro also accepts any number of if <expr>
forms at the end,
where the given expression should implement Condition
.
For each of these, the macro will wrap the given applier in a
ConditionalApplier
with the given condition.
Example
define_language! { enum SimpleLanguage { Num(i32), "+" = Add([Id; 2]), "-" = Sub([Id; 2]), "*" = Mul([Id; 2]), "/" = Div([Id; 2]), } } type EGraph = egg::EGraph<SimpleLanguage, ()>; let rules: &[Rewrite<SimpleLanguage, ()>] = &[ rewrite!("commute-add"; "(+ ?a ?b)" => "(+ ?b ?a)"), rewrite!("commute-mul"; "(* ?a ?b)" => "(* ?b ?a)"), rewrite!("add-0"; "(+ ?a 0)" => "?a"), rewrite!("mul-0"; "(* ?a 0)" => "0"), rewrite!("mul-1"; "(* ?a 1)" => "?a"), rewrite!("silly"; "(* ?a 1)" => { MySillyApplier("foo") }), rewrite!("something_conditional"; "(/ ?a ?b)" => "(* ?a (/ 1 ?b))" if is_not_zero("?b")), ]; #[derive(Debug)] struct MySillyApplier(&'static str); impl Applier<SimpleLanguage, ()> for MySillyApplier { fn apply_one(&self, _: &mut EGraph, _: Id, _: &Subst) -> Vec<Id> { panic!() } } // This returns a function that implements Condition fn is_not_zero(var: &'static str) -> impl Fn(&mut EGraph, Id, &Subst) -> bool { let var = var.parse().unwrap(); let zero = SimpleLanguage::Num(0); move |egraph, _, subst| !egraph[subst[&var]].nodes.contains(&zero) }