# HG changeset patch # User Steve Losh # Date 1467310531 0 # Node ID 0518a14633409072792f90f4cc32a3ed87a268f5 # Parent bb6e33f59c76e58221ed11407c616826ec63edad Update diff -r bb6e33f59c76 -r 0518a1463340 README.markdown --- a/README.markdown Thu Jun 30 18:13:49 2016 +0000 +++ b/README.markdown Thu Jun 30 18:15:31 2016 +0000 @@ -257,42 +257,45 @@ should be trivial for all GDL games. It is *really* tedious to do by hand though, so I really want to write a GDL to Bones translator. But to do that I think I need to sort out the `assert`/`retract` situation. -* I've been thinking about the best way to implement the rule - assertion/retraction UI in Bones and I have a few ideas. The current stopgap - UI of "all the parts of a predicate need to be defined in a single `(rules - ...)` call" is *really* awful to work with. + +### Assertion and Retraction in [Bones][] + +I've been thinking about the best way to implement the rule assertion/retraction +UI in Bones and I have a few ideas. The current stopgap UI of "all the parts of +a predicate need to be defined in a single `(rules ...)` call" is *really* awful +to work with. - There are a few ways I could solidify this. One way would be to delay - compilation of all the predicates until you call a top-level `(compile)`, at - which point all the predicates would be compiled and fixed forever. This - would let you split apart the rules, but not assert/retract things at runtime - without rebuilding the entire WAM, which is kind of shitty. +There are a few ways I could solidify this. One way would be to delay +compilation of all the predicates until you call a top-level `(compile)`, at +which point all the predicates would be compiled and fixed forever. This +would let you split apart the rules, but not assert/retract things at runtime +without rebuilding the entire WAM, which is kind of shitty. - On the other end, I could implement full dynamic assertion/retraction. This - would be the most flexible, but has drawbacks. There would probably be a lot - of wasted compilation: if you do `(fact (foo 1)) (fact (bar 2)) (fact (baz - 3))` it would compile `foo` three times, throwing the first two away. I'd - also need to implement a garbage collection algorithm for the code store, - which seems like a lot of work and a large cost at runtime. +On the other end, I could implement full dynamic assertion/retraction. This +would be the most flexible, but has drawbacks. There would probably be a lot of +wasted compilation: if you do `(fact (foo 1)) (fact (bar 2)) (fact (baz 3))` it +would compile `foo` three times, throwing the first two away. I'd also need to +implement a garbage collection algorithm for the code store, which seems like +a lot of work and a large cost at runtime. - An idea I've been rolling around in my head is to try to trade off some - flexibility for speed by using a kind of "stack-based" assertion/retraction - scheme. You would add rules one at a time and it would delay compiling them - until you call `(allocate-logic-stack-frame)`, at which point it would compile - everything and record the current top of the code store (and which predicates - have been defined). Then you could define more predicates, as long as they - weren't already used in a previous "frame", and freeze the frame again to use - them. When you want to retract, you would only be able to pop an entire frame - of predicates in one go. +An idea I've been rolling around in my head is to try to trade off some +flexibility for speed by using a kind of "stack-based" assertion/retraction +scheme. You would add rules one at a time and it would delay compiling them +until you call `(allocate-logic-stack-frame)`, at which point it would compile +everything and record the current top of the code store (and which predicates +have been defined). Then you could define more predicates, as long as they +weren't already used in a previous "frame", and freeze the frame again to use +them. When you want to retract, you would only be able to pop an entire frame +of predicates in one go. - This gives you less control -- you can only retract entire frames, and if you - want to retract something you defined way back at the start you're also forced - to retract everything that came later. But the benefit is that you don't have - to suffer useless recompilation, and you don't need to wait for garbage - collection. +This gives you less control -- you can only retract entire frames, and if you +want to retract something you defined way back at the start you're also forced +to retract everything that came later. But the benefit is that you don't have +to suffer useless recompilation, and you don't need to wait for garbage +collection. - This is probably my GGP mindset showing, because this would be perfect for - using with GDL. When you receive the rules of the game you compile them all, - and freeze the stack. Then for each state you can just compile and push the - `next` and `does` predicates into the new top frame, and pop it when you're - finished examining the state. +This is probably my GGP mindset showing, because this would be perfect for using +with GDL. When you receive the rules of the game you compile them all, and +freeze the stack. Then for each state you can just compile and push the `next` +and `does` predicates into the new top frame, and pop it when you're finished +examining the state.