示例#1
0
def test_Depth_update_agenda_asertion_order_affects_agenda_order_1():
    from pyknow.strategies import Depth
    from pyknow.activation import Activation
    from pyknow.rule import Rule
    from pyknow.agenda import Agenda

    act1 = Activation(rule=Rule(), facts=(1, ))
    act2 = Activation(rule=Rule(), facts=(2, ))
    first = {act1, act2}

    act3 = Activation(rule=Rule(), facts=(3, ))
    act4 = Activation(rule=Rule(), facts=(4, ))
    second = {act3, act4}

    a = Agenda()

    st = Depth()

    st.update_agenda(a, first)
    st.update_agenda(a, second)

    left, right = set(list(a.activations)[:2]), set(list(a.activations)[2:])

    assert left == second
    assert right == first
示例#2
0
def test_Rule_get_activations_needs_factlist(data):
    from pyknow.rule import Rule

    r = Rule()

    with pytest.raises(ValueError):
        r.get_activations(data)
示例#3
0
def test_Depth_update_agenda_different_salience():
    from random import shuffle

    from pyknow.strategies import Depth
    from pyknow.activation import Activation
    from pyknow.rule import Rule
    from pyknow.agenda import Agenda

    act1 = Activation(rule=Rule(salience=1), facts=(1, ))
    act2 = Activation(rule=Rule(salience=2), facts=(2, ))
    act3 = Activation(rule=Rule(salience=3), facts=(3, ))
    act4 = Activation(rule=Rule(salience=4), facts=(4, ))

    acts = [act1, act2, act3, act4]
    shuffle(acts)

    st = Depth()
    a = Agenda()

    for act in acts:
        st.update_agenda(a, [act])

    order = list(a.activations)
    assert (order.index(act4) < order.index(act3) < order.index(act2) <
            order.index(act1))
def test_Rule_get_activations_needs_factlist(data):
    from pyknow.rule import Rule

    r = Rule()

    with pytest.raises(ValueError):
        r.get_activations(data)
def test_Rule_empty_doesnt_match_empty_factlist():
    from pyknow.rule import Rule
    from pyknow.factlist import FactList

    r = Rule()
    fl = FactList()

    assert r.get_activations(fl) == tuple()
示例#6
0
def test_Rule_empty_doesnt_match_empty_factlist():
    from pyknow.rule import Rule
    from pyknow.factlist import FactList

    r = Rule()
    fl = FactList()

    assert tuple(r.get_activations(fl)) == tuple()
示例#7
0
def test_Rule_with_only_one_NOT_match_InitialFact_if_fact_is_not_present():
    from pyknow.rule import NOT, Rule
    from pyknow.factlist import FactList
    from pyknow.fact import Fact, InitialFact, L
    from pyknow.match import Capturation

    r = Rule(NOT(Fact(something=L(True))))
    fl = FactList()
    fl.declare(InitialFact())

    assert next(r.get_activations(fl, Capturation()), None) is not None
def test_Rule_empty_matches_with_initial_fact():
    from pyknow.rule import Rule
    from pyknow.factlist import FactList
    from pyknow.fact import InitialFact
    from pyknow.activation import Activation

    r = Rule()
    fl = FactList()
    idx = fl.declare(InitialFact())

    assert Activation(r, (0,)) in r.get_activations(fl)
示例#9
0
def test_Rule_empty_matches_with_initial_fact():
    from pyknow.rule import Rule
    from pyknow.factlist import FactList
    from pyknow.fact import InitialFact
    from pyknow.activation import Activation
    from pyknow.match import Capturation

    r = Rule()
    fl = FactList()
    fl.declare(InitialFact())
    assert Activation(None,
                      (0, )) in list(r.get_activations(fl, Capturation()))
示例#10
0
def test_Rule_multiple_criteria_generates_activation_with_matching_facts():
    from pyknow.rule import Rule
    from pyknow.factlist import FactList
    from pyknow.fact import Fact, L

    r = Rule(Fact(a=L(1)), Fact(b=L(2)))
    fl = FactList()
    fl.declare(Fact(a=L(1)))
    fl.declare(Fact(b=L(2)))

    activations = list(r.get_activations(fl))
    assert len(activations) == 1
    assert {0, 1} == set(activations[0].facts)
示例#11
0
def test_Rule_and_AND_nesting():
    from pyknow.rule import Rule, AND
    from pyknow.factlist import FactList
    from pyknow.fact import Fact, L

    r = Rule(AND(Fact(a=L(2)), Fact(b=L(1))))

    fl = FactList()
    fl.declare(Fact(a=L(2)))
    fl.declare(Fact(b=L(1)))

    activations = list(r.get_activations(fl))
    assert len(activations) == 1
    assert {0, 1} == set(activations[0].facts)
