changeset 1636:3252bdc284bc

rm dead code from previous tries
author drewp@bigasterisk.com
date Mon, 13 Sep 2021 00:18:47 -0700
parents 22d481f0a924
children ec3f98d0c1d8
files service/mqtt_to_rdf/inference.py service/mqtt_to_rdf/lhs_evaluation.py
diffstat 2 files changed, 7 insertions(+), 253 deletions(-) [+]
line wrap: on
line diff
--- a/service/mqtt_to_rdf/inference.py	Mon Sep 13 00:06:00 2021 -0700
+++ b/service/mqtt_to_rdf/inference.py	Mon Sep 13 00:18:47 2021 -0700
@@ -15,8 +15,8 @@
 from rdflib.term import Literal, Node, Variable
 
 from candidate_binding import CandidateBinding
-from inference_types import (BindableTerm, BindingUnknown, EvaluationFailed, ReadOnlyWorkingSet, Triple)
-from lhs_evaluation import Decimal, Evaluation, numericNode, parseList
+from inference_types import (BindableTerm, BindingUnknown, ReadOnlyWorkingSet, Triple)
+from lhs_evaluation import Decimal, numericNode, parseList
 
 log = logging.getLogger('infer')
 INDENT = '    '
@@ -233,10 +233,6 @@
             raise NotImplementedError()
         return self._current
 
-    def newLhsStmts(self) -> List[Triple]:
-        """under the curent bindings, what new stmts beyond workingSet are also true? includes all `prev`"""
-        return []
-
     def pastEnd(self) -> bool:
         return self._pastEnd
 
@@ -253,24 +249,7 @@
     graph: Graph
 
     def __post_init__(self):
-        # do precomputation in here that's not specific to the workingSet
-        # self.staticRuleStmts = Graph()
-        # self.nonStaticRuleStmts = Graph()
-
-        # self.lhsBindables: Set[BindableTerm] = set()
-        # self.lhsBnodes: Set[BNode] = set()
-        # for ruleStmt in self.graph:
-        #     varsAndBnodesInStmt = [term for term in ruleStmt if isinstance(term, (Variable, BNode))]
-        #     self.lhsBindables.update(varsAndBnodesInStmt)
-        #     self.lhsBnodes.update(x for x in varsAndBnodesInStmt if isinstance(x, BNode))
-        #     if not varsAndBnodesInStmt:
-        #         self.staticRuleStmts.add(ruleStmt)
-        #     else:
-        #         self.nonStaticRuleStmts.add(ruleStmt)
-
-        # self.nonStaticRuleStmtsSet = set(self.nonStaticRuleStmts)
-
-        self.evaluations = list(Evaluation.findEvals(self.graph))
+        pass
 
     def __repr__(self):
         return f"Lhs({graphDump(self.graph)})"
@@ -380,151 +359,12 @@
             log.debug(f'{INDENT*5} some rings started at pastEnd {stmtStack}')
             raise NoOptions()
 
