def reset(self, **kwargs): """ Performs a reset as per CLIPS behaviour (resets the agenda and factlist and declares InitialFact()) Any keyword argument passed to `reset` will be passed to @DefFacts which have those arguments on their signature. .. note:: If persistent facts have been added, they'll be re-declared. """ self.agenda = Agenda() self.facts = FactList() self.matcher.reset() deffacts = [] for deffact in self.get_deffacts(): signature = inspect.signature(deffact) if not any(p.kind == inspect.Parameter.VAR_KEYWORD for p in signature.parameters.values()): # There is not **kwargs defined. Pass only the defined # names. args = set(signature.parameters.keys()) deffacts.append( deffact(**{k: v for k, v in kwargs.items() if k in args})) else: deffacts.append(deffact(**kwargs)) # Declare all facts yielded by deffacts self.__declare(*chain.from_iterable(deffacts)) self.running = False
def test_factlist_declare_raises_valueError(): """ declare raises valueerror if not ``Fact`` object providen """ from experta.factlist import FactList import pytest with pytest.raises(ValueError): FactList().declare("Foo")
def test_factlist_declare(): """ Test declare method adds to factlist and updates index """ from experta.factlist import FactList from experta import Fact flist = FactList() assert getattr(flist, "last_index") == 0 assert not flist flist.declare(Fact()) assert getattr(flist, "last_index") == 1 assert isinstance(flist[0], Fact)
def test_factlist_raises_valueerror_on_invalid_fact(): from experta.factlist import FactList from experta import Fact, Field class MockFact(Fact): must_be_string = Field(str, mandatory=True) flist = FactList() f0 = MockFact(must_be_string=0) with pytest.raises(ValueError): flist.declare(f0)
def test_factlist_retract(): """ Test retract method """ from experta.factlist import FactList from experta import Fact flist = FactList() assert getattr(flist, "last_index") == 0 assert not flist flist.declare(Fact()) assert getattr(flist, "last_index") == 1 assert isinstance(flist[0], Fact) assert flist.retract(0) == 0 assert not flist
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]
def __init__(self): self.running = False self.facts = FactList() self.agenda = Agenda() if (isinstance(self.__matcher__, type) and issubclass(self.__matcher__, abstract.Matcher)): self.matcher = self.__matcher__(self) else: raise TypeError("__matcher__ must be a subclass of Matcher") if (isinstance(self.__strategy__, type) and issubclass(self.__strategy__, abstract.Strategy)): self.strategy = self.__strategy__() else: raise TypeError("__strategy__ must be a subclass of Strategy")
def test_DepthStrategy_update_agenda_asertion_order_affects_agenda_order_3(): """ From Clips docs on Depth Strategy:: Newly activated rules are placed above all rules of the same salience. For example, given that facta activates rule1 and rule2 and factb activates rule3 and rule4, then if facta is asserted before factb, rule3 and rule4 will be above rule1 and rule2 on the agenda. However, the position of rule1 relative to rule2 and rule3 relative to rule4 will be arbitrary. """ from experta.strategies import DepthStrategy from experta.activation import Activation from experta import Rule from experta.agenda import Agenda from experta import Fact from experta.factlist import FactList fl = FactList() f1 = Fact(1) fl.declare(f1) f2 = Fact(2) fl.declare(f2) act1 = Activation(rule=Rule(), facts=(f1, )) act2 = Activation(rule=Rule(), facts=(f1, )) act3 = Activation(rule=Rule(), facts=(f2, )) act4 = Activation(rule=Rule(), facts=(f2, )) a = Agenda() st = DepthStrategy() st.update_agenda(a, [act1, act2, act3, act4], []) order = list(a.activations) assert (order.index(act4) > order.index(act1) and order.index(act4) > order.index(act2)) assert (order.index(act3) > order.index(act1) and order.index(act3) > order.index(act2))
def test_DepthStrategy_update_agenda_different_salience(): from random import shuffle from experta.strategies import DepthStrategy from experta.activation import Activation from experta import Rule from experta import Fact from experta.agenda import Agenda from experta.factlist import FactList flist = FactList() f1 = Fact(1) flist.declare(f1) f2 = Fact(2) flist.declare(f2) f3 = Fact(3) flist.declare(f3) f4 = Fact(4) flist.declare(f4) act1 = Activation(rule=Rule(salience=1), facts=(f1, )) act2 = Activation(rule=Rule(salience=2), facts=(f2, )) act3 = Activation(rule=Rule(salience=3), facts=(f3, )) act4 = Activation(rule=Rule(salience=4), facts=(f4, )) acts = [act1, act2, act3, act4] shuffle(acts) st = DepthStrategy() a = Agenda() for act in acts: st.update_agenda(a, acts, []) order = list(a.activations) assert (order.index(act4) > order.index(act3) > order.index(act2) > order.index(act1))
def test_DepthStrategy_update_agenda_assertion_order_affects_agenda_order_1(): from experta.strategies import DepthStrategy from experta.activation import Activation from experta import Rule from experta.agenda import Agenda from experta import Fact from experta.factlist import FactList fl = FactList() f1 = Fact(1) fl.declare(f1) f2 = Fact(2) fl.declare(f2) f3 = Fact(3) fl.declare(f3) f4 = Fact(4) fl.declare(f4) act1 = Activation(rule=Rule(), facts=(f1, )) act2 = Activation(rule=Rule(), facts=(f2, )) first = [act1, act2] act3 = Activation(rule=Rule(), facts=(f3, )) act4 = Activation(rule=Rule(), facts=(f4, )) second = [act3, act4] a = Agenda() st = DepthStrategy() st.update_agenda(a, first, []) assert a.activations == first st.update_agenda(a, second, first) assert a.activations == second
def test_DepthStrategy_update_agenda_activations_to_agenda(): from experta.strategies import DepthStrategy from experta.activation import Activation from experta import Rule from experta.agenda import Agenda from experta import Fact from experta.factlist import FactList fl = FactList() f1 = Fact(1) fl.declare(f1) f2 = Fact(2) fl.declare(f2) act1 = Activation(rule=Rule(), facts=(f1, )) act2 = Activation(rule=Rule(), facts=(f2, )) a = Agenda() st = DepthStrategy() st.update_agenda(a, [act1, act2], []) assert act1 in a.activations assert act2 in a.activations
def test_factlist_facts_idx_starts_zero(): """ Factlist idx starts at zero """ from experta.factlist import FactList assert getattr(FactList(), "last_index") == 0