changeset 1612:272f78d4671a

mark skipped tests. move applyRule into Rule. minor cleanups.
author drewp@bigasterisk.com
date Mon, 06 Sep 2021 18:39:38 -0700
parents a794a150a89b
children 03ed8c9abd5b
files service/mqtt_to_rdf/inference.py service/mqtt_to_rdf/inference_test.py
diffstat 2 files changed, 67 insertions(+), 59 deletions(-) [+]
line wrap: on
line diff
--- a/service/mqtt_to_rdf/inference.py	Mon Sep 06 18:18:42 2021 -0700
+++ b/service/mqtt_to_rdf/inference.py	Mon Sep 06 18:39:38 2021 -0700
@@ -94,9 +94,9 @@
         self._logCandidates(orderedVars, orderedValueSets)
 
         log.debug(f'{INDENT*3} trying all permutations:')
-        for perm in itertools.product(*orderedValueSets):
+        for valueSet in itertools.product(*orderedValueSets):
             try:
-                yield BoundLhs(self, CandidateBinding(dict(zip(orderedVars, perm))))
+                yield BoundLhs(self, CandidateBinding(dict(zip(orderedVars, valueSet))))
             except EvaluationFailed:
                 stats['permCountFailingEval'] += 1
 
@@ -212,6 +212,18 @@
     def __post_init__(self):
         self.lhs = Lhs(self.lhsGraph)
 
+    def applyRule(self, workingSet: Graph, implied: Graph, stats: Dict):
+        for bound in self.lhs.findCandidateBindings(ReadOnlyGraphAggregate([workingSet]), stats):
+            log.debug(f'{INDENT*3} rule has a working binding:')
+
+            for lhsBoundStmt in bound.binding.apply(bound.graphWithoutEvals):
+                log.debug(f'{INDENT*5} adding {lhsBoundStmt=}')
+                workingSet.add(lhsBoundStmt)
+            for newStmt in bound.binding.apply(self.rhsGraph):
+                log.debug(f'{INDENT*5} adding {newStmt=}')
+                workingSet.add(newStmt)
+                implied.add(newStmt)
+
 
 class Inference:
 
@@ -223,7 +235,7 @@
         for stmt in g:
             if stmt[1] == LOG['implies']:
                 self.rules.append(Rule(stmt[0], stmt[2]))
-            # others should go to a default working set?
+            # other stmts should go to a default working set?
 
     @INFER_CALLS.time()
     def infer(self, graph: Graph):
@@ -259,9 +271,9 @@
         return implied
 
     def _iterateAllRules(self, workingSet: Graph, implied: Graph, stats):
-        for i, r in enumerate(self.rules):
-            self._logRuleApplicationHeader(workingSet, i, r)
-            _applyRule(r.lhs, r.rhsGraph, workingSet, implied, stats)
+        for i, rule in enumerate(self.rules):
+            self._logRuleApplicationHeader(workingSet, i, rule)
+            rule.applyRule(workingSet, implied, stats)
 
     def _logRuleApplicationHeader(self, workingSet, i, r: Rule):
         if not log.isEnabledFor(logging.DEBUG):
@@ -278,19 +290,6 @@
         log.debug(f'{INDENT*3} rule def rhs: {graphDump(r.rhsGraph)}')
 
 
-def _applyRule(lhs: Lhs, rhs: Graph, workingSet: Graph, implied: Graph, stats: Dict):
-    for bound in lhs.findCandidateBindings(ReadOnlyGraphAggregate([workingSet]), stats):
-        log.debug(f'{INDENT*3} rule has a working binding:')
-
-        for lhsBoundStmt in bound.binding.apply(bound.graphWithoutEvals):
-            log.debug(f'{INDENT*5} adding {lhsBoundStmt=}')
-            workingSet.add(lhsBoundStmt)
-        for newStmt in bound.binding.apply(rhs):
-            log.debug(f'{INDENT*5} adding {newStmt=}')
-            workingSet.add(newStmt)
-            implied.add(newStmt)
-
-
 def graphDump(g: Union[Graph, List[Triple]]):
     if not isinstance(g, Graph):
         log.warning(f"it's a {type(g)}")
@@ -300,7 +299,7 @@
     g.bind('', ROOM)
     g.bind('ex', Namespace('http://example.com/'))
     lines = cast(bytes, g.serialize(format='n3')).decode('utf8').splitlines()
-    lines = [line for line in lines if not line.startswith('@prefix')]
+    lines = [line.strip() for line in lines if not line.startswith('@prefix')]
     return ' '.join(lines)
 
 
--- a/service/mqtt_to_rdf/inference_test.py	Mon Sep 06 18:18:42 2021 -0700
+++ b/service/mqtt_to_rdf/inference_test.py	Mon Sep 06 18:39:38 2021 -0700
@@ -149,6 +149,11 @@
         inf = makeInferenceWithRules("{ (2) math:sum ?x } => { :new :stmt ?x } .")
         self.assertGraphEqual(inf.infer(N3("")), N3(":new :stmt 2 ."))
 
