Mercurial > code > home > repos > homeauto
changeset 1599:abbf0eb0e640
fix a bug with a slightly moer complicated set of rules
author | drewp@bigasterisk.com |
---|---|
date | Sun, 05 Sep 2021 22:43:13 -0700 |
parents | 9e6a593180b6 |
children | 89a50242cb5e |
files | service/mqtt_to_rdf/inference.py service/mqtt_to_rdf/inference_test.py |
diffstat | 2 files changed, 54 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- 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):
--- 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)