Skip to content

Commit

Permalink
Make sure metadata gets updated with congruence.
Browse files Browse the repository at this point in the history
  • Loading branch information
mwillsey committed Mar 2, 2020
1 parent ab12f48 commit 0de75c9
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

## [Unreleased] - ReleaseDate

### Changed
- **Fix:** An eclass's metadata will now get updated by
congruence. This unfortunately results in a little bit slower code,
but it's the right thing.

## [0.3.0] - 2020-02-27

### Added
Expand Down
2 changes: 1 addition & 1 deletion src/eclass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ assert_eq!(runner.egraph.find(runner.roots[0]), runner.egraph.find(just_foo));
[`math.rs`]: https://github.com/mwillsey/egg/blob/master/tests/math.rs
[`prop.rs`]: https://github.com/mwillsey/egg/blob/master/tests/prop.rs
*/
pub trait Metadata<L>: Sized + Debug {
pub trait Metadata<L>: Sized + Debug + PartialEq + Eq {
/// Unused for now, probably just make this `()`.
type Error: Debug;

Expand Down
20 changes: 19 additions & 1 deletion src/egraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ impl<L: Language, M: Metadata<L>> EGraph<L, M> {
fn rebuild_once(&mut self) -> usize {
let mut new_memo = IndexMap::new();
let mut to_union = Vec::new();
let mut new_metas = Vec::new();

for (leader, class) in self.classes.iter() {
for node in &class.nodes {
Expand All @@ -382,14 +383,26 @@ impl<L: Language, M: Metadata<L>> EGraph<L, M> {
}
}
}

let mut metas = class.nodes.iter().map(|n| M::make(self, n));
let first_meta = metas.next().expect("eclass shouldn't be empty");
let meta = metas.fold(first_meta, |m1, m2| m1.merge(&m2));
if meta != class.metadata {
new_metas.push((class.id, meta))
}
}

let n_unions = to_union.len();
for (id1, id2) in to_union {
self.union(id1, id2);
}

n_unions
let n_metas = new_metas.len();
for (id, meta) in new_metas {
self.classes.get_mut(id).metadata = meta;
}

n_unions + n_metas
}

fn rebuild_classes(&mut self) -> usize {
Expand Down Expand Up @@ -572,6 +585,11 @@ impl<L: Language, M: Metadata<L>> EGraph<L, M> {
warn!("Long time: {}, to do: {}", t, ids.len());
}

let mut metas = self[id].nodes.iter().map(|n| M::make(self, n));
let first_meta = metas.next().expect("eclass shouldn't be empty");
let meta = metas.fold(first_meta, |m1, m2| m1.merge(&m2));
self.classes.get_mut(id).metadata = meta;

let map = self[id]
.parents
.iter()
Expand Down
4 changes: 3 additions & 1 deletion src/rewrite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ where
///
/// // Our metadata in this case will be size of the smallest
/// // represented expression in the eclass.
/// #[derive(Debug)]
/// #[derive(Debug, Clone, PartialEq, Eq)]
/// struct Meta {
/// size: usize,
/// }
Expand Down Expand Up @@ -194,11 +194,13 @@ where
/// }}),
/// ];
///
/// #[derive(Debug, Clone, PartialEq, Eq)]
/// struct Funky {
/// a: Var,
/// b: Var,
/// c: Var,
/// }
///
/// impl Applier<Math, Meta> for Funky {
/// fn apply_one(&self, egraph: &mut EGraph, matched_id: Id, subst: &Subst) -> Vec<Id> {
/// let a: Id = subst[&self.a];
Expand Down
1 change: 1 addition & 0 deletions src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ where
// TODO check that we haven't
loop {
if let Err(stop_reason) = self.run_one(rules) {
info!("Stopping: {:?}", stop_reason);
self.stop_reason = Some(stop_reason);
break;
}
Expand Down
2 changes: 1 addition & 1 deletion tests/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl egg::CostFunction<Math> for MathCostFn {
}
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Meta {
pub cost: usize,
pub best: RecExpr<Math>,
Expand Down

0 comments on commit 0de75c9

Please sign in to comment.