Search code examples
.netrulesdata-analysis

Given key\value pairs, find all rules that satisfy and return true


Here is an interesting problem I've been brainstorming today.

Given an object with key/value pairs and a system/tool with defined rules/queries, find all rules that return true.

For example given a person:

{
    "FirstName": "John",
    "LastName": "Smith",
    "Age": 28,
    "Gender": "Male",
    "Location": "USA"
}

And given some rules:

Rule 1: Location = USA AND (Gender = Male OR Age < 20)
Rule 2: Location != USA AND (Gender = Female OR Age > 25)

I'd expect the system to return all the rules that would be true given the object. Then based on the rule that was true, do a specific action.

That's a simple example. The fun bits:

  • The passed object can have any number of different key\value pairs
  • There could be hundreds or thousands of different rules that need to be executed
  • Rules can contain any combination of the key value pairs
  • Performance and usability are the key
  • Usable in a .Net application

The idea for a custom implementation is:

Do map reduce and only return the rules that contain the keys from the object. This would reduce the number of rules that need to be executed, but could still be a few hundred rules.

Take each rule and execute it with the given values to see if it returns true.


Is there a better way to do this? Is there any tool (hopefully open source) that would already accomplish this?

The searches did not return much, and I could not even think of a proper search to do.


EDIT

After some more searching online, it turns out this is solvable using Rete Algorithm and numerous implementation in .Net and Java world.

This is the path I am currently headed down. If anyone has any better suggestions please provide them.


Solution

  • Why a separate step to map

    Just abort the test ASAP

    private bool? ruleMe (person p, rule r) 
    {
        foreach (string rKey in r.ExtractKeys())
           if(!p.ContainsKey(rKey)) return (bool?)null;
        // process r 
    
    }
    

    or extend both to create a HaskSet of Key

    public class person 
    {
        private HashSet<String> hSkey;
        public HashSet<String> HSkey 
        {
            if (hSkey == null)
            { 
               hSkey = new HashSet<String>();
               // populate hSkey
            }
            return hSkey;
        }
    }
    
    private bool? ruleMe (person p, rule r) 
    {
        if(!r.HSkey.IsProperSubset(p.HSkey))  // O(n of r.HSKey) 
           return (bool?)null;
        // process r 
    }