Beispiel #1
0
class Rule:
    '''
    In-memory representation of logic-engine rule, relying on parsing utilities in BooleanExpression.
    '''
    def __init__(self, rule_name, rule_cfg):
        self.name = rule_name
        self.expr = BooleanExpression(rule_cfg["expression"])
        self.actions = rule_cfg.get("actions")
        self.false_actions = rule_cfg.get("false_actions")
        self.new_facts = rule_cfg.get("facts")

    def evaluate(self, evaluated_facts):
        """
        Evaluates a compiled expression given the supplied facts.

        :type evaluated_facts: dict
        :arg evaluated_facts: Initial fact values (e.g. True or False) for each fact name.
        :rtype: bool
        """
        return self.expr.evaluate(evaluated_facts)

    def __str__(self):  # pragma: no cover
        return f"name: {self.name}\n"
        f"expression: '{self.expr}'\n"
        f"actions: {self.actions}\n"
        f"false_actions: {self.false_actions}\n"
        f"facts: {self.new_facts}"
Beispiel #2
0
 def __init__(self, cfg):
     super().__init__(cfg)
     self.logger = logging.getLogger()
     self.facts = {
         name: BooleanExpression(expr)
         for name, expr in cfg["facts"].items()
     }
     self.rule_engine = RuleEngine(cfg["facts"].keys(), cfg["rules"])
 def __init__(self, cfg):
     super().__init__(cfg)
     self.logger = structlog.getLogger(CHANNELLOGGERNAME)
     self.logger = self.logger.bind(class_module=__name__.split(".")[-1],
                                    channel=self.channel_name)
     self.facts = {
         name: BooleanExpression(expr)
         for name, expr in cfg["facts"].items()
     }
     self.rule_engine = RuleEngine(cfg["facts"].keys(), cfg["rules"])
Beispiel #4
0
def test_compound_fact():
    fact = BooleanExpression("z < 100 and a == 4")
    assert set(fact.required_names) == {"z", "a"}
    assert fact.evaluate({"z": 50, "a": 4}) is True
    assert fact.evaluate({"z": 100, "a": 4}) is False
    assert fact.evaluate({"z": 200, "a": 4}) is False
    assert fact.evaluate({"z": 200, "a": 5}) is False
    assert fact.evaluate({"z": 100, "a": 5}) is False
    assert fact.evaluate({"z": 50, "a": 5}) is False
Beispiel #5
0
 def __init__(self, rule_name, rule_cfg):
     self.name = rule_name
     self.expr = BooleanExpression(rule_cfg["expression"])
     self.actions = rule_cfg.get("actions")
     self.false_actions = rule_cfg.get("false_actions")
     self.new_facts = rule_cfg.get("facts")
Beispiel #6
0
def test_fact_using_numpy_function():
    fact = BooleanExpression("np.sum(vals) > 40")
    assert set(fact.required_names) == {"vals", "np"}
    with pytest.raises(Exception, match="name 'np' is not defined"):
        fact.evaluate(make_db(3))
Beispiel #7
0
def test_simple_fact():
    fact = BooleanExpression("z < 100")
    assert fact.required_names == ["z"]
    assert fact.evaluate({"z": 50}) is True
    assert fact.evaluate({"z": 100}) is False
    assert fact.evaluate({"z": 200}) is False
Beispiel #8
0
def test_fact_using_numpy_array():
    fact = BooleanExpression("vals.sum() > 40")
    assert fact.required_names == ["vals"]
    assert fact.evaluate(make_db(3)) is False
    assert fact.evaluate(make_db(10)) is True
Beispiel #9
0
def test_fact_with_nested_names():
    fact = BooleanExpression("z > 100 and b.c == 10")
    assert set(fact.required_names) == {"z", "b"}
Beispiel #10
0
def test_fact_with_fail_on_error():
    fact = BooleanExpression("fail_on_error(a[0])")
    assert set(fact.required_names) == {"a"}
Beispiel #11
0
def test_syntax_error(caplog):
    with pytest.raises(SyntaxError):
        BooleanExpression("z <")
    assert "The following expression string could not be parsed" in caplog.text