+    @unittest.skip("too hard for now")
+    def test3(self):
+        inf = makeInferenceWithRules("{ :a :b :c . :a :b ?x . } => { :new :stmt ?x } .")
+        self.assertGraphEqual(inf.infer(N3("")), N3(":new :stmt :c ."))
+
 
 class TestInferenceWithMathFunctions(WithGraphEqual):
 
@@ -200,21 +205,22 @@
         out = inf.infer(N3('[] a :MqttMessage ; :body "online" ; :topic :foo .'))
         self.assertIn((EX['frontDoorLockStatus'], EX['connectedStatus'], EX['Online']), out)
 
-#     def testTopicIsList(self):
-#         inf = makeInferenceWithRules('''
-#             { ?msg :body "online" . } => { ?msg :onlineTerm :Online . } .
-#             { ?msg :body "offline" . } => { ?msg :onlineTerm :Offline . } .
+    @unittest.skip("still too slow")
+    def testTopicIsList(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 .
-#             } .
-#         ''')
+            {
+            ?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)
+        out = inf.infer(N3('[] a :MqttMessage ; :body "online" ; :topic ( "frontdoorlock" "status" ) .'))
+        self.assertIn((EX['frontDoorLockStatus'], EX['connectedStatus'], EX['Online']), out)
 
     def testPerformance0(self):
         inf = makeInferenceWithRules('''
@@ -240,28 +246,29 @@
         valueF = cast(Decimal, vlit.toPython())
         self.assertAlmostEqual(float(valueF), 75.02)
 
-#     def testPerformance1(self):
-#         inf = makeInferenceWithRules('''
-#             {
-#               ?msg a :MqttMessage;
-#                 :topic ( "air_quality_indoor" "sensor" "bme280_temperature" "state" );
-#                 :bodyFloat ?valueC .
-#               ?valueC math:greaterThan -999 .
-#               ?valueC :asFarenheit ?valueF .
-#             } => {
-#               :airQualityIndoorTemperature :temperatureF ?valueF .
-#             } .
-#         ''')
-#         out = inf.infer(
-#             N3('''
-#             <urn:uuid:c6e1d92c-0ee1-11ec-bdbd-2a42c4691e9a> a :MqttMessage ;
-#                 :body "23.9" ;
-#                 :bodyFloat 2.39e+01 ;
-#                 :topic ( "air_quality_indoor" "sensor" "bme280_temperature" "state" ) .
-#         '''))
-#         vlit = cast(Literal, out.value(EX['airQualityIndoorTemperature'], EX['temperatureF']))
-#         valueF = cast(Decimal, vlit.toPython())
-#         self.assertAlmostEqual(float(valueF), 75.02)
+    @unittest.skip("still too slow")
+    def testPerformance1(self):
+        inf = makeInferenceWithRules('''
+            {
+              ?msg a :MqttMessage;
+                :topic ( "air_quality_indoor" "sensor" "bme280_temperature" "state" );
+                :bodyFloat ?valueC .
+              ?valueC math:greaterThan -999 .
+              ?valueC :asFarenheit ?valueF .
+            } => {
+              :airQualityIndoorTemperature :temperatureF ?valueF .
+            } .
+        ''')
+        out = inf.infer(
+            N3('''
+            <urn:uuid:c6e1d92c-0ee1-11ec-bdbd-2a42c4691e9a> a :MqttMessage ;
+                :body "23.9" ;
+                :bodyFloat 2.39e+01 ;
+                :topic ( "air_quality_indoor" "sensor" "bme280_temperature" "state" ) .
+        '''))
+        vlit = cast(Literal, out.value(EX['airQualityIndoorTemperature'], EX['temperatureF']))
+        valueF = cast(Decimal, vlit.toPython())
+        self.assertAlmostEqual(float(valueF), 75.02)
 
 
 class TestListPerformance(WithGraphEqual):
@@ -281,10 +288,11 @@
         implied = inf.infer(N3(":a :b (:e0 :e1 :e2) ."))
         self.assertGraphEqual(implied, N3(":new :stmt :here ."))
 
-    # def testList4(self):
-    #     inf = makeInferenceWithRules("{ :a :b (:e0 :e1 :e2 :e3) . } => { :new :stmt :here } .")
-    #     implied = inf.infer(N3(":a :b (:e0 :e1 :e2 :e3) ."))
-    #     self.assertGraphEqual(implied, N3(":new :stmt :here ."))
+    @unittest.skip("still too slow")
+    def testList4(self):
+        inf = makeInferenceWithRules("{ :a :b (:e0 :e1 :e2 :e3) . } => { :new :stmt :here } .")
+        implied = inf.infer(N3(":a :b (:e0 :e1 :e2 :e3) ."))
+        self.assertGraphEqual(implied, N3(":new :stmt :here ."))
 
 
 def fakeStats():
@@ -304,6 +312,7 @@
         cands = list(l.findCandidateBindings(ws, fakeStats()))
         self.assertEqual(len(cands), 1)
 
+    @unittest.skip("still too slow")
     def testListsOnlyMatchEachOther(self):
         l = Lhs(N3(":a :b (:e0 :e1) ."))
         ws = ReadOnlyGraphAggregate([N3(":a :b (:e0 :e1) .")])