Simple Rule Engine
Simple Rule Engine is a Python Library that provides simple yet powerful Python APIs for composing rules.
Salient Features
Ability to declaratively author both Scoring and Decision Rules.
The library offers clear segregation of rules vs. facts. Once a rule has been composed, it can be used against any fact set and evaulated.
The library offers composable functional syntax that can be extended with various format adapters. For example, developers can compose their rules in SQL (persist them in the database) and use an adapter to compose rules and execute them against data. See here for an example of such an extension.
Ability to version control rule declarations thus enabling auditing of rule changes over a period of time.
Ability to author chained rules. Evaluation of one rule can refer to the result of another rule, thus enabling modular, hierarchical rules.
Rule Grammar
At it's heart, the simple rule engine is composed of the following constructs:
Token
Operator
Expression
Conditional
They are described below.
Token:
An entity that is representative of a fact, and also guides clients on the data type of fact to be supplied.
Types of Tokens:
NumericToken
StringToken
BooleanToken
RuleToken
: A rule itself, composed as a Token
Example:
StringToken("pet")
represents a token pet of type String.NumericToken("age")
represents a token age of type Numeric.
A rule can be a Token too. A RuleToken implements Token and composes a Rule. When asked for value, a RuleToken executes the rule it composes and provides the value.
A Token in itself is not of much value, but when combined with an Operator
, allows the end user to compose rules.
Operator:
An Operator composes a base value and evaluates against a value supplied.
Example: Gte(35).evaulate(15)
returns False. Gte(35.0).evaulate(40.0)
returns True.
Expression:
An Expression composes a Token on the left hand side (LHS), Operator in the middle and the data to be evaulated on the right hand side (RHS).
Example:
Expression(NumericToken("cibil_score"), Between(floor=650, ceiling=800))
represents an evaluation that compares whether the fact cibil_score is between 650 and 800 or not.
Expression(NumericToken("cibil_score"), Between(floor=650, ceiling=800)).evaluate(dict(cibil_score=700))
evaluates to True.
An Expression is at the core of simple-rule-engine. Multiple Expressions strung together with
And
orOr
conditions make up for a full-fledged rule set.
Conditional:
A Conditional composes a list of Expressions.
WhenAll
evaluates to True when all expressions evaluate to True.WhenAny
evaluates to True when any expression evaluates to True.A Conditional can compose a Conditional - this enables clients to express complex conditions.
A Conditional can be further extended to implement NotWhenAll or NotWhenAny etc. as well.
Example:
With the use of
Conditional
andExpression
, you can weave any complex rule.
Rule Row:
A RuleRow composes a Conditional (as an antecedent (i.e. when)) and specifies a consequent (result (i.e. then)) when the antecedent evaluates to True.
For a Score, the consequent must be a float.
For a Decision, the consequent can be anything.
Rule Set:
A Rule Set composes a set of RuleRows.
For a score, each rule set carries a weight and the total weight of all rule sets must be equal to 1.
For a decision, there must be only one rule set.
Rule:
A rule composes one or many Rule sets.
For a score, the total score is calculated as sum(rule set score * weight).
A rule exposes
get_token_dict_structure
function that returns a dictionary of all facts required for the rule to be executed successfully.
Last updated