Beispiel #1
0
def test_or_operator():
    """
    Test OR operator
    """
    from experta.engine import KnowledgeEngine
    from experta import Rule, OR
    from experta import Fact, L

    class Test(KnowledgeEngine):
        """ Test KE """
        @Rule(OR(Fact(something=L(1)), Fact(something=L(2))))
        def rule1(self):
            """ First rule, something=1 and something=2"""
            pass

    ke_ = Test()
    ke_.reset()
    ke_.declare(Fact(something=1))
    assert len(ke_.agenda.activations) == 1

    ke_ = Test()
    ke_.reset()
    ke_.declare(Fact(something=2))
    assert len(ke_.agenda.activations) == 1

    ke_ = Test()
    ke_.reset()
    ke_.declare(Fact(something=3))
    assert len(ke_.agenda.activations) == 0
Beispiel #2
0
def test_TEST_2():
    from collections import Counter
    from experta import KnowledgeEngine, Rule, Fact, TEST, W

    executed = Counter()

    class Test(KnowledgeEngine):
        @Rule(Fact("a" << W()), Fact("b" << W()), TEST(lambda a, b: a > b),
              Fact("c" << W()), TEST(lambda b, c: b > c))
        def is_greater(self, a, b, c):
            nonlocal executed
            executed[(a, b, c)] += 1

    t = Test()
    f1 = Fact(1)
    f2 = Fact(2)
    f3 = Fact(3)
    f4 = Fact(4)
    t.reset()
    t.declare(f1, f2, f3, f4)
    t.run()

    assert len(executed) == 4
    assert (4, 3, 2) in executed and executed[(4, 3, 2)] == 1
    assert (4, 3, 1) in executed and executed[(4, 3, 1)] == 1
    assert (4, 2, 1) in executed and executed[(4, 2, 1)] == 1
    assert (3, 2, 1) in executed and executed[(3, 2, 1)] == 1
Beispiel #3
0
 class Test(KnowledgeEngine):
     @Rule(
         FORALL(Fact(key_a="k" << W()), Fact(key_b="k" << W()),
                Fact(key_c="k" << W())))
     def any_fact_once(self):
         nonlocal executed
         executed += 1
Beispiel #4
0
def test_ANDNOT_reactivation():
    from experta import KnowledgeEngine, Fact, Rule, NOT, W

    class KE(KnowledgeEngine):
        @Rule(Fact(x='x' << W()), NOT(Fact(y='x' << W())))
        def r1(self):
            pass

    ke = KE()
    ke.reset()
    assert not ke.agenda.activations

    f1 = ke.declare(Fact(x=1))
    assert ke.agenda.activations

    ke.retract(f1)
    assert not ke.agenda.activations

    f2 = ke.declare(Fact(y=1))
    assert not ke.agenda.activations

    f3 = ke.declare(Fact(x=1))
    assert not ke.agenda.activations

    f4 = ke.declare(Fact(x=2))
    assert ke.agenda.activations

    ke.retract(f4)
    assert not ke.agenda.activations
Beispiel #5
0
def test_nested_values_dict_and_lists():
    from experta import KnowledgeEngine, Fact, Rule

    class KE(KnowledgeEngine):
        @Rule(Fact(key__0__with__nested__1__dicts=1))
        def r1(self):
            pass

    ke = KE()
    ke.reset()
    assert len(ke.agenda.activations) == 0

    p0 = ke.declare(
        Fact(key={"with": {
            "nested": [{
                "other": 1
            }, {
                "dicts": 1
            }]
        }}))
    assert len(ke.agenda.activations) == 0

    p1 = ke.declare(
        Fact(key=[{
            "with": {
                "nested": [{
                    "other": 1
                }, {
                    "dicts": 1
                }]
            }
        }]))
    assert len(ke.agenda.activations) == 1
Beispiel #6
0
def test_KnowledgeEngine_reset():
    """
    Given a set of fixed facts, they're still there
    after a reset.
    Also, we have in account that InitialFact() is always there.
    And that if we add a normal fact after that, it's not persistent
    """

    from experta.engine import KnowledgeEngine
    from experta.deffacts import DefFacts
    from experta import Fact

    class KE1(KnowledgeEngine):
        @DefFacts()
        def some_facts(self):
            yield Fact(foo=1)

    ke = KE1()
    ke.declare(Fact(bar=9))
    ke.declare(Fact(bar=7))
    ke.declare(Fact(bar=8))
    ke.reset()

    assert len(ke.facts) == 2  # Initialfact + Fact(foo=1)

    ke = KE1()
    ke.reset()
    ke.declare(Fact(foo=2))
    ke.declare(Fact(foo=3, bar=4))

    assert len(ke.facts) == 4
Beispiel #7
0
def test_prepare_rule__or_starting_with_not():
    from experta import Rule, InitialFact, NOT, Fact, OR, AND

    rule = Rule(OR(NOT(Fact(1)), NOT(Fact(2))))(lambda: None)

    assert list(utils.prepare_rule(rule)) == [
        OR(AND(InitialFact(), NOT(Fact(1))), AND(InitialFact(), NOT(Fact(2))))
    ]
Beispiel #8
0
def test_or_inside_or_inside_fact():
    from experta import Fact, OR, Rule, L
    from experta.matchers.rete.dnf import dnf

    input_ = Rule(Fact(a=L(1) | (L(2) | L(3))))
    output = Rule(OR(Fact(a=L(1)), Fact(a=L(2)), Fact(a=L(3))))

    result = dnf(input_)
    assert result == output
Beispiel #9
0
def test_not_and_inside_fact():
    from experta import Fact, OR, Rule, L
    from experta.matchers.rete.dnf import dnf

    input_ = Rule(Fact(a=~(L(1) & L(2))))
    output = Rule(OR(Fact(a=~L(1)), Fact(a=~L(2))))

    result = dnf(input_)
    assert result == output
Beispiel #10
0
def test_Rule_is_iterable():
    from experta import Rule
    from experta import Fact

    rule_ = iter(Rule(Fact(a=1), Fact(a=2)))
    assert next(rule_) == Fact(a=1)
    assert next(rule_) == Fact(a=2)
    with pytest.raises(StopIteration):
        assert next(rule_)
Beispiel #11
0
def test_or_inside_fact():
    from experta import Fact, OR, Rule, L
    from experta.matchers.rete.dnf import dnf

    input_ = Rule(Fact(a=L(1) | L(2), b=3))
    output = Rule(OR(Fact(a=L(1), b=3), Fact(a=L(2), b=3)))

    result = dnf(input_)
    assert set(result[0]) == set(output[0])
Beispiel #12
0
def test_double_not_inside_fact():
    from experta import Fact, OR, Rule, L
    from experta.matchers.rete.dnf import dnf

    input_ = Rule(Fact(a=~~L(1)))
    output = Rule(Fact(a=L(1)))

    result = dnf(input_)
    assert result == output
Beispiel #13
0
    class KE(KnowledgeEngine):
        @Rule(Fact(s=True), Fact('A'))
        def second(self):
            executed.append(second)

        @Rule(AS.f << Fact(s=False), Fact('A'))
        def first(self, f):
            executed.append(first)
            self.modify(f, s=True)
Beispiel #14
0
    class Test(KnowledgeEngine):
        @DefFacts()
        def test_deffacts(self):
            yield Fact(a=1)

        @Rule(~Fact(b=2) & Fact(a=1))
        def test_fact_after_not(self):
            nonlocal executions
            executions += 1
Beispiel #15
0
def test_not_or_inside_fact():
    from experta import Fact, OR, Rule, L
    from experta.fieldconstraint import ANDFC, NOTFC
    from experta.matchers.rete.dnf import dnf

    input_ = Rule(Fact(a=~(L(1) | L(2))))
    output = Rule(Fact(a=ANDFC(NOTFC(L(1)), NOTFC(L(2)))))

    result = dnf(input_)
    assert result == output
Beispiel #16
0
def test_or_inside_or_inside_and():
    from experta import Fact, OR, AND, Rule
    from experta.matchers.rete.dnf import dnf

    input_ = Rule(AND(Fact(b=1), OR(Fact(a=1), OR(Fact(a=3), Fact(a=4)))))
    output = Rule(
        OR(AND(Fact(b=1), Fact(a=1)), AND(Fact(b=1), Fact(a=3)),
           AND(Fact(b=1), Fact(a=4))))
    result = dnf(input_)
    assert result == output
