diff --git a/src/egraph.rs b/src/egraph.rs index 39d0d368..429d572e 100644 --- a/src/egraph.rs +++ b/src/egraph.rs @@ -72,6 +72,13 @@ pub struct EGraph> { #[cfg_attr(feature = "serde-1", serde(skip))] #[cfg_attr(feature = "serde-1", serde(default = "default_classes_by_op"))] pub(crate) classes_by_op: HashMap, HashSet>, + /// Whether or not reading operation are allowed on this e-graph. + /// Mutating operations will set this to `false`, and + /// [`EGraph::rebuild`] will set it to true. + /// Reading operations require this to be `true`. + /// Only manually set it if you know what you're doing. + #[cfg_attr(feature = "serde-1", serde(skip))] + pub clean: bool, } #[cfg(feature = "serde-1")] @@ -103,6 +110,7 @@ impl> EGraph { to_union: Default::default(), classes: Default::default(), unionfind: Default::default(), + clean: false, explain: None, pending: Default::default(), memo: Default::default(), @@ -408,6 +416,8 @@ impl> EGraph { assert!(self.memo.insert(enode, id).is_none()); N::modify(self, id); + + self.clean = false; id }) } @@ -470,6 +480,7 @@ impl> EGraph { subst: &Subst, rule_name: impl Into, ) -> bool { + self.clean = false; if let Some(explain) = &mut self.explain { if self.unionfind.find_mut(id1) == self.unionfind.find_mut(id2) { false @@ -504,6 +515,7 @@ impl> EGraph { /// You must call [`rebuild`](EGraph::rebuild) to observe any effect. /// pub fn union(&mut self, id1: Id, id2: Id) -> bool { + self.clean = false; if self.explain.is_some() { panic!("Use union_instantiations when explanation mode is enabled."); } @@ -757,6 +769,8 @@ impl> EGraph { /// invariants before any query operations, otherwise the results /// may be stale or incorrect. /// + /// This will set [`EGraph::clean`] to `true`. + /// /// # Example /// ``` /// use egg::{*, SymbolLang as S}; @@ -808,6 +822,7 @@ impl> EGraph { ); debug_assert!(self.check_memo()); + self.clean = true; n_unions } diff --git a/src/machine.rs b/src/machine.rs index 739956e7..df66ff3f 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -307,6 +307,7 @@ impl Program { { let mut machine = Machine::default(); + assert!(egraph.clean, "Tried to search a dirty e-graph!"); assert_eq!(machine.reg.len(), 0); for expr in &self.ground_terms { if let Some(id) = egraph.lookup_expr(&expr.clone()) {