-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
the main engine has been updated to make use of Uniplate's wonderful "contexts" method to abstract over and optimise the actual tree traversal. bump uniplate version update documentation
- Loading branch information
Showing
7 changed files
with
154 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
//! Here we test the `reduce_with_rule_groups` function. | ||
//! Each rule group is applied to the whole tree as with `reduce_with_rules`, before the next group is tried. | ||
//! Every time a change is made, the algorithm starts again with the first group. | ||
//! | ||
//! This lets us make powerful "evaluation" rules which greedily reduce the tree as much as possible, before other | ||
//! "rewriting" rules are applied. | ||
use tree_morph::{helpers::select_first, *}; | ||
use uniplate::derive::Uniplate; | ||
|
||
/// A simple language of two literals and a wrapper | ||
#[derive(Debug, Clone, PartialEq, Eq, Uniplate)] | ||
#[uniplate()] | ||
enum Expr { | ||
A, // a | ||
B, // b | ||
Wrap(Box<Expr>), // [E] | ||
} | ||
|
||
/// Rule container: holds a primitive function and implements the Rule trait | ||
struct Rl(fn(&Expr) -> Option<Expr>); | ||
|
||
impl Rule<Expr, ()> for Rl { | ||
fn apply(&self, cmd: &mut Commands<Expr, ()>, expr: &Expr, _: &()) -> Option<Expr> { | ||
self.0(expr) | ||
} | ||
} | ||
|
||
mod rules { | ||
use super::*; | ||
|
||
/// [a] ~> a | ||
pub fn unwrap_a(expr: &Expr) -> Option<Expr> { | ||
if let Expr::Wrap(inner) = expr { | ||
if let Expr::A = **inner { | ||
return Some(Expr::A); | ||
} | ||
} | ||
None | ||
} | ||
|
||
/// a ~> b | ||
pub fn a_to_b(expr: &Expr) -> Option<Expr> { | ||
if let Expr::A = expr { | ||
return Some(Expr::B); | ||
} | ||
None | ||
} | ||
} | ||
|
||
#[test] | ||
fn test_same_group() { | ||
// If the rules are in the same group, unwrap_a will apply higher in the tree | ||
|
||
// [a] | ||
let expr = Expr::Wrap(Box::new(Expr::A)); | ||
|
||
let (expr, _) = reduce_with_rule_groups( | ||
&[&[Rl(rules::unwrap_a), Rl(rules::a_to_b)]], | ||
select_first, | ||
expr, | ||
(), | ||
); | ||
|
||
// [a] ~> a ~> b | ||
assert_eq!(expr, Expr::B); | ||
} | ||
|
||
#[test] | ||
fn test_a_to_b_first() { | ||
// a_to_b is in a higher group than unwrap_a, so it will be applied first to the lower expression | ||
|
||
// [a] | ||
let expr = Expr::Wrap(Box::new(Expr::A)); | ||
|
||
let (expr, _) = reduce_with_rule_groups( | ||
&[&[Rl(rules::a_to_b)], &[Rl(rules::unwrap_a)]], | ||
select_first, | ||
expr, | ||
(), | ||
); | ||
|
||
// [a] ~> [b] | ||
assert_eq!(expr, Expr::Wrap(Box::new(Expr::B))); | ||
} |
Submodule vendor
updated
from d3aab5 to 1d007a