Rete algorithm
en.wikipedia.org
en.wikipedia.org
It's a really interesting algorithm, and allows one to get O(1) incremental pattern matching (ie, when one adds a pattern, one is told of a matching pattern in O(1) time) at the cost of O(npattern * nitems) memory usage. I was trying to use it in the context of pattern matching within a compiler, but I never went anywhere since I had COVID, then a PhD to get to :)
Music to my ears :) thanks for sharing this!
Among other things, the rules engine would ensure that bowling balls wouldn't be packed in with ceramic dolls, or that goods that could be dangerous if spilled and mixed wouldn't be packed together. Overall, a very fun project for a young programmer.
- pattern matching - custom DSL - caching
I find it difficult to summarize in an "elevator pitch," and I only started seeing things fall into place after trying to use it in earnest on my own. I highly recommend reading the CLIPS documentation posted on the main CLIPS website. The PDFs are long, but quite complete and well written.
Self promotion: If you prefer something a little more interactive, check out the Tour of CLIPS I made: https://ryjo.codes/tour-of-clips.html
Just a heads up: this is not light reading. Rules-based programming is a confusing departure from traditional programming; there's more "magic" involved, similar to convention-over-configutation in other languages/frameworks. The benefits outweigh the upfront learning cost, though.
Here is a recent post on HN that recently got some traction and has some pretty good discussions: Tour of CLIPS (2022) - https://news.ycombinator.com/item?id=40201729
If anyone is working directly with CLIPS, let me know! I'm actively working on a low level networking library called CLIPSockets, and would like to work with the language full time some day.
CLIPS is one of those definitely underrated gems, many many thanks for what you are doing!
In case anyone might be able to answer..
What are some of the biggest rule systems deployed in the wild, and are any of them recent? Since it seems like this is mostly about first order logic.. do any of these rule-engines actually out perform all the modern work on SMT solvers and other theorem-provers? Same question for this more probabilistic Rete-OO flavor.. isn't there already some faster and more generic engine available that handles this kind of thing as a special case?
[1] https://en.wikipedia.org/wiki/Drools#Drools_in_Apache_Kie [2] https://en.wikipedia.org/wiki/Rete_algorithm#Rete-OO
You have plenty of business cases here by FICO, the market leader: https://www.fico.com/en/customers
Also IBM is pretty strong in this area: https://www.ibm.com/products/operational-decision-manager
https://www.rapid7.com/blog/post/2013/11/01/vulnerability-ma...
More than a decade after i used it last, recruiters still randomly call out of the blue for short to medium term contracts using Blaze Advisor.
Rete is an elegant algorithm that is also quite flexible: one can make non-distributive aggregations, outer joins and recursive traversal work. However, it is quite memory-hungry due to the large state of certain nodes (e.g., join operators). I tried to work around this by using distributed execution, but that made the system very inefficient and complex to operate. I also looked into the TREAT algorithm but found that it is more limited in its functionality than Rete.
For incremental view maintenance, the state of the art has now moved on to techniques such as differential dataflow or DBSP (https://www.vldb.org/pvldb/vol16/p1601-budiu.pdf).
Incremental view maintenance is different enough from rule composition and evaluation that the model diverges to be more optimal. Collections of tuples and instead of DAGs lots of cyclical loops to continue computation of the diffs.
There are deep and intrinsic space or time trade offs so many of the modern approaches moved toward natural dataflow concurrency, and streaming semantics where space or time trade offs can be chosen at runtime through batching and data context opposed to early RETE variations which were very OOP and eagerly evaluated instead of lazy (all in memory in the same place instantiated and mutated).
It'll be interesting to see where these differential dataflow approaches go as we head into local-first constraints where central authority on data isn't possible and long divergence of synchronization occurs. Lots of CRDTs in this future for sure. E.g. https://github.com/RhizomeDB/rs-rhizome / https://fission.codes/blog/fission-reactor-dialog-first-look...
I have a funny history with OPS5. When my company bought me a Xerox 1108 Lisp Machine in 1982, converting OPS5 to run on InterLisp-D and adding a nice UI was my first project. I also ported it to the Mac in 1984 (ExperOPS5), and one weekend I converted Charles Forgy’s original Common Lisp code to MIT Scheme.
The Rete Matching Algorithm (https://news.ycombinator.com/item?id=11364718) - Mar 2016 (21 comments)
Project Area52 (http://phrack.org/issues/56/6.html)
So, now your knowledge base is RDF nodes.
I have not yet had a chance to play with it myself, but when I was playing with RDF and turned down that corridor in surprise: "Oh my, what. have. we. here!"
I think it's pretty neat.
Was fun :)
They have different heuristics for conflict resolution when more than one rule can be fired. Once you define the strategy, it will be consistent throughout the entire lifecycle.
Once the network is compiled, it ensures that previously matched patterns are not recomputed, which increases performance.
Likewise either with knowledge graphs or using LLMs to generate possible predicates and constraints to run against a rule engine or backwards chain through facts is a way to minimize hallucinations of generative models.
A primary goal of Rete is to narrow the rule set to be applied based on changes in the working memory. Quite important if you have a large rule set over a more naive, perhaps brute force, approach of apply rules.
But modern machines are pretty stupid fast, and when operating on very slow hardware of the day, Rete was very important. Today, I don't know. Or, simply, that the use cases perhaps narrow particularly for smaller rule sets.
"Here's a bunch of rules (say, anonymous JS functions). Run each one against this working set (which is little more than a fancy map). If any of the members of the map change, do it again."
Cheap hack 2B. Register with each rule what variables its interested in:
addRule(['weight', 'height'], function(map) { var w = map.get("weight"); var h = map.get("height"); var bmi = w / (h * h); map.put("bmi", bmi); });
addRule(['bmi'], function(map) { var bmi = map.get("bmi"); if (bmi > 30) { map.put("weight_status", "obese"); } });
(No, this isn't a rule development environment. Yes, rule engines can be very complicated, and rule interaction, precedence, etc. are a Thing. This is a trivial example, doesn't mean it's not potentially useful for some scenarios however.)Tour of CLIPS (2022) - https://news.ycombinator.com/item?id=40201729 - April 2024 (41 comments, with more links at https://news.ycombinator.com/item?id=40213716)
Also:
Rust rule matching engine (Rete algorithm) (2020) - https://news.ycombinator.com/item?id=37649161 - Sept 2023 (2 comments)
The Rete Matching Algorithm (2002) - https://news.ycombinator.com/item?id=11364718 - March 2016 (21 comments)
RETE is cool and common context applications with LLMs is going to be a very interesting space that may revive this as a more general purpose technology.
- https://github.com/nemonik/Intellect (Dead - 2017)
- https://github.com/jruizgit/rules (dead)
- https://github.com/cmaclell/py_rete (dead)
- https://github.com/nilp0inter/experta (dead)
- https://github.com/GNaive/naive-rete (dead)
(All of them are rule engine - I guess they implement the Rete algo or some variant but no time to check ATM).
Also: "production" is probably false since all of them are dead (or were, last time I checked - I'd be happy to be proven wrong).
Self-plug: my interview with its original author. https://thesearch.space/episodes/2-ryan-brush-on-retaking-ru...
For me, the "It's just Clojure" part is a drawback, not only for me personally but when I think about the kind of audiences that I have traditionally wanted to author rules, between a real, lisp-y, dynamically-typed, programming language and asking folks to write in the Drools DSLs, I'll take my chances with the DSLs
The rule structures themself have a data structure representation that is independent of the DSL. You can have other DSL's implemented that target this structure. Again though, it certainly is easiest to do with Clojure. This was touched on in this post https://www.toomuchcode.org/blog/2015/11/14/insta-declarativ...
Sadly, it is no longer maintained.
It's a little strange, but very flexible. I'd like to try adapting it to evaluate rules specified using annotated Kotlin.
I don't have any affiliation with them, it was considered for a project I worked on in 2005.
What we liked about it was the ability to contextualize events by keeping a history and relationship between objects and events that we could reference as part of our rules. Particularly when we get an event storm and putting more signal into situational awareness when there is a lot of noise.
- TREAT
- GATOR
Source: via Forgy himself, see https://www.youtube.com/watch?v=BUw-67B_qA4#t=4m30s (the video and the blog that goes along with it are really annoying in holding out the explanation until the end)