0

I have the following code, and the Experta engine gives unexpected output: None. Is the P predicate function applied correctly?

from experta import Fact, KnowledgeEngine, L, AS, Rule, P, AND



class QuoteFact(Fact):
    """Info about the traffic light."""
    pass


class GoodSymbolFact(Fact):
    pass


class _RuleEngine(KnowledgeEngine):
    @Rule(
        QuoteFact(P(lambda x: float(x.price) > 1.00))
    )
    def accept(self, quote_fact):
        good_symbol_fact = GoodSymbolFact(symbol=quote_fact.symbol)
        self.declare(good_symbol_fact)


_engine = _RuleEngine()
_engine.reset()
_engine.declare(QuoteFact(price=100.00, symbol="AAPL"))

result = _engine.run()
print(result)
user1187968
  • 7,154
  • 16
  • 81
  • 152

1 Answers1

0

If you look at the source code of the run method you'll see that it doesn't return anything. So result will always be None. If you want to access the facts declared in your engine, you can simply loop over them:

from experta import Fact, KnowledgeEngine, L, AS, Rule, P, AND

class QuoteFact(Fact):
    """Info about the traffic light."""
    pass

class GoodSymbolFact(Fact):
    pass

class _RuleEngine(KnowledgeEngine):
    @Rule(
        QuoteFact(P(lambda x: float(x.price) > 1.00))
    )
    def accept(self, quote_fact):
        good_symbol_fact = GoodSymbolFact(symbol=quote_fact.symbol)
        self.declare(good_symbol_fact)

_engine = _RuleEngine()
_engine.reset()
_engine.declare(QuoteFact(price=100.00, symbol="AAPL"))

_engine.run()
for fact in _engine.facts.items():
    print(fact)

Output:

(0, InitialFact())
(1, QuoteFact(price=100.0, symbol='AAPL'))

Note: alternatively, you can keep track of the added facts by letting your rules print some stuff when they run, just like in the examples in the README.

Tranbi
  • 11,407
  • 6
  • 16
  • 33