-
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
initial implementation of generic tree reduction library #344
base: main
Are you sure you want to change the base?
Conversation
crates/gen_reduce/src/lib.rs
Outdated
fn apply(&mut self, mut tree: T, mut meta: M) -> (T, M) { | ||
while let Some(cmd) = self.commands.pop_front() { | ||
match cmd { | ||
Command::Transform(f) => tree = f(&tree), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be changed to give ownership to the transforming function, since the main application in our case would be to put the tree into an And
and this requires ownership or cloning. If cloned, the original is discarded anyways so it will be unnecessary.
Hi @lixitrixi - as we discusssed earlier I am keen to try this. It would be good if you constructed a few examples, maybe as doctests, and I can give you a few more challenge test cases to test the kinds of features we will need. You can use the calculator language (with statements to be sure of the biplate behaviour) for the tests: https://crates.io/crates/uniplate |
We talked about this today during the drop in session and I encouraged people to bug you about adding that concrete example, or helping others add it. Consider yourself warned :) |
Absolutely! I will do this before our meeting tomorrow. |
having a generic tree rewriting library that builds on top of uniplate sounds like a good idea to me. but gen_reduce isn't the best name you will agree. have been thinking: spell? as in spellcasting. or alchemy, all about transformation? oh apparently grimoire means "A textbook of magic, typically including instructions on how to create magical objects" according to wikipedia. each rule can be a spell and the whole ruleset is a grimoire. I'll stop there... |
I finally can understand what this PR is about! Great documentation, @lixitrixi! |
Absolutely!!! I'll also be contributing a bit over reading week (not much to do on the plane). Would you be able to meet virtually tomorrow to split up some of the tasks? |
Hey! I'm not gonna be in St Andrews by tommorow afternoon. Can we do tommorow morning? (Like 9-10AM or 10-11AM) |
I like this direction :0 Unfortunately grimoire is taken... how about "thaum" for thaumaturgy? |
I won't veto thaum :) |
This is intended to be a possible project for the VIP!
The main idea is to abstract the reduction rule system into a powerful engine acting on generic Uniplate types. The main access point is the function
reduce
, which accepts a list of rules, a tree, and some metadata.Rules must support a function which, given some subtree and some persistent metadata, returns either a new subtree to replace the given one, or some error. Errors may simply mean "Not Applicable", or could even do some optimisation by pruning the entire subtree from the engine's traversal. Side effects such as adding top-level constraints and rewriting the metadata are contained in a Command Pattern, and are applied if and after the whole tree is rewritten with a rule's returned subtree.
Currently the library doesn't support what we need in Conjure Oxide: (1) rewrite selection and (2) dirty-clean optimisation. These might be implemented in the following ways:
(Iter<(Rule, SubTree)>) -> Option<SubTree>
or similar. The use of an iterator makes it more efficient by lazily evaluating rule reductions, but also opens up problems with how to deal with rules returning "Prune" or "Ignore" errors in the middle of the iteration. If a rule says to ignore the whole subtree, should we discard the user's choice of rewrite?