Python Rule Based Engine

user7692855 picture user7692855 · Nov 21, 2018 · Viewed 34.1k times · Source

I am looking to design a system that will essentially need to make decisions based on input. The input will be a person.

class Person:
    def __init__(self, name, age, sex, weight, height, nationality):
        self.name = name
        self.age = age
        self.sex = sex
        self.weight = weight
        self.height = height
        self.nationality = nationality

We want to assign each person to a school class based on certain rules.

For example:

Women from the UK between 22-25 should go to class B. Men over 75 should go to class A. Women over 6ft should go to class C.

We will have approximately 400 different rules and the first rule that is met should be applied - we need to maintain the order of the rules.

I am thinking about how to store/represent the rules here. Obviously, you could just have a veeeery long if, elif, elif statement but this isn't efficient. Another option would be storing the rules in a database and maybe having an in memory table.

I would like to be able to edit the rules without doing a release - possibly having a front end to allow non tech people to add, remove and reorder rules.

Everything is on the table here - the only certain requirement is the actually programming language must be Python.

Added for further context

I suppose my question is how to store the rules. At the moment it is one huge long if elif elif statement so anytime there is a change to the business logic the PM does up the new rules and I then convert them to the if statement.

All inputs to the system will be sent through the same list of rules and the first rule that matches will be applied. Multiple rules can apply to each input but it's always the first that is applied.

e.g.

Women over 25 go to Class B
Women go to Class A.

Any women over 25 will be sent to class B even though the second rule also applies.

Input will always contain the same format input - haven't decided where it will be an object or a dict but some of the values may be None. Some Persons may not have a weight associated with them.

Answer

noxdafox picture noxdafox · Nov 24, 2018

Rather than re-inventing the wheel, I'd suggest you to use some readily available solution. There are several expert systems out there and I'll focus on those which are either in Python or can be used via Python.

CLIPS

CLIPS is an expert system originally developed by NASA. It's considered state of the art and used in university courses when teaching basics of AI. It's a great starting point due to its excellent documentation.

Its syntax is definitely not Python, it rather reminds of Lisp. The advantage of CLIPS is that is a solid C engine which can be fully integrated with any other Python system via its bindings: the older pyclips and the newer clipspy. The bindings allow to embed Python code within the CLIPS language making it very easy to extend.

Rules can be loaded at runtime without the need of restarting the engine which should better suit your need.

PyKE

The Python Knowledge Engine it's a fairly powerful logic programming framework. As for CLIPS, PyKE comes with its own syntax to express rules and relies on Python for implementing the mechanics.

In other words, you write what to do in Python and you express when and how via rules.

Rules can be activated and deactivated on demand. This should allow you to support releaseless updates.

Durable Rules

Durable Rules is a fairly new project with the ambition of supporting multiple programming languages (Python, Node.js and Ruby so far).

Durable Rules allow you to write the whole knowledge base (facts and rules) in Python. The syntax might look a bit weird though, a note in this regards at the end of the post.

I am not sure if you can update the rule-set while the system is online.

Apart from the multiple syntax support, what interest me of this project is the fact the core is a C based implementation of RETE built on top of Redis DB. On a long run, this might lead to some interesting development.

PyKnow, Python Intellect & Business Rules

PyKnow/Experta

Intellect

Business Rules

These projects allow to express knowledge bases mostly in Python. I have never seen them in action and I am not sure about their performance and feature support.


The main reason I recommend against brewing your own rule engine to use in production is that, despite it seems an easy task at first, it quickly becomes evident that the problem domain is way bigger than predicted.

Python OOP nature seems initially a good fit for expressing knowledge as both Rules and Facts could be simple classes. Nevertheless, as soon as the pattern matching becomes a little more complex (Employee must have worked > 3 years in Company which Stock value is < 10$ in the last 3 years) two things become evident.

  1. The limitation of simply using and, or, not, is, ... make things really hard to read
  2. The problem suddenly reveals its exponential nature and performance become a major concern

Moreover, forcing the employees of an organization to use yet-another-in-house-built-language is usually a bad idea. It prevents them from learning something used in broader contexts such as CLIPS or Drools and will get you stuck in a maintenance/documentation loop for a long time.