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)