-    def _allStaticStatementsMatch(self, knownTrue: ReadOnlyWorkingSet) -> bool:
-        # bug: see TestSelfFulfillingRule.test3 for a case where this rule's
-        # static stmt is matched by a non-static stmt in the rule itself
-        for ruleStmt in self.staticRuleStmts:
-            if ruleStmt not in knownTrue:
-                log.debug(f'{INDENT*3} {ruleStmt} not in working set- skip rule')
-                return False
-        return True
-
-    def _possibleBindings(self, workingSet, stats) -> Iterator['BoundLhs']:
-        """this yields at least the working bindings, and possibly others"""
-        candidateTermMatches: Dict[BindableTerm, Set[Node]] = self._allCandidateTermMatches(workingSet)
-        for bindRow in self._product(candidateTermMatches):
-            try:
-                yield BoundLhs(self, bindRow)
-            except EvaluationFailed:
-                stats['permCountFailingEval'] += 1
-
-    def _allCandidateTermMatches(self, workingSet: ReadOnlyWorkingSet) -> Dict[BindableTerm, Set[Node]]:
-        """the total set of terms each variable could possibly match"""
-
-        candidateTermMatches: Dict[BindableTerm, Set[Node]] = defaultdict(set)
-        for lhsStmt in self.graph:
-            log.debug(f'{INDENT*4} possibles for this lhs stmt: {lhsStmt}')
-            for i, trueStmt in enumerate(workingSet):
-                # log.debug(f'{INDENT*5} consider this true stmt ({i}): {trueStmt}')
-
-                for v, vals in self._bindingsFromStatement(lhsStmt, trueStmt):
-                    candidateTermMatches[v].update(vals)
-
-        return candidateTermMatches
-
-    def _bindingsFromStatement(self, stmt1: Triple, stmt2: Triple) -> Iterator[Tuple[Variable, Set[Node]]]:
-        """if these stmts match otherwise, what BNode or Variable mappings do we learn?
-        
-        e.g. stmt1=(?x B ?y) and stmt2=(A B C), then we yield (?x, {A}) and (?y, {C})
-        or   stmt1=(_:x B C) and stmt2=(A B C), then we yield (_:x, {A})
-        or   stmt1=(?x B C)  and stmt2=(A B D), then we yield nothing
-        """
-        bindingsFromStatement = {}
-        for term1, term2 in zip(stmt1, stmt2):
-            if isinstance(term1, (BNode, Variable)):
-                bindingsFromStatement.setdefault(term1, set()).add(term2)
-            elif term1 != term2:
-                break
-        else:
-            for v, vals in bindingsFromStatement.items():
-                log.debug(f'{INDENT*5} {v=} {vals=}')
-                yield v, vals
-
-    def _product(self, candidateTermMatches: Dict[BindableTerm, Set[Node]]) -> Iterator[CandidateBinding]:
-        orderedVars, orderedValueSets = _organize(candidateTermMatches)
-        self._logCandidates(orderedVars, orderedValueSets)
-        log.debug(f'{INDENT*3} trying all permutations:')
-        if not orderedValueSets:
-            yield CandidateBinding({})
-            return
-
-        if not orderedValueSets or not all(orderedValueSets):
-            # some var or bnode has no options at all
-            return
-        rings: List[Iterator[Node]] = [itertools.cycle(valSet) for valSet in orderedValueSets]
-        currentSet: List[Node] = [next(ring) for ring in rings]
-        starts = [valSet[-1] for valSet in orderedValueSets]
-        while True:
-            for col, curr in enumerate(currentSet):
-                currentSet[col] = next(rings[col])
-                log.debug(f'{INDENT*4} currentSet: {repr(currentSet)}')
-                yield CandidateBinding(dict(zip(orderedVars, currentSet)))
-                if curr is not starts[col]:
-                    break
-                if col == len(orderedValueSets) - 1:
-                    return
-
-    def _logCandidates(self, orderedVars, orderedValueSets):
-        if not log.isEnabledFor(logging.DEBUG):
-            return
-        log.debug(f'{INDENT*3} resulting candidate terms:')
-        for v, vals in zip(orderedVars, orderedValueSets):
-            log.debug(f'{INDENT*4} {v!r} could be:')
-            for val in vals:
-                log.debug(f'{INDENT*5}{val!r}')
-
 
 @dataclass
 class BoundLhs:
     lhs: Lhs
     binding: CandidateBinding
 
-    def __post_init__(self):
-        self.usedByFuncs = Graph()
-        # self._applyFunctions()
-
-    def lhsStmtsWithoutEvals(self):
-        for stmt in self.lhs.graph:
-            if stmt in self.usedByFuncs:
-                continue
-            yield stmt
-
-    def _applyFunctions(self):
-        """may grow the binding with some results"""
-        while True:
-            delta = self._applyFunctionsIteration()
-            if delta == 0:
-                break
-
-    def _applyFunctionsIteration(self):
-        before = len(self.binding.binding)
-        delta = 0
-        for ev in self.lhs.evaluations:
-            newBindings, usedGraph = ev.resultBindings(self.binding)
-            self.usedByFuncs += usedGraph
-            self.binding.addNewBindings(newBindings)
-        delta = len(self.binding.binding) - before
-        log.debug(f'{INDENT*4} eval rules made {delta} new bindings')
-        return delta
-
-    def verify(self, workingSet: ReadOnlyWorkingSet) -> bool:
-        """Can this bound lhs be true all at once in workingSet?"""
-        rem = cast(Set[Triple], self.lhs.nonStaticRuleStmtsSet.difference(self.usedByFuncs))
-        boundLhs = self.binding.apply(rem)
-
-        if log.isEnabledFor(logging.DEBUG):
-            boundLhs = list(boundLhs)
-            self._logVerifyBanner(boundLhs, workingSet)
-
-        for stmt in boundLhs:
-            log.debug(f'{INDENT*4} check for %s', stmt)
-
-            if stmt not in workingSet:
-                log.debug(f'{INDENT*5} stmt not known to be true')
-                return False
-        return True
-
-    def _logVerifyBanner(self, boundLhs, workingSet: ReadOnlyWorkingSet):
-        log.debug(f'{INDENT*4}/ verify all bindings against this boundLhs:')
-        for stmt in sorted(boundLhs):
-            log.debug(f'{INDENT*4}|{INDENT} {stmt}')
-
-        # log.debug(f'{INDENT*4}| and against this workingSet:')
-        # for stmt in sorted(workingSet):
-        #     log.debug(f'{INDENT*4}|{INDENT} {stmt}')
-
-        log.debug(f'{INDENT*4}\\')
-
 
 @dataclass
 class Rule:
@@ -647,17 +487,3 @@
     lines = cast(bytes, g.serialize(format='n3')).decode('utf8').splitlines()
     lines = [line.strip() for line in lines if not line.startswith('@prefix')]
     return ' '.join(lines)
