concept
Rule engine is not something new rise, this concept proposed actually can be traced back to the last century, the rule engine originated in rule-based expert system, it belongs to the category of the artificial intelligence expert system, the imitation of human reasoning of the reasoning engine, is to apply logical rules in knowledge base to deduce the new information of a part of the system.
Consider this scenario:
When I was a member, I would encounter such demand. Different points would be given to users according to the price and category of goods they purchased.
Commodity prices | Present integral |
---|---|
< 100 | Give away 20 |
< 500 | Give away 80 |
> 500 | Give away 200 |
If we write code to do that
const addPointsByOrderPrice = (order) = >{
if(order.price > 500 ){
add(order.account_id, 200);
} else if (order.price >100){
add(order.account_id, 80);
} else {
add(order.account_id, 20); }}Copy the code
After a few days, the operation of students said, this effect is not very good, we will change the rules, into 100-200 yuan for 20, 200-500 yuan for 90, 500-800 for 100….. And so on all the way to 1w.
If you have a requirement like this, you can’t write n if else’s. So you’re thinking, well, if I write this rule to the configuration center or the database, it’s ok.
Then you have the following code
let rules = await db.select("select * from rules");
const addPointsByOrderPrice = (order) = >{
for(let rule of rules){
if(order.price > rule.price){
add(order.account_id, rule.point);
break; }}}Copy the code
Then the latter product imagination is rich, feel that this condition is not refined enough, but also according to the label attributes of the goods, user tags to judge. If it is a new user, multiply it by two, and if it is a special sale of XX activity, the points will be added by 20.
Normal people have to be killed by product demand. As you can see, the activity rules and the code are already coupled together. Even with the configuration center, a lot of times the development students still need to write hard code to develop.
This requires a declarative language that clearly describes the rules and gameplay. What the rules engine does is basically separate the business rules from the code.
In the rule engine, rules are defined in if-THEN form using rule language. If defines the condition of the rule, and then defines the result of the rule. The rules engine computes these rules based on the data and finds a match. In this way, when the rules need to be modified, only the corresponding rules need to be modified, which can effectively reduce the amount of code development and maintenance.
The best known open source rules engine is Drools.
Pete algorithm
This is one of the core algorithms used in Drools. Rete algorithm is a fast forward rule matching algorithm. It is an efficient pattern matching algorithm for production systems. The matching speed is independent of the number of rules. It solves two problems:
- A large number of repeated condition matching efficiency problems
- The problem of rules conflict with norms
With this algorithm we can understand the core idea of rules engine.
First, a few concepts about rules engines are explained:
Fact: The relationship between objects and between object properties
Rule: An inference statement consisting of conditions and conclusions, usually expressed as if… Then. The if part of a rule is called LHS (left-hand-side) and the THEN part is called RHS (Right hand side).
Module: The condition of an IF statement. Here the IF condition may be a large condition consisting of several smaller conditions. A pattern is the smallest atomic condition that can’t be divided any further.
DSL (Domain Language) : Domain experts only need to focus on the business, not the technology
Suppose there are N rules in the system, on average P patterns in the conditional part of each rule, and M facts to process at a given point in time. Then what rule matching should do is: for each rule R, judge whether the current fact o satisfies LHS(r)=True; if so, add the instance r(o) of rule R, that is, rule + the fact satisfying the rule, to the conflict set for processing. The following process is usually adopted:
- Take an R out of N rules;
- Take a combination c of P facts from M facts;
- Test LHS(r) with c, if LHS(r (c))=True, add RHS(r (c)) to queue;
- If there are other combinations of M facts C, goto 3;
- Take the next rule, r, goto 2;
The actual problem may be more complex. During the execution of rules, the RHS data may be changed to invalidate the matched rule instances or generate new matches that meet the rules, forming a “dynamic” matching chain.
At present, the common pattern matching algorithms include Rete, Treat, Leaps, HAL, Matchbox, etc.
Imagine a scenario where logistics is divided into goods. The attributes of the goods include weight, type, place of receipt, whether urgent or not.
Rules engines are divided into three major concepts:
StockFact: This object holds basic information about goods.
SelectStockRule: Filter rule
IF: Weight < 10kg Category ! = combustible goods receiving place! THEN hand over to xx flight for air transportationCopy the code
Rete algorithm partition
Agenda: Once a business object matches a rule, an Agenda for the rule and the business object is formed. That is, the StockFact that the goods are to be shipped by air.
Execution-engine: The executor that the business object executes the result of a rule after it matches the previous rule. The actuator of the StockFact event that the goods are placed in air transport
The Rete algorithm can be divided into two parts: rule compilation and rule execution. When the Rete algorithm makes a fact assertion, it consists of three phases: matching, selection, and execution, called the match-select-act cycle. It’s essentially swapping space for time, which consumes a lot of memory.
AlphaNode: For example. Weight < 10kg This is an alpha node when a rule has multiple literals that are chained together.
BetaNode: Compares and checks two objects. Let’s say the combination of these two conditions
Weight < 10kg && Category ! = flammableCopy the code
The convention is that the two inputs for BetaNode are called the left (Join Node) and the right. The left side is usually a list of objects, and the right side (NotNode) is usually a single object. Each Bate node has its own terminal node and so on. BetaNode Has the memory function. The input on the left is called Beta Memory and remembers all semantics as they arrive. The input on the right becomes Alpha Memory
The most important rule engine is Patten Matcher. The regular expression we often use is a form of pattern matching.
Patten Matcher process presentation1. The sequence is ABCDE. ABD is the Alpha node and CD is the Beta node.
2. Take Fact from WM and first match A. If A matches the condition, the reference of Fact is stored in A’s Alpha Cache. A Beta node with no left reference exits.
3. Then match B. If B matches the condition, store the Fact reference in B’s Alpha Cache. And then B has a Beta node left referenced, which is C.
4.C is the Beta node, there is A left reference to node A, and then the Alpha Cache has A reference to node A. If so, it is stored in the Beta node corresponding to the C node. exit
5. A match to D. If the match is true, the Fact reference is stored in D’s Alpha Cache. Also find the left reference Beta node E for D, whose left reference is C. If C’s BetaCache has a reference to C, if yes, the reference to E exists in the BetaCache
6. The Fact matches these rules, forms an agenda, places them in the conflict zone, and executes the result.
What if more than one rule is triggered?
We defined multiple rules, each with a different significance, and when a message is asserted, they are fired in the order of significance (from highest to lowest).
PS: Significance is an option that can be specified on a rule, giving it priority and allowing the developer some control over the active conflict resolution.
Nodejs Open source component -Nools
Go to Github and link noolsjs/nools. First of all, the Nools project has been out of maintenance for some time. Even Google has not found any useful Chinese documents. They are all foreign documents with some history, but the official documents are complete. Therefore, it is not recommended to use it on a large scale in the production environment, as it may cause accidental injury.
It’s not very useful, but it’s a good way to understand the concept of a rules engine, since Nools is implemented using the Rete algorithm.
var nools = require("nools");
var flow = nools.compile("./Demo2.nools"),
Param = flow.getDefined("Param");
session = flow.getSession(new Param(11))
.on('assert'.function (result) {
console.log(result);// The callback returns the assert content, output result2
})
.on('modify'.function (result) {
console.log(result, result.param1);// Return the modified value, output {param1:21} 21(no parameter note)
})
.match().then(function () {
console.log('end');// Execute whether or not any of the rules are met, output end
});
Copy the code
You can see that there are several states here, assert, modify.
According to the official document, it is
- assert (fact) – emitted when facts are asserted
- retract (fact) – emitted when facts are retracted
- modify (fact) – emitted when facts are modified
- fire (name, rule) – emitted when an activation is fired.
Using these states, we can easily control the flow of the network in the NOols file.
Suppose you currently have the following NOols files
define Param { // As an input message for the rule
param1 : 0.note :'test for nothing'.constructor : function(p1){
this.param1 = p1;
}
}
rule condition1 { // Define the rule condition1
when { p:Param p.param1 <= 10; } then { assert("result111"); } } rule condition2 {// Define the rule condition2
when { p:Param p.param1 > 10 && p.param1 <= 20; } then {// Each of these events can be triggered by multiple
assert('result2'); // Triggers the assert event
//fire(p);
modify(p,function(){ // Trigger the modify event
p.param1 -= 10; }); }}Copy the code
It defines two rules: params <= 10, params > 10 && params <=20;
Let’s take a closer look at the Rete network from the DSL syntax.
Scene design
Now we are going to design a visualization of the lottery rules.
In addition to basic services such as lottery service and user service, the following issues should be considered:
- Visual rules editor
- Rules automation testing framework
- Fact browser
- Mock services
- Rule management and versioning
- A cache of user insensitive states
- Rule execution
All you need to do here is focus on the AST and the rules engine if you want to make this work.
The first part is visual rule editing. Although the rules engine separates the logic from the business code, the DSL is really hard to read. The goal, of course, is to be easy to configure, even without development involvement. Suppose the design is to generate a specific DSL to the rules engine by writing a simple line like this.
If (The old user is true and the active days are greater than20) or new users Then raffle chance +1
Copy the code
This paragraph is very easy to understand. The Parse module is introduced here to convert this paragraph into a DSL.
In fact, syntax parsing, here consider using Pegjs this library implementation. There is no further introduction here, interested can refer to pegjs.org/online. Higher order…
The second part is the rules engine, so you can choose nools or JSON-rules-engine to implement it. (Json-rules-engine also provides a corresponding open source editor, which can be used directly for visual editing if the diagram is convenient, although I personally find it difficult to use).
The above provides the idea of a rule generator. If you go into detail, you will find that what I defined above are static rules, and there will be dynamic rules in the actual production environment. Here I will leave it to you to think in the actual business.
gossip
There are no small number of scenarios in the industry where rules engines are used, especially now that the middle platform concept has been around for some time and a lot of complex logic is being integrated into a large system. The introduction of rules engines can reduce a lot of code complexity and coding effort.
The benchmark of rule engine Tob is IBM’s iLog. I have learned from friends of China Mobile’s partner companies that the new billing and package on Guangdong Mobile is using this set, and many insurance companies are also using iLog. Like Taobao Meituan e-commerce coupon rules, will also use the rule engine, but are generally self-developed. The financial risk control of banks will also have a rule engine. Even some apps such as Douyin and BigoLive, short video apps, will also have a rule engine. The model will be used to identify, and then the corresponding graphics will be loaded as dynamic rules.
Although online search rules engine, the basic is out of Drools, but many times the actual selection will not choose it, mainly because
- There are so many Drools related components that you need to study them individually to know if you need them
- Drools logic is complex and the principle is not understood. Once problems occur, it is difficult to troubleshoot
- Drools requires writing DSL (Domain specific language) files, which are expensive to learn
Therefore, teams such as Meituan and Taobao prefer to use dynamic script engines, such as Groovy, Aviator and easyRule, when selecting rule engines. The DSL writing method of these engines is similar to Java, and the component ecology is seamlessly compatible with Java.
For a small rule engine, it is recommended to write your own or use a lightweight framework to be faster, since most of the time you will not be exposed to millions of rules. If you write it yourself, you can consider directly designing the decision tree, which is compatible with visualization and easy to traverse. Js components like CacheControl/json-rules-engine are also a good choice.
Remaining issues:
- How do I select the appropriate component
- Visual configuration of rules
- Rules maintenance
- Rule execution efficiency
The reference documents
Introduction and basic use of PEg.js
nools
Rule matching -Rete algorithm principle and implementation _ my code steward – Houwenbin’s column -CSDN blog _rete
Stop saying you don’t understand the rules engine!
RETE algorithm first look
Bytes to beat school/club recruit delivery link: job.toutiao.com/s/SYWV68P