Conversation
…and `analysis_pending`
|
Just so I understand; this is not a user facing change? The goal is to implement various egg internals using a more flexible analysis API, right? |
|
Unfortunately, the old |
|
I see. I think this is a cool idea, and could be the right thing going forward. I would hope that it would result in code reduction rather and growth, but maybe that's asking for too much. In general, I'm pretty hesitant (but not totally unwilling) to break the user-facing API at this point unless there is some demonstrable need. Most of the egg maintainers (including me) are spending more time on other projects at the moment. But don't let that stop you from experimenting or working on a fork! |
|
@robert-chiniquy I heard that you were working on a fork of |
|
Oh, heh, sorry, I'm absolutely not going to work on a fork, I'm just going to use my own hacked fork until something equivalent to my latest PR lands (this is how I avoid waiting). |
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