# HG changeset patch # User drewp@bigasterisk.com # Date 1630906993 25200 # Node ID abbf0eb0e64014249108bb97bec72ef9323ab786 # Parent 9e6a593180b6b8db5e21d1bddef5ee2764d8a699 fix a bug with a slightly moer complicated set of rules diff -r 9e6a593180b6 -r abbf0eb0e640 service/mqtt_to_rdf/inference.py --- a/service/mqtt_to_rdf/inference.py Sun Sep 05 22:40:50 2021 -0700 +++ b/service/mqtt_to_rdf/inference.py Sun Sep 05 22:43:13 2021 -0700 @@ -33,6 +33,12 @@ """e.g. we were given (5 math:greaterThan 6)""" +class BindingUnknown(ValueError): + """e.g. we were asked to make the bound version + of (A B ?c) and we don't have a binding for ?c + """ + + @dataclass class CandidateBinding: binding: Dict[BindableTerm, Node] @@ -43,12 +49,18 @@ def apply(self, g: Graph) -> Iterator[Triple]: for stmt in g: - yield (self._applyTerm(stmt[0]), self._applyTerm(stmt[1]), self._applyTerm(stmt[2])) + try: + bound = (self._applyTerm(stmt[0]), self._applyTerm(stmt[1]), self._applyTerm(stmt[2])) + except BindingUnknown: + continue + yield bound def _applyTerm(self, term: Node): if isinstance(term, (Variable, BNode)): if term in self.binding: return self.binding[term] + else: + raise BindingUnknown() return term def applyFunctions(self, lhs) -> Graph: @@ -310,7 +322,11 @@ self.rules = ConjunctiveGraph() def setRules(self, g: ConjunctiveGraph): - self.rules = g + self.rules = ConjunctiveGraph() + for stmt in g: + if stmt[1] == LOG['implies']: + self.rules.add(stmt) + # others should go to a default working set? def infer(self, graph: Graph): """ @@ -342,10 +358,7 @@ def _iterateAllRules(self, workingSet: Graph, implied: Graph): for i, r in enumerate(self.rules): self.logRuleApplicationHeader(workingSet, i, r) - if r[1] == LOG['implies']: - applyRule(Lhs(r[0]), r[2], workingSet, implied) - else: - log.info(f'{INDENT*2} {r} not a rule?') + applyRule(Lhs(r[0]), r[2], workingSet, implied) def logRuleApplicationHeader(self, workingSet, i, r): if not log.isEnabledFor(logging.DEBUG): diff -r 9e6a593180b6 -r abbf0eb0e640 service/mqtt_to_rdf/inference_test.py --- a/service/mqtt_to_rdf/inference_test.py Sun Sep 05 22:40:50 2021 -0700 +++ b/service/mqtt_to_rdf/inference_test.py Sun Sep 05 22:43:13 2021 -0700 @@ -198,3 +198,38 @@ (bn, RDF.first, Literal(0)), (bn, RDF.rest, RDF.nil), ]) + + +class TestUseCases(WithGraphEqual): + + def testSimpleTopic(self): + inf = makeInferenceWithRules(''' +{ ?msg :body "online" . } => { ?msg :onlineTerm :Online . } . + { ?msg :body "offline" . } => { ?msg :onlineTerm :Offline . } . + +{ + ?msg a :MqttMessage ; + :topic :foo; + :onlineTerm ?onlineness . } => { + :frontDoorLockStatus :connectedStatus ?onlineness . +} . + ''') + + out = inf.infer(N3('[] a :MqttMessage ; :body "online" ; :topic :foo .')) + self.assertIn((EX['frontDoorLockStatus'], EX['connectedStatus'], EX['Online']), out) + + def testTopicIsListhg(self): + inf = makeInferenceWithRules(''' +{ ?msg :body "online" . } => { ?msg :onlineTerm :Online . } . +{ ?msg :body "offline" . } => { ?msg :onlineTerm :Offline . } . + +{ + ?msg a :MqttMessage ; + :topic ( "frontdoorlock" "status" ); + :onlineTerm ?onlineness . } => { + :frontDoorLockStatus :connectedStatus ?onlineness . +} . + ''') + + out = inf.infer(N3('[] a :MqttMessage ; :body "online" ; :topic ( "frontdoorlock" "status" ) .')) + self.assertIn((EX['frontDoorLockStatus'], EX['connectedStatus'], EX['Online']), out)