Beispiel #17
0
def test_and_inside_or_inside_fact():
    from experta import Fact, OR, Rule, L
    from experta.fieldconstraint import ANDFC
    from experta.matchers.rete.dnf import dnf

    input_ = Rule(Fact(a=L(1) | (L(2) & L(3))))
    output = Rule(OR(Fact(a=L(1)), Fact(a=ANDFC(L(2), L(3)))))

    result = dnf(input_)
    assert result == output
Beispiel #18
0
def test_featurecheck_call_not_predicate():
    from experta.matchers.rete.check import FeatureCheck
    from experta import P, Fact

    # Positional matching (negated)
    check = FeatureCheck(0, ~P(lambda _: True))
    assert not check(Fact('somedata'))

    # Positional not matching (negated)
    check = FeatureCheck(0, ~P(lambda _: False))
    assert check(Fact('somedata'))
Beispiel #19
0
def test_featurecheck_call_not_wildcard():
    from experta.matchers.rete.check import FeatureCheck
    from experta import W, Fact

    # Positional match (negated)
    check = FeatureCheck(0, ~W())
    assert not check(Fact('somedata'))

    # Positional match (negated) with binding
    check = FeatureCheck(0, ~W('X'))
    assert check(Fact('somedata')) == {(False, 'X'): 'somedata'}
Beispiel #20
0
    class Test(KnowledgeEngine):
        """ Test KE """
        @DefFacts()
        def some_facts(self):
            yield Fact(other=1)
            yield Fact(other=2)

        @Rule(OR(Fact(something=1), Fact(something=2)))
        def rule1(self):
            """ First rule, something=1 and something=2"""
            pass
Beispiel #21
0
def test_featurecheck_call_not_literal():
    from experta.matchers.rete.check import FeatureCheck
    from experta import L, Fact

    # Positional matching (negated)
    check = FeatureCheck(0, ~L('somedata'))
    assert not check(Fact('somedata'))

    # Positional not matching (negated)
    check = FeatureCheck(0, ~L('somedata'))
    assert check(Fact('otherdata'))
Beispiel #22
0
class RandomFracEngine(KnowledgeEngine):
    @Rule(Fact(id=MATCH.id, contentEditable=True, value=W()))
    def input_random(self, id):
        return Sai(selection=id,
                   action='UpdateTextArea',
                   inputs={'value': str(randint(0, 100))})

    @Rule(Fact(id='done'))
    def click_done(self):
        return Sai(selection='done',
                   action='ButtonPressed',
                   inputs={'value': -1})
Beispiel #23
0
def test_retraction():
    engine = RetractionEngine()
    engine.reset()

    a = Fact('A_parent')
    b = Fact('B_parent')
    engine.declare(a)
    engine.declare(b)

    engine.run(5)
    assert len(engine.facts) == 8

    engine.retract(b)
    assert len(engine.facts) == 3
Beispiel #24
0
def test_and_inside_or():
    from experta import Fact, Rule, AND, OR
    from experta.matchers.rete.dnf import dnf

    input_ = Rule(OR(AND(Fact(a=1), Fact(a=2)), AND(Fact(a=3), Fact(a=4))))
    output = Rule(OR(AND(Fact(a=1), Fact(a=2)), AND(Fact(a=3), Fact(a=4))))
    assert dnf(input_[0]) == output[0]
Beispiel #25
0
def test_featurecheck_call_literal():
    from experta.matchers.rete.check import FeatureCheck
    from experta import L, Fact

    # Positional field not present
    check = FeatureCheck(0, L('mydata'))
    assert not check(Fact())

    # Positional field present, matching and not matching
    check = FeatureCheck(0, L('mydata'))
    assert check(Fact('mydata'))
    check = FeatureCheck(0, L('otherdata'))
    assert not check(Fact('mydata'))

    # Named field present, matching and not matching
    check = FeatureCheck('mykey', L('mydata'))
    assert check(Fact(mykey='mydata'))

    check = FeatureCheck('mykey', L('mydata'))
    assert not check(Fact(mykey='myotherdata'))

    # Named field not present
    check = FeatureCheck('mykey', L('mydata'))
    assert not check(Fact(otherkey='mydata'))

    # Literal with binding, matching and not matching
    check = FeatureCheck('mykey', L('mydata', __bind__='D'))
    assert check(Fact(mykey='mydata')) == {'D': 'mydata'}
    check = FeatureCheck('mykey', L('mydata', __bind__='D'))
    assert check(Fact(mykey='otherdata')) is False
