jruizgit / rules

Durable Rules Engine
MIT License
1.16k stars 206 forks source link

JSON Rule Format to Support NOT operator ? #256

Open wisegb opened 5 years ago

wisegb commented 5 years ago

Hi

I am leveraging the engine.Host class to create my own rule engine instance and loading rules via a JSON file and calling set_rulesets() method. This all works fine.

However, for one of my rules I need to do a negation. I am not sure of the syntax. What is the proper way to negate another clause? For example, consider this rule:

"r_1": { "all": [ {"first": {"condition": "foo"}}, {"second": {"$and": [ {"id": {"first": "id"}}, {"condition": "bar"} ] }}, {"third": {"$and": [ {"id": {"second": "id"}}, {"condition": "cat"} ] }} ], "run": "rule_fired" }

How can I take the NOT of the condition (third) e.g.,

first AND second AND NOT third

Thanks Bowden

jruizgit commented 5 years ago

Hi, thanks for asking the question. The durable_rules engine does not implement unary logical operators. Each binary logical operator has a corresponding binary negation. In the case above, you would do:

{"third": {"$or": [ {"$neq": {"id": {"second": "id"}}}, {"$neq": {"condition": "cat"}} ] }}
wisegb commented 5 years ago

Thank you! That helps!

I have a couple follow up questions:

Consider the logic: first AND second AND third AND NOT fourth

The challenge is that the fourth condition may be missing from the events/facts In that case, the rule should still fire because first, second, and third conditions are met. Does durable rules have a way to handle that?

The second question is:

Suppose I have rules like:

"r_1": { "all": [ {"first": {"condition": "foo"}} ], "run": "r_1" }

"r_2": { "all": [ {"first": {"condition": "foo"}}, {"second": {"label": "foo"}}, ], "run": "r_2" }

In other words, rule r_1 has a subset of the conditions of rule r_2. During testing, when both events are posted to satisfy first and second conditions, the first rule still fires.

So if there is a single event I would like rule 1 to fire but if there are both events, then rule 2 should fire.

Is this not possible? Is there a better way to define the rule?