Skip to content

Commit eb5b548

Browse files
committed
Clarify id_to_expr and prevent copy_with_unions when explanations are disabled
1 parent a7423da commit eb5b548

File tree

1 file changed

+27
-5
lines changed

1 file changed

+27
-5
lines changed

src/egraph.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,9 @@ impl<L: Language, N: Analysis<L>> EGraph<L, N> {
217217

218218
/// Make a copy of the egraph with the same nodes, but no unions between them.
219219
pub fn copy_without_unions(&self, analysis: N) -> Self {
220+
if self.explain.is_none() {
221+
panic!("Use runner.with_explanations_enabled() or egraph.with_explanations_enabled() before running to get a copied egraph without unions");
222+
}
220223
let mut egraph = Self::new(analysis);
221224
for node in &self.nodes {
222225
egraph.add(node.clone());
@@ -638,7 +641,7 @@ impl<L: Language, N: Analysis<L>> EGraph<L, N> {
638641

639642
/// Similar to [`add_expr`](EGraph::add_expr) but the `Id` returned may not be canonical
640643
///
641-
/// Calling [`id_to_expr`](EGraph::id_to_expr) on this `Id` return a copy of `expr`
644+
/// Calling [`id_to_expr`](EGraph::id_to_expr) on this `Id` return a copy of `expr` when explanations are enabled
642645
pub fn add_expr_uncanonical(&mut self, expr: &RecExpr<L>) -> Id {
643646
let nodes = expr.as_ref();
644647
let mut new_ids = Vec::with_capacity(nodes.len());
@@ -676,7 +679,7 @@ impl<L: Language, N: Analysis<L>> EGraph<L, N> {
676679
/// canonical
677680
///
678681
/// Like [`add_uncanonical`](EGraph::add_uncanonical), when explanations are enabled calling
679-
/// Calling [`id_to_expr`](EGraph::id_to_expr) on this `Id` return an corrispond to the
682+
/// Calling [`id_to_expr`](EGraph::id_to_expr) on this `Id` return an correspond to the
680683
/// instantiation of the pattern
681684
fn add_instantiation_noncanonical(&mut self, pat: &PatternAst<L>, subst: &Subst) -> Id {
682685
let nodes = pat.as_ref();
@@ -796,7 +799,7 @@ impl<L: Language, N: Analysis<L>> EGraph<L, N> {
796799
/// When explanations are enabled calling [`id_to_expr`](EGraph::id_to_expr) on this `Id` will
797800
/// correspond to the parameter `enode`
798801
///
799-
/// # Example
802+
/// ## Example
800803
/// ```
801804
/// # use egg::*;
802805
/// let mut egraph: EGraph<SymbolLang, ()> = EGraph::default().with_explanations_enabled();
@@ -811,6 +814,25 @@ impl<L: Language, N: Analysis<L>> EGraph<L, N> {
811814
/// assert_eq!(egraph.id_to_expr(fa), "(f a)".parse().unwrap());
812815
/// assert_eq!(egraph.id_to_expr(fb), "(f b)".parse().unwrap());
813816
/// ```
817+
///
818+
/// When explanations are not enabled calling [`id_to_expr`](EGraph::id_to_expr) on this `Id` will
819+
/// produce an expression with equivalent but not necessarily identical children
820+
///
821+
/// # Example
822+
/// ```
823+
/// # use egg::*;
824+
/// let mut egraph: EGraph<SymbolLang, ()> = EGraph::default().with_explanations_disabled();
825+
/// let a = egraph.add_uncanonical(SymbolLang::leaf("a"));
826+
/// let b = egraph.add_uncanonical(SymbolLang::leaf("b"));
827+
/// egraph.union(a, b);
828+
/// egraph.rebuild();
829+
///
830+
/// let fa = egraph.add_uncanonical(SymbolLang::new("f", vec![a]));
831+
/// let fb = egraph.add_uncanonical(SymbolLang::new("f", vec![b]));
832+
///
833+
/// assert_eq!(egraph.id_to_expr(fa), "(f a)".parse().unwrap());
834+
/// assert_eq!(egraph.id_to_expr(fb), "(f a)".parse().unwrap());
835+
/// ```
814836
pub fn add_uncanonical(&mut self, mut enode: L) -> Id {
815837
let original = enode.clone();
816838
if let Some(existing_id) = self.lookup_internal(&mut enode) {
@@ -822,8 +844,8 @@ impl<L: Language, N: Analysis<L>> EGraph<L, N> {
822844
} else {
823845
let new_id = self.unionfind.make_set();
824846
explain.add(original.clone(), new_id, new_id);
825-
self.nodes.push(original);
826847
debug_assert_eq!(Id::from(self.nodes.len()), new_id);
848+
self.nodes.push(original);
827849
self.unionfind.union(id, new_id);
828850
explain.union(existing_id, new_id, Justification::Congruence, true);
829851
new_id
@@ -855,8 +877,8 @@ impl<L: Language, N: Analysis<L>> EGraph<L, N> {
855877
parents: Default::default(),
856878
};
857879

858-
self.nodes.push(original);
859880
debug_assert_eq!(Id::from(self.nodes.len()), id);
881+
self.nodes.push(original);
860882

861883
// add this enode to the parent lists of its children
862884
enode.for_each(|child| {

0 commit comments

Comments
 (0)