Beispiel #26
0
class ttt_engine(KnowledgeEngine):
    # @DefFacts()
    # def init_board(self, x=3, players=['X', 'O']):
    #     return
    #     yield CurrentPlayer(name=players[0])
    #     for row in range(3):
    #         for col in range(3):
    #             yield Square(row=row, col=col, player='')

    # @Rule(
    #     AS.square1 << Square(row=MATCH.row, col=MATCH.square1col),
    #     AS.square2 << Square(row=MATCH.row, col=MATCH.square2col),
    #     TEST(lambda square1col, square2col: square2col == square1col + 1),
    # )
    # def horizontally_adj(self, row, square1col, square2col):
    #     relation = Fact(
    #         relation="horizontally_adjacent",
    #         row=row,
    #         square1col=square1col,
    #         square2col=square2col,
    #     )
    # self.declare(relation)

    # ... other relations

    # @Rule(
    #     Fact(type="CurrentPlayer", player=MATCH.player),
    #     AS.square << Fact(type="Square", row=MATCH.row, col=MATCH.col,
    #                       player=""),
    #     NOT(Fact(type="PossibleMove", row=MATCH.row, col=MATCH.col,
    #              player=MATCH.player))
    # )
    # def suggest_move(self, row, col, player):
    #     self.declare(Fact(type="PossibleMove", row=row, col=col,
    #                       player=player))

    # @Rule(
    #     Fact(type="CurrentPlayer", player=MATCH.player),
    #     AS.square
    #     << Fact(type="PossibleMove", row=MATCH.row, col=MATCH.col,
    #             player=MATCH.player),
    # )
    # def make_move(self, row, col, player):
    #     return Sai(None, "move", {"row": row, "col": col, "player": player})

    @Rule(Fact(type='CurrentPlayer', player=MATCH.player),
          Fact(type='Square', row=MATCH.row, col=MATCH.col, player=""))
    def make_move(self, row, col, player):
        print("moving", row, col, player)
        return Sai(None, 'move', {'row': row, 'col': col, 'player': player})
Beispiel #27
0
    class Test(KnowledgeEngine):
        @DefFacts()
        def tested_deffacts(self):
            for i in to_declare:
                yield Fact(something=i)

        @Rule(Fact(something=L(1)), Fact(something=L(2)))
        def rule1(self):
            nonlocal executions
            executions.append('rule1')

        @Rule(Fact(something=L(3)))
        def rule2(self):
            nonlocal executions
            executions.append('rule2')
Beispiel #28
0
def test_initial_not_vs_and_not():
    from experta import KnowledgeEngine, Rule, Fact, DefFacts

    executions = 0

    class Test(KnowledgeEngine):
        @DefFacts()
        def test_deffacts(self):
            yield Fact(a=1)

        @Rule(Fact(a=1) & ~Fact(b=2))
        def test_fact_before_not(self):
            nonlocal executions
            executions += 1

    t = Test()
    t.reset()
    t.run()

    assert executions == 1

    t.retract(1)
    t.declare(Fact(a=1))
    t.run()
    assert executions == 2

    executions = 0

    class Test(KnowledgeEngine):
        @DefFacts()
        def test_deffacts(self):
            yield Fact(a=1)

        @Rule(~Fact(b=2) & Fact(a=1))
        def test_fact_after_not(self):
            nonlocal executions
            executions += 1

    t = Test()
    t.reset()
    t.run()

    assert executions == 1

    t.retract(1)
    t.declare(Fact(a=1))
    t.run()
    assert executions == 2
Beispiel #29
0
def test_factlist_changes():
    """ Test factlist changes """

    from experta.factlist import FactList
    from experta import Fact

    flist = FactList()

    f0 = flist.declare(Fact(a=1))
    assert flist.changes[0] == [f0]

    f1 = flist.declare(Fact(b=1))
    assert flist.changes[0] == [f1]

    flist.retract(f1)
    assert flist.changes[1] == [f1]
Beispiel #30
0
 class TestRule(KnowledgeEngine):
     @Rule(Fact(MATCH.value1, MATCH.value2))
     def myrule(self, value1, **kws):
         assert value1 == "SOMETHING1"
         assert kws == {"value2": "SOMETHING2"}
         nonlocal called
         called = True