Beispiel #1
0
def test_retematcher_changes_are_propagated(TestNode):
    from pyknow.engine import KnowledgeEngine
    from pyknow.fact import Fact
    from pyknow.matchers.rete import ReteMatcher
    from pyknow.matchers.rete.token import Token

    matcher = ReteMatcher(KnowledgeEngine())
    tn1 = TestNode()
    tn2 = TestNode()

    matcher.root_node.add_child(tn1, tn1.activate)
    matcher.root_node.add_child(tn2, tn2.activate)

    f1 = Fact(__factid__=1)
    f2 = Fact(__factid__=2)
    f3 = Fact(__factid__=3)
    f4 = Fact(__factid__=4)

    matcher.changes(adding=[f1, f2], deleting=[f3, f4])

    assert Token.valid(f1) in tn1.added
    assert Token.valid(f1) in tn2.added
    assert Token.valid(f2) in tn1.added
    assert Token.valid(f2) in tn2.added
    assert Token.invalid(f3) in tn1.added
    assert Token.invalid(f3) in tn2.added
    assert Token.invalid(f4) in tn1.added
    assert Token.invalid(f4) in tn2.added
Beispiel #2
0
def test_ordinarymatchnode_left_activate_invalid_remove_from_left_memory():
    from pyknow.matchers.rete.nodes import OrdinaryMatchNode
    from pyknow.matchers.rete.token import Token
    from pyknow.fact import Fact

    omn = OrdinaryMatchNode(lambda l, r: True)

    fact = Fact(test='data')
    token = Token.valid(fact)
    omn.left_memory.append(token.to_info())

    omn.activate_left(Token.invalid(fact))

    assert not omn.left_memory
Beispiel #3
0
def test_token_initialization_conversions():
    """
    Token.data is modified in this way:
        - If is a Fact: Converted to a Set containing this Fact.
        - An interable of Facts: Converter to a set of Facts.

    """
    from pyknow.matchers.rete.token import Token
    from pyknow.fact import Fact

    t1 = Token(Token.TagType.VALID, Fact())
    assert t1.data == {Fact()}

    t2 = Token(Token.TagType.VALID, [Fact(a=1), Fact(b=2)])
    assert t2.data == {Fact(a=1), Fact(b=2)}
Beispiel #4
0
def test_busnode_remove(TestNode):
    from pyknow.matchers.rete.nodes import BusNode
    from pyknow.matchers.rete.token import Token
    from pyknow.fact import Fact

    bn = BusNode()
    tn1 = TestNode()
    tn2 = TestNode()

    bn.add_child(tn1, tn1.activate)
    bn.add_child(tn2, tn2.activate)

    bn.remove(Fact())

    assert tn1.added == [Token.invalid(Fact())]
    assert tn2.added == [Token.invalid(Fact())]
Beispiel #5
0
def test_ordinarymatchnode_left_activate_invalid_build_new_tokens(TestNode):
    from pyknow.matchers.rete.nodes import OrdinaryMatchNode
    from pyknow.matchers.rete.token import Token
    from pyknow.fact import Fact

    omn = OrdinaryMatchNode(lambda l, r: True)
    tn1 = TestNode()
    tn2 = TestNode()
    omn.add_child(tn1, tn1.activate)
    omn.add_child(tn2, tn2.activate)

    rt1 = Token.valid(Fact(rightdata='rightdata1'))
    rt2 = Token.valid(Fact(rightdata='rightdata2'))
    omn.right_memory.append(rt1.to_info())
    omn.right_memory.append(rt2.to_info())

    token = Token.invalid(Fact(leftdata='leftdata'))
    omn.activate_left(token)

    assert tn1.added == [Token.invalid([Fact(leftdata='leftdata'),
                                        Fact(rightdata='rightdata1')]),
                         Token.invalid([Fact(leftdata='leftdata'),
                                        Fact(rightdata='rightdata2')])]

    assert tn2.added == [Token.invalid([Fact(leftdata='leftdata'),
                                        Fact(rightdata='rightdata1')]),
                         Token.invalid([Fact(leftdata='leftdata'),
                                        Fact(rightdata='rightdata2')])]
Beispiel #6
0
def test_token_copy_mutable():
    from pyknow.matchers.rete.token import Token

    a = Token.valid([])
    b = a.copy()

    assert a == b and a is not b
    assert a.data == b.data and a.data is not b.data
    assert a.context == b.context and a.context is not b.context
Beispiel #7
0
def test_notnode_left_activate_valid_matching(TestNode):
    from pyknow.matchers.rete.nodes import NotNode
    from pyknow.matchers.rete.token import Token
    from pyknow.fact import Fact

    nn = NotNode(lambda l, r: True)
    nn.right_memory.append(Token.valid(Fact(test='data')).to_info())

    tn1 = TestNode()
    tn2 = TestNode()

    nn.add_child(tn1, tn1.activate)
    nn.add_child(tn2, tn2.activate)

    token = Token.valid(Fact(test='data'))
    nn.activate_left(token)

    assert not tn1.added
    assert not tn2.added
    assert nn.left_memory[token.to_info()] == 1
