comparison service/mqtt_to_rdf/inference.py @ 1640:4bb6f593ebf3

speedups: abort some rules faster
author drewp@bigasterisk.com
date Wed, 15 Sep 2021 23:56:02 -0700
parents ae5ca4ba8954
children 5403c6343fa4
comparison
equal deleted inserted replaced
1639:ae5ca4ba8954 1640:4bb6f593ebf3
10 from typing import (Dict, Iterator, List, Optional, Sequence, Set, Tuple, Union, cast) 10 from typing import (Dict, Iterator, List, Optional, Sequence, Set, Tuple, Union, cast)
11 11
12 from prometheus_client import Histogram, Summary 12 from prometheus_client import Histogram, Summary
13 from rdflib import RDF, BNode, Graph, Namespace 13 from rdflib import RDF, BNode, Graph, Namespace
14 from rdflib.graph import ConjunctiveGraph, ReadOnlyGraphAggregate 14 from rdflib.graph import ConjunctiveGraph, ReadOnlyGraphAggregate
15 from rdflib.term import Node, Variable 15 from rdflib.term import Node, URIRef, Variable
16 16
17 from candidate_binding import BindingConflict, CandidateBinding 17 from candidate_binding import BindingConflict, CandidateBinding
18 from inference_types import BindingUnknown, ReadOnlyWorkingSet, Triple 18 from inference_types import BindingUnknown, ReadOnlyWorkingSet, Triple
19 from lhs_evaluation import functionsFor, lhsStmtsUsedByFuncs 19 from lhs_evaluation import functionsFor, lhsStmtsUsedByFuncs, rulePredicates
20 20
21 log = logging.getLogger('infer') 21 log = logging.getLogger('infer')
22 INDENT = ' ' 22 INDENT = ' '
23 23
24 INFER_CALLS = Summary('inference_infer_calls', 'calls') 24 INFER_CALLS = Summary('inference_infer_calls', 'calls')
130 return True 130 return True
131 return False 131 return False
132 132
133 def _advanceWithFunctions(self) -> bool: 133 def _advanceWithFunctions(self) -> bool:
134 pred: Node = self.lhsStmt[1] 134 pred: Node = self.lhsStmt[1]
135 if not isinstance(pred, URIRef):
136 raise NotImplementedError
135 137
136 for functionType in functionsFor(pred): 138 for functionType in functionsFor(pred):
137 fn = functionType(self.lhsStmt, self.parent.graph) 139 fn = functionType(self.lhsStmt, self.parent.graph)
138 try: 140 try:
139 out = fn.bind(self._prevBindings()) 141 out = fn.bind(self._prevBindings())
203 if self.graph.__len__() == 0: 205 if self.graph.__len__() == 0:
204 # special case- no LHS! 206 # special case- no LHS!
205 yield BoundLhs(self, CandidateBinding({})) 207 yield BoundLhs(self, CandidateBinding({}))
206 return 208 return
207 209
210 if self._checkPredicateCounts(knownTrue):
211 stats['_checkPredicateCountsCulls'] += 1
212 return
213
208 log.debug(f'{INDENT*4} build new StmtLooper stack') 214 log.debug(f'{INDENT*4} build new StmtLooper stack')
209 215
210 try: 216 try:
211 stmtStack = self._assembleRings(knownTrue) 217 stmtStack = self._assembleRings(knownTrue)
212 except NoOptions: 218 except NoOptions:
238 244
239 def _debugStmtStack(self, label, stmtStack): 245 def _debugStmtStack(self, label, stmtStack):
240 log.debug(f'{INDENT*5} {label}:') 246 log.debug(f'{INDENT*5} {label}:')
241 for l in stmtStack: 247 for l in stmtStack:
242 log.debug(f'{INDENT*6} {l} curbind={l.currentBinding() if not l.pastEnd() else "<end>"}') 248 log.debug(f'{INDENT*6} {l} curbind={l.currentBinding() if not l.pastEnd() else "<end>"}')
249
250 def _checkPredicateCounts(self, knownTrue):
251 """raise NoOptions quickly in some cases"""
252 myPreds = set(p for s, p, o in self.graph if isinstance(p, URIRef))
253 myPreds -= rulePredicates()
254 myPreds -= {RDF.first, RDF.rest}
255 if any((None, p, None) not in knownTrue for p in set(myPreds)):
256 return True
257 return False
243 258
244 def _assembleRings(self, knownTrue: ReadOnlyWorkingSet) -> List[StmtLooper]: 259 def _assembleRings(self, knownTrue: ReadOnlyWorkingSet) -> List[StmtLooper]:
245 """make StmtLooper for each stmt in our LHS graph, but do it in a way that they all 260 """make StmtLooper for each stmt in our LHS graph, but do it in a way that they all
246 start out valid (or else raise NoOptions)""" 261 start out valid (or else raise NoOptions)"""
247 262