示例#12
0
def test_Rule_simple_testce():
    from pyknow.rule import Rule
    from pyknow.fact import Fact, T, L
    from pyknow.factlist import FactList

    r = Rule(Fact(a=T(lambda c, x: x.startswith('D'))))

    fl = FactList()
    fl.declare(Fact(a=L("David")))
    fl.declare(Fact(a=L("Penelope")))

    activations = list(r.get_activations(fl))

    assert len(activations) == 1

    assert {0} == set(activations[0].facts)
示例#13
0
def test_Depth_update_agenda_activations_to_agenda():
    from pyknow.strategies import Depth
    from pyknow.activation import Activation
    from pyknow.rule import Rule
    from pyknow.agenda import Agenda

    act1 = Activation(rule=Rule(), facts=(1, ))
    act2 = Activation(rule=Rule(), facts=(2, ))

    a = Agenda()

    st = Depth()
    st.update_agenda(a, {act1, act2})

    assert act1 in a.activations
    assert act2 in a.activations
示例#14
0
def test_Rule_with_empty_Fact_matches_all_Facts():
    from pyknow.rule import Rule
    from pyknow.factlist import FactList
    from pyknow.fact import Fact
    from pyknow.activation import Activation

    r = Rule(Fact())
    fl = FactList()
    fl.declare(Fact(something=True))
    fl.declare(Fact(something=False))
    fl.declare(Fact(something=3))

    activations = r.get_activations(fl)
    assert len(activations) == 3
    for i in range(3):
        assert Activation(r, (i, )) in activations
示例#15
0
def test_activation_facts_only_tuple():
    """ Check if activation facts are required to be a tuple """
    from pyknow.activation import Activation
    from pyknow.rule import Rule
    import pytest
    with pytest.raises(ValueError):
        Activation(rule=Rule(), facts=list())
示例#16
0
def test_Strategy_update_agenda_update_executed(strategy):
    from pyknow import strategies
    from pyknow.activation import Activation
    from pyknow.rule import Rule
    from pyknow.agenda import Agenda

    act1 = Activation(rule=Rule(), facts=(1, ))
    act2 = Activation(rule=Rule(), facts=(2, ))

    st = getattr(strategies, strategy)()
    a = Agenda()
    a.executed.add(act1)

    st.update_agenda(a, [act2])

    assert act1 not in a.executed
示例#17
0
def test_Rule_with_NOT_DEFINED():
    from pyknow.rule import Rule, NOT
    from pyknow.factlist import FactList
    from pyknow.fact import Fact, InitialFact, L, W

    r = Rule(Fact(a=L(1)), NOT(Fact(b=W(True))))

    fl = FactList()
    fl.declare(InitialFact())
    fl.declare(Fact(a=L(1)))

    activations = r.get_activations(fl)
    assert len(list(activations)) == 1

    fl.declare(Fact(b=L('SOMETHING')))
    activations = r.get_activations(fl)
    assert len(list(activations)) == 0
示例#18
0
def test_Rule_with_empty_Fact_matches_all_Facts():
    from pyknow.rule import Rule
    from pyknow.factlist import FactList
    from pyknow.fact import Fact, L
    from pyknow.activation import Activation

    r = Rule(Fact())
    fl = FactList()

    fl.declare(Fact(something=L(True)))
    fl.declare(Fact(something=L(False)))
    fl.declare(Fact(something=L(3)))

    activations = list(r.get_activations(fl))
    assert len(activations) == 3
    for i in range(3):
        assert Activation(None, (i, )) in activations
示例#19
0
def test_conflictsetchange_accepts_rule():
    from pyknow.matchers.rete.nodes import ConflictSetNode
    from pyknow.rule import Rule

    # MUST NOT RAISE
    ConflictSetNode(Rule())

    with pytest.raises(TypeError):
        ConflictSetNode('NOTARULE')
示例#20
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
示例#21
0
def test_rule_with_NOT_testce():
    from pyknow.rule import Rule, NOT
    from pyknow.factlist import FactList
    from pyknow.fact import Fact, InitialFact, L, T

    r = Rule(Fact(a=L(1)), NOT(Fact(b=T(lambda c, x: x.startswith('D')))))

    fl = FactList()
    fl.declare(InitialFact())
    fl.declare(Fact(a=L(1)))

    activations = r.get_activations(fl)
    assert len(list(activations)) == 1

    fl.declare(Fact(b=L('David')))
    activations = r.get_activations(fl)
    assert len(list(activations)) == 0

    fl = FactList()
    fl.declare(InitialFact())
    fl.declare(Fact(a=L(1)))
    fl.declare(Fact(b=L('Penelope')))
    activations = r.get_activations(fl)
    assert len(list(activations)) == 1
示例#22
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
示例#23
0
def test_retematcher_changes_return_activations_if_csn():
    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

    matcher = ReteMatcher(KnowledgeEngine())
    rule = Rule()
    csn = ConflictSetNode(rule)
    matcher.root_node.add_child(csn, csn.activate)

    added, removed = matcher.changes(
        adding=[Fact(__factid__=1), Fact(__factid__=2)])

    assert len(added) == 2
    assert all(isinstance(a, Activation) for a in added)
