-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding a way to see the parents of expressions - Help Needed! #282
Comments
I think the underlying problems are that our trees are immutable data structures and how Rusts ownership model gets in the way of trees in general. Doing this bidirectional "parent contains child which contains a pointer to the parent" seems to be annoying in Rust from as it basically turns things into a DAG and creates ownership problems. (https://github.com/SimonSapin/rust-forest, https://timidger.github.io/posts/designing-a-bi-mutable-directional-tree-safely-in-rust/). Then something like cursors, visitor pattern, etc to traverse the tree. To do this, Rc Refcells would be needed. However, we decided early on that we would do a functional / immutable tree instead and I think that has advantages in this case (eg handling backtracking). Our general solution to this was Uniplate - if it is a "all in one" recursive algorithm something like descend() or transform() would work, or for "one at a time" things there are Zippers, which would allow directly going up to the parent. |
Is this a tree traversal? |
If this is still a tree traversal, the parent could check the children and make itself dirty if any of the children are dirty? |
This is still a tree traversal but the issue with that would be if rules have a depth higher than one down. I don't know if any rules do have a further depth than that so you might be able to advise me. If that is the case then yeah looking at children would work but if grandchildren can affect grandparents then those would need to be checked etc. |
One thing i am not sure about is whether a clean to dirty change propagates all the way up the tree, or just changes the immediate parent? My understanding is that it should make all ancestors dirty, as those expressions have all changed in some way? That makes the recursion simpler as dirty just bubbles up all layers instead of just one (this would require some sort of "if we are directly above a node that has just had a rule applied to it" logic) Also, if the children of the current node are moved around by a rule, are they clean or dirty? For the rule stuff, CC @gskorokhod @ozgurakgun @lixitrixi |
I think dirty should go all the way up the tree. Also, I'd mark children dirty if they move -- in general it's safer to mark things as "dirty", as it just means rules and simplifications are applied to them (and, if things move around, they might now be candidates for that). I think Rust's immutablility helps with dealing with dirty. If you mark something as dirty, it means you have a mutable reference to it. That means whoever asked you to look at it is either going to put it in a new parent, or has a mutable reference to the parent (else how did they give you a mutable reference to the child?) Therefore you could introduce a rule (not sure it's possible to enforce this with code reasonably) that if you call "apply_all_rules" (or other methods which can make things dirty), then it's your job to check if it made it dirty, and if so pass the flag up to the parent. Can add a debug check which sweeps the whole tree every so often, and check if there is ever a dirty child with a clean parent, which means someone messed up! |
So I am currently trying to implement the clean/dirty optimisation which is explained briefly in this issue under "The rewrite function". I have implemented almost everything I need to get this working except I need some way to traverse back up the expressions to mark them as dirty. For context, the
apply_all_rules
function is the function that should mark nodes as dirty if there are rules to apply. I have made a mockmark_dirty
function which would work ifExpression
had some sort of parent attribute but this does not exist.There are quite a few ways this could be achieved but I am unsure what the best course of action is. If we were to add to the
Expression
itself then we would need to set each node's parent when creating the model. I don't know much about how the model is made, would this be simple? Alternatively, we could put this parent attribute within theMetadata
but this would also require us to set it somewhere and I am not sure exactly where I would be able to do this in the code.@ozgurakgun @ChrisJefferson @niklasdewally @lixitrixi @gskorokhod
If anybody has suggestions on the best course of action for this then please let me know as this is the last hurdle before the PR for this optimisation can be made. Thanks in advance!
The text was updated successfully, but these errors were encountered: