# Path: pyknow/abstract.py
# class Matcher(metaclass=abc.ABCMeta):
# class Strategy(metaclass=abc.ABCMeta):
#     def __init__(self, engine):
#     def changes(self, adding=None, deleting=None):  # pragma: no cover
#     def reset(self):  # pragma: no cover
#     def __init__(self, *args, **kwargs):
#     def _update_agenda(self, agenda, added, removed):  # pragma: no cover
#     def update_agenda(self, agenda, added, removed):


import pytest
from pyknow import abstract
        from pyknow.matchers.rete import ReteMatcher
    from pyknow.matchers.rete import ReteMatcher
    from pyknow.matchers.rete import ReteMatcher
    from pyknow.engine import KnowledgeEngine
    from pyknow.matchers.rete import ReteMatcher
    from pyknow.engine import KnowledgeEngine
    from pyknow.matchers.rete.nodes import BusNode
    from pyknow.engine import KnowledgeEngine
    from pyknow.fact import Fact
    from pyknow.matchers.rete import ReteMatcher
    from pyknow.matchers.rete.token import Token
    from pyknow.engine import KnowledgeEngine
    from pyknow.fact import Fact
    from pyknow.rule import Rule
    from pyknow.activation import Activation
    from pyknow.matchers.rete.nodes import ConflictSetNode
    from pyknow.matchers.rete import ReteMatcher

def test_retematcher_has_root_node():

    matcher = ReteMatcher(KnowledgeEngine())
    assert hasattr(matcher, 'root_node')
    assert isinstance(matcher.root_node, BusNode)


def test_retematcher_changes_are_propagated(TestNode):

    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

# Path: pyknow/abstract.py
# class Matcher(metaclass=abc.ABCMeta):
# class Strategy(metaclass=abc.ABCMeta):
#     def __init__(self, engine):
#     def changes(self, adding=None, deleting=None):  # pragma: no cover
#     def reset(self):  # pragma: no cover
#     def __init__(self, *args, **kwargs):
#     def _update_agenda(self, agenda, added, removed):  # pragma: no cover
#     def update_agenda(self, agenda, added, removed):


# Path: tests/unit/matchers/rete/test_matcher.py
import pytest
from pyknow import abstract
        from pyknow.matchers.rete import ReteMatcher
    from pyknow.matchers.rete import ReteMatcher
    from pyknow.matchers.rete import ReteMatcher
    from pyknow.engine import KnowledgeEngine
    from pyknow.matchers.rete import ReteMatcher
    from pyknow.engine import KnowledgeEngine
    from pyknow.matchers.rete.nodes import BusNode
    from pyknow.engine import KnowledgeEngine
    from pyknow.fact import Fact
    from pyknow.matchers.rete import ReteMatcher
    from pyknow.matchers.rete.token import Token
    from pyknow.engine import KnowledgeEngine
    from pyknow.fact import Fact
    from pyknow.rule import Rule
    from pyknow.activation import Activation
    from pyknow.matchers.rete.nodes import ConflictSetNode
    from pyknow.matchers.rete import ReteMatcher


def test_retematcher_has_root_node():

    matcher = ReteMatcher(KnowledgeEngine())
    assert hasattr(matcher, 'root_node')
    assert isinstance(matcher.root_node, BusNode)


def test_retematcher_changes_are_propagated(TestNode):

    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