comparison service/mqtt_to_rdf/inference.py @ 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
comparison
equal deleted inserted replaced
1611:a794a150a89b 1612:272f78d4671a
92 92
93 orderedVars, orderedValueSets = _organize(candidateTermMatches) 93 orderedVars, orderedValueSets = _organize(candidateTermMatches)
94 self._logCandidates(orderedVars, orderedValueSets) 94 self._logCandidates(orderedVars, orderedValueSets)
95 95
96 log.debug(f'{INDENT*3} trying all permutations:') 96 log.debug(f'{INDENT*3} trying all permutations:')
97 for perm in itertools.product(*orderedValueSets): 97 for valueSet in itertools.product(*orderedValueSets):
98 try: 98 try:
99 yield BoundLhs(self, CandidateBinding(dict(zip(orderedVars, perm)))) 99 yield BoundLhs(self, CandidateBinding(dict(zip(orderedVars, valueSet))))
100 except EvaluationFailed: 100 except EvaluationFailed:
101 stats['permCountFailingEval'] += 1 101 stats['permCountFailingEval'] += 1
102 102
103 def _allCandidateTermMatches(self, workingSet: ReadOnlyWorkingSet) -> Dict[BindableTerm, Set[Node]]: 103 def _allCandidateTermMatches(self, workingSet: ReadOnlyWorkingSet) -> Dict[BindableTerm, Set[Node]]:
104 """the total set of terms each variable could possibly match""" 104 """the total set of terms each variable could possibly match"""
210 rhsGraph: Graph 210 rhsGraph: Graph
211 211
212 def __post_init__(self): 212 def __post_init__(self):
213 self.lhs = Lhs(self.lhsGraph) 213 self.lhs = Lhs(self.lhsGraph)
214 214
215 def applyRule(self, workingSet: Graph, implied: Graph, stats: Dict):
216 for bound in self.lhs.findCandidateBindings(ReadOnlyGraphAggregate([workingSet]), stats):
217 log.debug(f'{INDENT*3} rule has a working binding:')
218
219 for lhsBoundStmt in bound.binding.apply(bound.graphWithoutEvals):
220 log.debug(f'{INDENT*5} adding {lhsBoundStmt=}')
221 workingSet.add(lhsBoundStmt)
222 for newStmt in bound.binding.apply(self.rhsGraph):
223 log.debug(f'{INDENT*5} adding {newStmt=}')
224 workingSet.add(newStmt)
225 implied.add(newStmt)
226
215 227
216 class Inference: 228 class Inference:
217 229
218 def __init__(self) -> None: 230 def __init__(self) -> None:
219 self.rules = [] 231 self.rules = []
221 def setRules(self, g: ConjunctiveGraph): 233 def setRules(self, g: ConjunctiveGraph):
222 self.rules: List[Rule] = [] 234 self.rules: List[Rule] = []
223 for stmt in g: 235 for stmt in g:
224 if stmt[1] == LOG['implies']: 236 if stmt[1] == LOG['implies']:
225 self.rules.append(Rule(stmt[0], stmt[2])) 237 self.rules.append(Rule(stmt[0], stmt[2]))
226 # others should go to a default working set? 238 # other stmts should go to a default working set?
227 239
228 @INFER_CALLS.time() 240 @INFER_CALLS.time()
229 def infer(self, graph: Graph): 241 def infer(self, graph: Graph):
230 """ 242 """
231 returns new graph of inferred statements. 243 returns new graph of inferred statements.
257 for st in implied: 269 for st in implied:
258 log.info(f'{INDENT*1} {st}') 270 log.info(f'{INDENT*1} {st}')
259 return implied 271 return implied
260 272
261 def _iterateAllRules(self, workingSet: Graph, implied: Graph, stats): 273 def _iterateAllRules(self, workingSet: Graph, implied: Graph, stats):
262 for i, r in enumerate(self.rules): 274 for i, rule in enumerate(self.rules):
263 self._logRuleApplicationHeader(workingSet, i, r) 275 self._logRuleApplicationHeader(workingSet, i, rule)
264 _applyRule(r.lhs, r.rhsGraph, workingSet, implied, stats) 276 rule.applyRule(workingSet, implied, stats)
265 277
266 def _logRuleApplicationHeader(self, workingSet, i, r: Rule): 278 def _logRuleApplicationHeader(self, workingSet, i, r: Rule):
267 if not log.isEnabledFor(logging.DEBUG): 279 if not log.isEnabledFor(logging.DEBUG):
268 return 280 return
269 281
274 286
275 log.debug('') 287 log.debug('')
276 log.debug(f'{INDENT*2}-applying rule {i}') 288 log.debug(f'{INDENT*2}-applying rule {i}')
277 log.debug(f'{INDENT*3} rule def lhs: {graphDump(r.lhsGraph)}') 289 log.debug(f'{INDENT*3} rule def lhs: {graphDump(r.lhsGraph)}')
278 log.debug(f'{INDENT*3} rule def rhs: {graphDump(r.rhsGraph)}') 290 log.debug(f'{INDENT*3} rule def rhs: {graphDump(r.rhsGraph)}')
279
280
281 def _applyRule(lhs: Lhs, rhs: Graph, workingSet: Graph, implied: Graph, stats: Dict):
282 for bound in lhs.findCandidateBindings(ReadOnlyGraphAggregate([workingSet]), stats):
283 log.debug(f'{INDENT*3} rule has a working binding:')
284
285 for lhsBoundStmt in bound.binding.apply(bound.graphWithoutEvals):
286 log.debug(f'{INDENT*5} adding {lhsBoundStmt=}')
287 workingSet.add(lhsBoundStmt)
288 for newStmt in bound.binding.apply(rhs):
289 log.debug(f'{INDENT*5} adding {newStmt=}')
290 workingSet.add(newStmt)
291 implied.add(newStmt)
292 291
293 292
294 def graphDump(g: Union[Graph, List[Triple]]): 293 def graphDump(g: Union[Graph, List[Triple]]):
295 if not isinstance(g, Graph): 294 if not isinstance(g, Graph):
296 log.warning(f"it's a {type(g)}") 295 log.warning(f"it's a {type(g)}")
298 g2 += g 297 g2 += g
299 g = g2 298 g = g2
300 g.bind('', ROOM) 299 g.bind('', ROOM)
301 g.bind('ex', Namespace('http://example.com/')) 300 g.bind('ex', Namespace('http://example.com/'))
302 lines = cast(bytes, g.serialize(format='n3')).decode('utf8').splitlines() 301 lines = cast(bytes, g.serialize(format='n3')).decode('utf8').splitlines()
303 lines = [line for line in lines if not line.startswith('@prefix')] 302 lines = [line.strip() for line in lines if not line.startswith('@prefix')]
304 return ' '.join(lines) 303 return ' '.join(lines)
305 304
306 305
307 def _organize(candidateTermMatches: Dict[BindableTerm, Set[Node]]) -> Tuple[List[BindableTerm], List[List[Node]]]: 306 def _organize(candidateTermMatches: Dict[BindableTerm, Set[Node]]) -> Tuple[List[BindableTerm], List[List[Node]]]:
308 items = list(candidateTermMatches.items()) 307 items = list(candidateTermMatches.items())