https://groovy-lang.org/
https://commons.apache.org/proper/commons-jexl/
https://github.com/mvel/mvel
https://docs.spring.io/spring-framework/docs/3.0.x/reference/expressions.html
https://commons.apache.org/proper/commons-ognl/
https://github.com/killme2008/aviatorscript
https://github.com/google/cel-go
https://github.com/google/cel-spec
https://github.com/bilibili/gengine
https://github.com/oleg-shilo/cs-script
https://github.com/j-easy/easy-rules
Either in a declarative way using annotations:
@Rule(name = "weather rule", description = "if it rains then take an umbrella")
public class WeatherRule {
@Condition
public boolean itRains(@Fact("rain") boolean rain) {
return rain;
}
@Action
public void takeAnUmbrella() {
System.out.println("It rains, take an umbrella!");
}
}
Or in a programmatic way with a fluent API:
Rule weatherRule = new RuleBuilder()
.name("weather rule")
.description("if it rains then take an umbrella")
.when(facts -> facts.get("rain").equals(true))
.then(facts -> System.out.println("It rains, take an umbrella!"))
.build();
Or using an Expression Language:
Rule weatherRule = new MVELRule()
.name("weather rule")
.description("if it rains then take an umbrella")
.when("rain == true")
.then("System.out.println(\"It rains, take an umbrella!\");");
Or using a rule descriptor:
Like in the following weather-rule.yml
example file:
name: "weather rule"
description: "if it rains then take an umbrella"
condition: "rain == true"
actions:
- "System.out.println(\"It rains, take an umbrella!\");"
MVELRuleFactory ruleFactory = new MVELRuleFactory(new YamlRuleDefinitionReader());
Rule weatherRule = ruleFactory.createRule(new FileReader("weather-rule.yml"));
public class Test {
public static void main(String[] args) {
// define facts
Facts facts = new Facts();
facts.put("rain", true);
// define rules
Rule weatherRule = ...
Rules rules = new Rules();
rules.register(weatherRule);
// fire rules on known facts
RulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.fire(rules, facts);
}
}
https://github.com/CacheControl/json-rules-engine
const { Engine } = require('json-rules-engine')
/**
* Setup a new engine
*/
let engine = new Engine()
// define a rule for detecting the player has exceeded foul limits. Foul out any player who:
// (has committed 5 fouls AND game is 40 minutes) OR (has committed 6 fouls AND game is 48 minutes)
engine.addRule({
conditions: {
any: [{
all: [{
fact: 'gameDuration',
operator: 'equal',
value: 40
}, {
fact: 'personalFoulCount',
operator: 'greaterThanInclusive',
value: 5
}]
}, {
all: [{
fact: 'gameDuration',
operator: 'equal',
value: 48
}, {
fact: 'personalFoulCount',
operator: 'greaterThanInclusive',
value: 6
}]
}]
},
event: { // define the event to fire when the conditions evaluate truthy
type: 'fouledOut',
params: {
message: 'Player has fouled out!'
}
}
})
/**
* Define facts the engine will use to evaluate the conditions above.
* Facts may also be loaded asynchronously at runtime; see the advanced example below
*/
let facts = {
personalFoulCount: 6,
gameDuration: 40
}
// Run the engine to evaluate
engine
.run(facts)
.then(({ events }) => {
events.map(event => console.log(event.params.message))
})
/*
* Output:
*
* Player has fouled out!
*/
https://www.drools.org/
https://github.com/youseries/urule
https://github.com/wfh45678/radar
https://github.com/jetlinks/rule-engine
//规则模型
RuleModel{
events:[ RuleLink ] # 事件连接点,用于自定义规则事件的处理规则
nodes:[ RuleNodeModel ] # 所有节点信息,包含事件节点
}
//节点模型
RuleNodeModel{
executor: "" # 节点执行器标识
configuration: { Map } # 节点配置
events:[ RuleLink ] # 事件连接点,用于自定义节点事件的处理规则
inputs:[ RuleLink ] # 输入连接点
outputs:[ RuleLink ] # 输出连接点
}
//连接点,将2个规则节点关联
RuleLink{
type: "" # 类型,为事件连接点时类型则为事件类型
condition: Condition # 连接条件
source: RuleNodeModel # 连接节点
target: RuleNodeModel # 被连接节点
}
//条件
Condition{
type: "" # 条件类型。如: expression
configuration: { Map } # 条件配置
}
https://github.com/andbi/evrete
class PrimeNumbers {
public static void main(String[] args) {
KnowledgeService service = new KnowledgeService();
StatefulSession session = service
.newKnowledge()
.newRule()
.forEach(
"$i1", Integer.class,
"$i2", Integer.class,
"$i3", Integer.class
)
.where("$i1 * $i2 == $i3")
.execute(
ctx -> {
int $i3 = ctx.get("$i3");
ctx.delete($i3);
}
)
.createSession();
// Inject candidates
for (int i = 2; i <= 100; i++) {
session.insert(i);
}
// Execute rules
session.fire();
// Print current memory state
session.forEachMemoryObject(System.out::println);
// Closing resources
session.close();
service.shutdown();
}
}
https://github.com/momosecurity/aswan
https://github.com/microsoft/RulesEngine
[
{
"WorkflowName": "Discount",
"Rules": [
{
"RuleName": "GiveDiscount10",
"SuccessEvent": "10",
"ErrorMessage": "One or more adjust rules failed.",
"ErrorType": "Error",
"RuleExpressionType": "LambdaExpression",
"Expression": "input1.country == \"india\" AND input1.loyalityFactor <= 2 AND input1.totalPurchasesToDate >= 5000"
},
{
"RuleName": "GiveDiscount20",
"SuccessEvent": "20",
"ErrorMessage": "One or more adjust rules failed.",
"ErrorType": "Error",
"RuleExpressionType": "LambdaExpression",
"Expression": "input1.country == \"india\" AND input1.loyalityFactor >= 3 AND input1.totalPurchasesToDate >= 10000"
}
]
}
]
https://github.com/NRules/NRules
Rules engine for .NET, based on the Rete matching algorithm, with internal DSL in C#.
public class PreferredCustomerDiscountRule : Rule
{
public override void Define()
{
Customer customer = default;
IEnumerable orders = default;
When()
.Match(() => customer, c => c.IsPreferred)
.Query(() => orders, x => x
.Match(
o => o.Customer == customer,
o => o.IsOpen,
o => o.PercentDiscount == 0.0)
.Collect()
.Where(c => c.Any()));
Then()
.Do(ctx => ApplyDiscount(orders, 10.0))
.Do(ctx => ctx.UpdateAll(orders));
}
private static void ApplyDiscount(IEnumerable orders, double discount)
{
foreach (var order in orders)
{
order.PercentDiscount = discount;
}
}
}