-
-
-def _organize(candidateTermMatches: Dict[BindableTerm, Set[Node]]) -> Tuple[List[BindableTerm], List[List[Node]]]:
-    items = list(candidateTermMatches.items())
-    items.sort()
-    orderedVars: List[BindableTerm] = []
-    orderedValueSets: List[List[Node]] = []
-    for v, vals in items:
-        orderedVars.append(v)
-        orderedValues: List[Node] = list(vals)
-        orderedValues.sort(key=str)
-        orderedValueSets.append(orderedValues)
-
-    return orderedVars, orderedValueSets
--- a/service/mqtt_to_rdf/lhs_evaluation.py	Mon Sep 13 00:06:00 2021 -0700
+++ b/service/mqtt_to_rdf/lhs_evaluation.py	Mon Sep 13 00:18:47 2021 -0700
@@ -1,14 +1,12 @@
 import logging
 from decimal import Decimal
-from typing import Dict, Iterable, Iterator, List, Set, Tuple
+from typing import List, Set, Tuple
 
 from prometheus_client import Summary
-from rdflib import RDF, Graph, Literal, Namespace, URIRef
-from rdflib.term import Node, Variable
+from rdflib import RDF, Literal, Namespace, URIRef
+from rdflib.term import Node
 
-from candidate_binding import CandidateBinding
-from inference import CandidateBinding
-from inference_types import BindableTerm, EvaluationFailed, Triple
+from inference_types import Triple
 
 log = logging.getLogger('infer')
 
@@ -18,76 +16,6 @@
 LOG = Namespace('http://www.w3.org/2000/10/swap/log#')
 MATH = Namespace('http://www.w3.org/2000/10/swap/math#')
 
-# Graph() makes a BNode if you don't pass
-# identifier, which can be a bottleneck.
-GRAPH_ID = URIRef('dont/care')
-
-
-# alternate name LhsComponent
-class Evaluation:
-    """some lhs statements need to be evaluated with a special function 
-    (e.g. math) and then not considered for the rest of the rule-firing 
-    process. It's like they already 'matched' something, so they don't need
-    to match a statement from the known-true working set.
-    
-    One Evaluation instance is for one function call.
-    """
-
-    @staticmethod
-    def findEvals(graph: Graph) -> Iterator['Evaluation']:
-        for stmt in graph.triples((None, MATH['sum'], None)):
-            operands, operandsStmts = parseList(graph, stmt[0])
-            yield Evaluation(operands, stmt, operandsStmts)
-
-        for stmt in graph.triples((None, MATH['greaterThan'], None)):
-            yield Evaluation([stmt[0], stmt[2]], stmt, [])
-
-        for stmt in graph.triples((None, ROOM['asFarenheit'], None)):
-            yield Evaluation([stmt[0]], stmt, [])
-
-    # internal, use findEvals
-    def __init__(self, operands: List[Node], mainStmt: Triple, otherStmts: Iterable[Triple]) -> None:
-        self.operands = operands
-        self.operandsStmts = Graph(identifier=GRAPH_ID)
-        self.operandsStmts += otherStmts  # may grow
-        self.operandsStmts.add(mainStmt)
-        self.stmt = mainStmt
-
-    def resultBindings(self, inputBindings: CandidateBinding) -> Tuple[CandidateBinding, Graph]:
-        """under the bindings so far, what would this evaluation tell us, and which stmts would be consumed from doing so?"""
-        pred = self.stmt[1]
-        objVar: Node = self.stmt[2]
-        boundOperands = []
-        for op in self.operands:
-            if isinstance(op, Variable):
-                try:
-                    op = inputBindings.binding[op]
-                except KeyError:
-                    return CandidateBinding(binding={}), self.operandsStmts
-
-            boundOperands.append(op)
-
-        if pred == MATH['sum']:
-            obj = Literal(sum(map(numericNode, boundOperands)))
-            if not isinstance(objVar, Variable):
-                raise TypeError(f'expected Variable, got {objVar!r}')
-            res = CandidateBinding({objVar: obj})
-        elif pred == ROOM['asFarenheit']:
-            if len(boundOperands) != 1:
-                raise ValueError(":asFarenheit takes 1 subject operand")
-            f = Literal(Decimal(numericNode(boundOperands[0])) * 9 / 5 + 32)
-            if not isinstance(objVar, Variable):
-                raise TypeError(f'expected Variable, got {objVar!r}')
-            res = CandidateBinding({objVar: f})
-        elif pred == MATH['greaterThan']:
-            if not (numericNode(boundOperands[0]) > numericNode(boundOperands[1])):
-                raise EvaluationFailed()
-            res= CandidateBinding({})
-        else:
-            raise NotImplementedError(repr(pred))
-
-        return res, self.operandsStmts
-
 
 def numericNode(n: Node):
     if not isinstance(n, Literal):