Files
Sheerka-Old/tests/sheerkarete/test_conditions.py
T
kodjo 7dcaa9c111 Fixed #29: Parsers: Implement parsing memoization
Fixed #77 : Parser: ShortTermMemoryParser should be called separately
Fixed #78 : Remove VariableNode usage
Fixed #79 : ConceptManager: Implement compile caching
Fixed #80 : SheerkaExecute : parsers_key is not correctly computed
Fixed #81 : ValidateConceptEvaluator : Validate concept's where and pre clauses right after the parsing
Fixed #82 : SheerkaIsAManager: isa() failed when the set as a body
Fixed #83 : ValidateConceptEvaluator : Support BNF and SYA Concepts
Fixed #84 : ExpressionParser: Implement the parser as a standard parser
Fixed #85 : Services: Give order to services
Fixed #86 : cannot manage smart_get_attr(the short, color)
2021-06-07 21:14:03 +02:00

371 lines
13 KiB
Python

import pytest
from sheerkarete.common import WME, V
from sheerkarete.conditions import NotEqualsCondition, AndConditions, Condition, NegatedCondition, \
NegatedConjunctiveConditions, FilterCondition, BindCondition
from sheerkarete.network import ReteNetwork
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
from tests.sheerkarete.RuleForTestingRete import RuleForTestingRete
class TestReteConditions(TestUsingMemoryBasedSheerka):
def test_i_can_manage_condition(self):
network = ReteNetwork()
condition = Condition("id", "attr", "value")
rule = RuleForTestingRete(AndConditions([condition]))
network.add_rule(rule)
assert len(list(network.matches)) == 0
wme = WME("id", "attr", "value")
network.add_wme(wme)
matches = list(network.matches)
assert len(matches) == 1
assert matches[0].pnode.rules == [rule]
assert matches[0].token.wmes == [wme]
# remove wme
network.remove_wme(wme)
assert len(list(network.matches)) == 0
@pytest.mark.skip("Comparison between variables need to be implemented.")
def test_i_can_test_condition_between_variables(self):
network = ReteNetwork()
conditions = [Condition(V("x"), "__name__", "x"),
Condition(V("y"), "__name__", "y"),
Condition(V("x"), "__self__", V("y"))],
rule = RuleForTestingRete(AndConditions(conditions))
network.add_rule(rule)
assert len(list(network.matches)) == 0
wme_x = WME("x", "__self__", "10")
wme_y = WME("y", "__self__", "10")
network.add_wme(wme_x)
network.add_wme(wme_y)
matches = list(network.matches)
assert len(matches) == 1
assert matches[0].pnode.rules == [rule]
assert matches[0].token.wmes == [wme_x, wme_y]
# remove wme
network.remove_wme(wme_x)
assert len(list(network.matches)) == 0
def test_i_can_manage_not_equals_condition(self):
network = ReteNetwork()
# I can add the condition
cond1 = NotEqualsCondition("id", "value", 5)
rule1 = RuleForTestingRete(AndConditions([cond1]), name="first id != 5")
network.add_rule(rule1)
assert list(network.alpha_hash.keys()) == [("id", "value", "*")]
assert len(network.alpha_hash[("id", "value", "*")]) == 1
assert network.alpha_hash[("id", "value", "*")][0].condition == cond1
# Another rule with the same condition
rule2 = RuleForTestingRete(AndConditions([cond1]), name="second id != 5")
network.add_rule(rule2)
assert list(network.alpha_hash.keys()) == [("id", "value", "*")]
assert len(network.alpha_hash[("id", "value", "*")]) == 1
assert network.alpha_hash[("id", "value", "*")][0].condition == cond1
cond2 = NotEqualsCondition("id", "value", 6)
rule3 = RuleForTestingRete(AndConditions([cond2]), name="id != 6")
network.add_rule(rule3)
assert list(network.alpha_hash.keys()) == [("id", "value", "*")]
assert len(network.alpha_hash[("id", "value", "*")]) == 2
assert network.alpha_hash[("id", "value", "*")][0].condition == cond1
assert network.alpha_hash[("id", "value", "*")][1].condition == cond2
# I can match
wme1 = WME("id", "value", "1")
network.add_wme(wme1)
matches = list(network.matches)
assert len(matches) == 2
assert matches[0].pnode.rules == [rule1, rule2]
assert matches[1].pnode.rules == [rule3]
# I can remove
network.remove_wme(wme1)
assert len(list(network.matches)) == 0
# I can add a non match
wme2 = WME("id", "value", 5)
network.add_wme(wme2)
matches = list(network.matches)
assert len(matches) == 1
assert matches[0].pnode.rules == [rule3]
def test_i_can_manage_negative_condition(self):
network = ReteNetwork()
condition = NegatedCondition("id", "attr", "value")
rule = RuleForTestingRete(AndConditions([condition]))
network.add_rule(rule)
assert len(network.beta_root.children) == 1
matches = list(network.matches)
assert len(matches) == 1
assert matches[0].pnode.rules == [rule]
assert matches[0].token.wmes == [None]
wme = WME("id", "attr", "value")
network.add_wme(wme)
matches = list(network.matches)
assert len(matches) == 0
# remove wme
network.remove_wme(wme)
matches = list(network.matches)
assert len(matches) == 1
assert matches[0].pnode.rules == [rule]
assert matches[0].token.wmes == [None]
def test_i_can_manage_ncc(self):
network = ReteNetwork()
c1 = Condition(V("x"), "is a", "light")
c2 = Condition(V("x"), "is", "red")
c3 = Condition(V("x"), "is", "blue")
rule = RuleForTestingRete(AndConditions([c1, NegatedConjunctiveConditions(c2, c3)]))
network.add_rule(rule)
wme1 = WME("x1", "is a", "light")
wme2 = WME("x1", "is", "blue")
network.add_wme(wme1)
network.add_wme(wme2)
matches = list(network.matches)
assert len(matches) == 1
assert matches[0].token.wmes == [wme1, None]
wme3 = WME("x1", "is", "red")
network.add_wme(wme3)
assert len(list(network.matches)) == 0
wme4 = WME("x2", "is a", "light")
network.add_wme(wme4)
matches = list(network.matches)
assert len(matches) == 1
assert matches[0].token.wmes == [wme4, None]
# remove a wme
network.remove_wme(wme2)
matches = list(network.matches)
assert len(matches) == 2
assert matches[0].token.wmes == [wme4, None]
assert matches[1].token.wmes == [wme1, None]
def test_i_can_manage_ncc_when_already_inserted_elements(self):
network = ReteNetwork()
wme1 = WME("x1", "is a", "light")
wme2 = WME("x1", "is", "blue")
network.add_wme(wme1)
network.add_wme(wme2)
c1 = Condition(V("x"), "is a", "light")
c2 = Condition(V("x"), "is", "red")
c3 = Condition(V("x"), "is", "blue")
rule = RuleForTestingRete(AndConditions([c1, NegatedConjunctiveConditions(c2, c3)]))
network.add_rule(rule)
matches = list(network.matches)
assert len(matches) == 1
assert matches[0].token.wmes == [wme1, None]
wme3 = WME("x1", "is", "red")
network.add_wme(wme3)
assert len(list(network.matches)) == 0
# remove back
network.remove_wme(wme2)
matches = list(network.matches)
assert len(matches) == 1
assert matches[0].token.wmes == [wme1, None]
def test_i_can_manage_ncc_when_already_inserted_elements2(self):
network = ReteNetwork()
wme1 = WME("x1", "is a", "light")
wme2 = WME("x1", "is", "blue")
wme3 = WME("x1", "is", "red")
network.add_wme(wme1)
network.add_wme(wme2)
network.add_wme(wme3)
c1 = Condition(V("x"), "is a", "light")
c2 = Condition(V("x"), "is", "red")
c3 = Condition(V("x"), "is", "blue")
rule = RuleForTestingRete(AndConditions([c1, NegatedConjunctiveConditions(c2, c3)]))
network.add_rule(rule)
assert len(list(network.matches)) == 0
# remove a wme
network.remove_wme(wme3)
matches = list(network.matches)
assert len(matches) == 1
assert matches[0].token.wmes == [wme1, None]
def test_i_can_manage_filter_condition(self):
network = ReteNetwork()
c1 = Condition("value", "equals", V("x"))
c2 = Condition("value", "equals", V("y"))
c3 = FilterCondition(lambda x, y: x == y + 1)
rule = RuleForTestingRete(AndConditions([c1, c2, c3]))
network.add_rule(rule)
assert len(list(network.matches)) == 0
wme1 = WME("value", "equals", 5)
wme2 = WME("value", "equals", 3)
network.add_wme(wme1)
network.add_wme(wme2)
assert len(list(network.matches)) == 0
wme3 = WME("value", "equals", 4)
network.add_wme(wme3)
matches = list(network.matches)
assert len(matches) == 2
assert matches[0].token.wmes == [wme1, wme3]
assert matches[1].token.wmes == [wme3, wme2]
# remove a WME
network.remove_wme(wme1)
matches = list(network.matches)
assert len(matches) == 1
assert matches[0].token.wmes == [wme3, wme2]
def test_i_can_manage_filter_when_it_is_the_first_condition(self):
network = ReteNetwork()
c1 = FilterCondition(lambda: True)
rule = RuleForTestingRete(AndConditions([c1]))
network.add_rule(rule)
matches = list(network.matches)
assert len(matches) == 1
assert matches[0].token.wmes == [None]
assert matches[0].token.binding == {}
# remove wme
network.remove_rule(rule)
assert len(list(network.matches)) == 0
def test_i_can_filter_already_inserted_elements(self):
network = ReteNetwork()
wme1 = WME("value", "equals", 5)
wme2 = WME("value", "equals", 3)
wme3 = WME("value", "equals", 4)
network.add_wme(wme1)
network.add_wme(wme2)
network.add_wme(wme3)
c1 = Condition("value", "equals", V("x"))
c2 = Condition("value", "equals", V("y"))
c3 = FilterCondition(lambda x, y: x == y + 1)
rule = RuleForTestingRete(AndConditions([c1, c2, c3]))
network.add_rule(rule)
matches = list(network.matches)
assert len(matches) == 2
# assert matches[0].token.wmes == [wme3, wme2]
# assert matches[1].token.wmes == [wme1, wme3]
assert len(matches[0].token.wmes) == 2
assert len(matches[1].token.wmes) == 2
def test_i_can_manage_binding_conditions(self):
network = ReteNetwork()
c1 = Condition("value", "equals", V("x"))
c2 = BindCondition(lambda x: x + 5, V("z"))
rule = RuleForTestingRete(AndConditions([c1, c2]))
network.add_rule(rule)
assert len(list(network.matches)) == 0
wme1 = WME("value", "equals", 1)
network.add_wme(wme1)
matches = list(network.matches)
assert len(matches) == 1
assert matches[0].token.wmes == [wme1]
assert matches[0].token.binding == {V("z"): 6, V("x"): 1}
# remove wme
network.remove_wme(wme1)
assert len(list(network.matches)) == 0
def test_i_can_manage_bind_when_it_is_the_first_condition(self):
network = ReteNetwork()
c1 = BindCondition(lambda: 5, V("x"))
rule = RuleForTestingRete(AndConditions([c1]))
network.add_rule(rule)
matches = list(network.matches)
assert len(matches) == 1
assert matches[0].token.wmes == [None]
assert matches[0].token.binding == {V("x"): 5}
# remove wme
network.remove_rule(rule)
assert len(list(network.matches)) == 0
def test_i_can_match_on_the_correct_variable_name(self):
network = ReteNetwork()
condition = Condition(V("x"), "attr", V("x"))
rule = RuleForTestingRete(AndConditions([condition]))
network.add_rule(rule)
wme = WME('a', 'attr', 'c')
network.add_wme(wme)
assert len(list(network.matches)) == 0
wme = WME('a', 'attr', 'a')
network.add_wme(wme)
assert len(list(network.matches)) == 1
def test_condition_test(self):
c0 = Condition(V('x'), 'color', 'red')
w0 = WME('B1', 'color', 'red')
w1 = WME('B1', 'color', 'blue')
assert c0.test(w0)
assert not c0.test(w1)
c1 = Condition(V('x'), 'is', V('x'))
w2 = WME('B1', 'is', 'B3')
assert not c1.test(w2)
def test_black_white(self):
# KSI 2021-02-07. I simply copy this test
net = ReteNetwork()
c1 = Condition(V('item'), 'cat', V('cid'))
c2 = Condition(V('item'), 'shop', V('sid'))
white = NegatedConjunctiveConditions(
NegatedCondition(V('item'), 'cat', '100'),
NegatedCondition(V('item'), 'cat', '101'),
NegatedCondition(V('item'), 'cat', '102'),
)
n1 = NegatedCondition(V('item'), 'shop', '1')
n2 = NegatedCondition(V('item'), 'shop', '2')
n3 = NegatedCondition(V('item'), 'shop', '3')
rule = RuleForTestingRete(AndConditions([c1, c2, white, n1, n2, n3]))
net.add_rule(rule)
wmes = [
WME('item:1', 'cat', '101'),
WME('item:1', 'shop', '4'),
WME('item:2', 'cat', '100'),
WME('item:2', 'shop', '1'),
]
for wme in wmes:
net.add_wme(wme)
p0 = rule.rete_p_nodes[0]
assert len(list(p0.activations)) == 1
assert list(p0.activations)[0].binding[V('item')] == 'item:1'