Beispiel #8
0
def test_token_initialization_types():
    """
    Token.tag must be a Tag
    Token.data can be:
        - A Fact
        - An interable of Facts

    """
    from pyknow.matchers.rete.token import Token
    from pyknow.fact import Fact

    with pytest.raises(TypeError):
        Token(None, Fact())

    with pytest.raises(TypeError):
        Token(Token.TagType.VALID, None)

    with pytest.raises(TypeError):
        Token(Token.TagType.VALID, [Fact(), None])

    with pytest.raises(TypeError):
        Token(Token.TagType.VALID, [Fact()], [])

    # THIS MUST NOT RAISE
    Token(Token.TagType.VALID, Fact(), {})
    Token(Token.TagType.VALID, [Fact(), Fact()], {})
Beispiel #9
0
def test_ordinarymatchnode_left_activate_valid_store_in_left_memory():
    from pyknow.matchers.rete.nodes import OrdinaryMatchNode
    from pyknow.matchers.rete.token import Token, TokenInfo
    from pyknow.fact import Fact

    omn = OrdinaryMatchNode(lambda l, r: True)

    assert not omn.left_memory

    fact = Fact(test='data')
    token = Token.valid(fact)
    omn.activate_left(token)

    assert TokenInfo({fact}, {}) in omn.left_memory
Beispiel #10
0
def test_conflictsetchange_valid_adds_to_memory():
    from pyknow.fact import Fact
    from pyknow.matchers.rete.nodes import ConflictSetNode
    from pyknow.matchers.rete.token import Token, TokenInfo
    from pyknow.rule import Rule

    csn = ConflictSetNode(Rule())

    f = Fact(test='data')
    f.__factid__ = 1

    csn.activate(Token.valid(f, {'mycontextdata': 'data'}))

    assert TokenInfo([f], {'mycontextdata': 'data'}) in csn.memory
Beispiel #11
0
def test_featuretesternode_pass_fact_to_matcher():
    from pyknow.matchers.rete.nodes import FeatureTesterNode
    from pyknow.matchers.rete.token import Token
    from pyknow.fact import Fact

    fact = Fact(this_is_my_fact=True)

    def _matcher(f):
        nonlocal fact
        assert f is fact

    ftn = FeatureTesterNode(_matcher)

    ftn.activate(Token.valid(fact))
Beispiel #12
0
def test_conflictsetchange_invalid_removes_from_memory():
    from pyknow.fact import Fact
    from pyknow.matchers.rete.nodes import ConflictSetNode
    from pyknow.matchers.rete.token import Token, TokenInfo
    from pyknow.rule import Rule

    csn = ConflictSetNode(Rule())
    csn.memory.append(
        TokenInfo([Fact(__factid__=1, test='data')],
                  {'mycontextdata': 'data'}))

    csn.activate(
        Token.invalid(Fact(__factid__=1, test='data'),
                      {'mycontextdata': 'data'}))

    assert not csn.memory
Beispiel #13
0
def test_featuretesternode_pass_when_callable_fail(TestNode):
    from pyknow.matchers.rete.nodes import FeatureTesterNode
    from pyknow.matchers.rete.token import Token
    from pyknow.fact import Fact

    ftn = FeatureTesterNode(lambda f: False)
    tn1 = TestNode()
    tn2 = TestNode()

    token = Token.valid(Fact(test=True))

    ftn.add_child(tn1, tn1.activate)
    ftn.add_child(tn2, tn2.activate)

    ftn.activate(token)

    assert tn1.added == tn2.added == []
Beispiel #14
0
def test_conflictsetchange_get_activations_data():
    from pyknow.matchers.rete.nodes import ConflictSetNode
    from pyknow.matchers.rete.token import Token
    from pyknow.rule import Rule
    from pyknow.fact import Fact
    from pyknow.activation import Activation

    rule = Rule()
    csn = ConflictSetNode(rule)
    csn.activate(Token.valid(Fact(__factid__=1, first=1), {'data': 'test'}))

    added, removed = csn.get_activations()

    assert len(added) == 1
    assert len(removed) == 0

    assert list(added)[0].rule is rule
    assert Fact(__factid__=1, first=1) in list(added)[0].facts
    assert list(added)[0].context == {'data': 'test'}
Beispiel #15
0
def test_featuretesternode_pass_when_callable_modify_context(TestNode):
    from pyknow.matchers.rete.nodes import FeatureTesterNode
    from pyknow.matchers.rete.token import Token
    from pyknow.fact import Fact

    ftn = FeatureTesterNode(lambda f: {'something': True})
    tn1 = TestNode()
    tn2 = TestNode()

    token = Token.valid(Fact(test=True), {'something': False})

    ftn.add_child(tn1, tn1.activate)
    ftn.add_child(tn2, tn2.activate)

    ftn.activate(token)

    newtoken = token.copy()
    newtoken.context['something'] = True

    assert tn1.added == tn2.added == []
def test_conflictsetchange_get_activations_data():
    from pyknow.matchers.rete.nodes import ConflictSetNode
    from pyknow.matchers.rete.token import Token
    from pyknow.rule import Rule
    from pyknow.fact import Fact

    rule = Rule()
    csn = ConflictSetNode(rule)

    f = Fact(first=1)
    f.__factid__ = 1

    csn.activate(Token.valid(f, {'data': 'test'}))

    added, removed = csn.get_activations()

    assert len(added) == 1
    assert len(removed) == 0

    assert list(added)[0].rule is rule
    assert f in list(added)[0].facts
    assert list(added)[0].context == {'data': 'test'}
Beispiel #17
0
def test_token_shortcut_invalid():
    from pyknow.matchers.rete.token import Token

    assert Token.invalid([]) == Token(Token.TagType.INVALID, [])