Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Note this assumes #291
I've noticed that
EGraphandEClassstruct's can be broken down into various parts that serve different purposes:Core egraph: (
EGraph.{unionfind, nodes, memo, pending, classes}, EClass.{id, parents})process_unions)EGraph.parentscould potentially be de-duplicated but this is never requiredBacktracking e-matching:
EGraph.classes_by_op, EClass.nodesEClass.nodesis maintained partially incrementallyrebuild_classesbefore e-matchingCustom Lattice Analysis:
EGraph.{analysis, analysis_pending}, EClass.dataN=()EGraph.analysis_pendingwhenAnalysis::mergealways returnsDidMerge(false, false)Explanations:
EGraph.explainOptioncausing slight overheadIdSymbolsI've started experimenting with trying to factor out the core egraph and use a new
Analysistrait (I renamed the old one toLatticeAnalysis) to handle everything else though so far the core egraph still includes explanations. ThisAnalysistrait is implemented for pairs ofAnalysiss to allow composing multiple together. I created to implementation of thisAnalysis, traitEMatchingAnalysiswhich containsclasses_by_opand hasEClass.nodesas its data field, andWrapLatticeAnalysisthat wraps aLatticeAnalysisto handleanalysis_pending.To handle methods that relied on a specific analysis like
set_analysis_dataorsearch_eclassI implemented them for egraphs with specific analysis instantiations, egEGraph<L, (WrapAnalysisData<N>, N2)>forset_analysis_dataorEGraph<L, (N, EMatchingAnalysis<L>)>forsearch_eclass, and I created the aliaslegacy::EGraph<L, N> = EGraph<L, (WrapAnalysisData<N>, EMatchingAnalysis<L>)>. While this has worked fine, for now, it seems like it will break down if users want to use these types of methods for multiple analyses at once, for example, if theexplain_equivalencerequired something likeEGraph<L, (ExplainAnalysis, N2)>then a user could call it andset_analysis_dataon the sameEGraph. I could have something like implementset_analysis_dataforEGraph<L, ((WrapAnalysisData<N> N2), N3)>and implementexplain_equivalenceforEGraph<L, ((N2, ExplainAnalysis), N3)>but this doesn't seem scalable.Other side effects of this change
EGraph::dot,EGraph::intersect, andExtractor::neware more expensive since they need to calculate the nodes in each eclass, andAnalysiss can't access the nodes of an eclass. This second change prevented the constant folding analysis from themathtest from removing nodes from eclasses representing constants which caused 4 of the tests to fail.I'm making this a draft PR so that you can view the exact changes I made but I am mostly interested in discussion