示例#24
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'}
示例#25
0
def test_Rule_decorator_raise_AttributeError_if_called_without_function():
    from pyknow.rule import Rule

    with pytest.raises(AttributeError):
        Rule()()
示例#26
0
def test_activation_has_facts():
    """ Check if activation has facts property """
    from pyknow.activation import Activation
    from pyknow.rule import Rule
    assert hasattr(Activation(rule=Rule(), facts=tuple()), 'facts')
示例#27
0
文件: __init__.py 项目: fly2mars/TO
    def build_alpha_part(ruleset, root_node):
        """
        Given a set of already adapted rules, build the alpha part of
        the RETE network starting at `root_node`.

        """
        # Adds a dummy rule with InitialFact as LHS for always generate
        # the alpha part matching InitialFact(). This is needed for the
        # CE using InitialFact
        ruleset = ruleset.copy()
        ruleset.add(Rule(InitialFact()))

        # Generate a dictionary with rules and the set of facts of the
        # rule.
        rule_facts = {rule: extract_facts(rule) for rule in ruleset}

        # For each fact build a list of checker function capable of
        # check for each part in the fact.
        fact_checks = {
            fact: set(generate_checks(fact))
            for fact in chain.from_iterable(rule_facts.values())
        }

        # Make a ranking of the most used checks
        check_rank = Counter(chain.from_iterable(fact_checks.values()))

        def weighted_check_sort(check):
            """Sort check by its type and number of times seen."""
            if isinstance(check, TypeCheck):
                return (float('inf'), hash(check))
            elif isinstance(check, FactCapture):
                return (float('-inf'), hash(check))
            elif isinstance(check, FeatureCheck):
                return (check_rank[check], hash(check))
            else:
                raise TypeError("Unknown check type.")  # pragma: no cover

        def weighted_rule_sort(rule):
            """Sort rules by the average weight of its checks."""
            total = 0
            for fact in rule_facts[rule]:
                for check in fact_checks[fact]:
                    total += check_rank[check]
            return total / len(rule_facts[rule])

        sorted_rules = sorted(ruleset, key=weighted_rule_sort, reverse=True)

        fact_terminal_nodes = dict()
        # For rule in rank order and for each rule fact also in rank
        # order, build the alpha brank looking for an existing node
        # first.
        for rule in sorted_rules:
            for fact in rule_facts[rule]:
                current_node = root_node
                fact_sorted_checks = sorted(fact_checks[fact],
                                            key=weighted_check_sort,
                                            reverse=True)

                for check in fact_sorted_checks:
                    # Look for a child node with the given check in the
                    # current parent node.
                    for child in current_node.children:
                        if child.node.matcher is check:
                            current_node = child.node
                            break
                    else:
                        # Create a new node and append as child
                        new_node = FeatureTesterNode(check)
                        current_node.add_child(new_node, new_node.activate)
                        current_node = new_node

                fact_terminal_nodes[fact] = current_node

        # Return this dictionary containing the last alpha node for each
        # fact.
        return fact_terminal_nodes
示例#28
0
def test_Rule_nesting_issubclass():
    """
        This actually tests that nesting a Rule is permitted.
        Rule nesting can be useful for meta-stuff, and
    """
    from pyknow.rule import Rule
    from pyknow.factlist import FactList
    from pyknow.fact import Fact, L

    r1 = Rule(Fact(a=L(1)), Fact(b=L(2)), Fact(c=L(3)))
    r2 = Rule(Fact(a=L(1)), Rule(Fact(b=L(2)), Fact(c=L(3))))
    r3 = Rule(Fact(a=L(1)), Rule(Fact(b=L(2)), Rule(Fact(c=L(3)))))
    r4 = Rule(Rule(Fact(a=L(1))), Rule(Fact(b=L(2))), Rule(Fact(c=L(3))))
    r5 = Rule(Rule(Fact(a=L(1)), Fact(b=L(2)), Fact(c=L(3))))

    fl = FactList()
    fl.declare(Fact(a=L(1)))
    fl.declare(Fact(b=L(2)))
    fl.declare(Fact(c=L(3)))

    for r in (r1, r2, r3, r4, r5):
        activations = list(r.get_activations(fl))
        assert len(activations) == 1
        assert {0, 1, 2} == set(activations[0].facts)
示例#29
-1
def test_Rule_multiple_criteria_generates_activation_with_matching_facts():
    from pyknow.rule import Rule
    from pyknow.factlist import FactList
    from pyknow.fact import Fact

    r = Rule(Fact(a=1), Fact(b=2))
    fl = FactList()
    fl.declare(Fact(a=1))
    fl.declare(Fact(b=2))

    activations = r.get_activations(fl)
    assert len(activations) == 1
    assert {0, 1} == set(activations[0].facts)