Function rule

Source
pub fn rule(
    egraph: &mut EGraph,
    ruleset: &str,
    facts: Facts<String, String>,
    actions: Actions,
) -> Result<Vec<CommandOutput>, Error>
Expand description

Add a rule to the e-graph whose right-hand side is made up of actions.

use egglog::prelude::*;

let mut egraph = EGraph::default();
egraph.parse_and_run_program(
    None,
    "
(function fib (i64) i64 :no-merge)
(set (fib 0) 0)
(set (fib 1) 1)
(rule (
    (= f0 (fib x))
    (= f1 (fib (+ x 1)))
) (
    (set (fib (+ x 2)) (+ f0 f1))
))
(run 10)
    ",
)?;

let big_number = 20;

// check that `(fib 20)` is not in the e-graph
let results = query(
    &mut egraph,
    vars![f: i64],
    facts![(= (fib (unquote exprs::int(big_number))) f)],
)?;

assert!(results.iter().next().is_none());

let ruleset = "custom_ruleset";
add_ruleset(&mut egraph, ruleset)?;

// add the rule from `build_test_database` to the egraph
rule(
    &mut egraph,
    ruleset,
    facts![
        (= f0 (fib x))
        (= f1 (fib (+ x 1)))
    ],
    actions![
        (set (fib (+ x 2)) (+ f0 f1))
    ],
)?;

// run that rule 10 times
for _ in 0..10 {
    run_ruleset(&mut egraph, ruleset)?;
}

// check that `(fib 20)` is now in the e-graph
let results = query(
    &mut egraph,
    vars![f: i64],
    facts![(= (fib (unquote exprs::int(big_number))) f)],
)?;

let y = egraph.base_to_value::<i64>(6765);
let results: Vec<_> = results.iter().collect();
assert_eq!(results, [[y]]);