comparison service/mqtt_to_rdf/inference.py @ 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
comparison
equal deleted inserted replaced
1598:9e6a593180b6 1599:abbf0eb0e640
31 31
32 class EvaluationFailed(ValueError): 32 class EvaluationFailed(ValueError):
33 """e.g. we were given (5 math:greaterThan 6)""" 33 """e.g. we were given (5 math:greaterThan 6)"""
34 34
35 35
36 class BindingUnknown(ValueError):
37 """e.g. we were asked to make the bound version
38 of (A B ?c) and we don't have a binding for ?c
39 """
40
41
36 @dataclass 42 @dataclass
37 class CandidateBinding: 43 class CandidateBinding:
38 binding: Dict[BindableTerm, Node] 44 binding: Dict[BindableTerm, Node]
39 45
40 def __repr__(self): 46 def __repr__(self):
41 b = " ".join("%s=%s" % (k, v) for k, v in sorted(self.binding.items())) 47 b = " ".join("%s=%s" % (k, v) for k, v in sorted(self.binding.items()))
42 return f'CandidateBinding({b})' 48 return f'CandidateBinding({b})'
43 49
44 def apply(self, g: Graph) -> Iterator[Triple]: 50 def apply(self, g: Graph) -> Iterator[Triple]:
45 for stmt in g: 51 for stmt in g:
46 yield (self._applyTerm(stmt[0]), self._applyTerm(stmt[1]), self._applyTerm(stmt[2])) 52 try:
53 bound = (self._applyTerm(stmt[0]), self._applyTerm(stmt[1]), self._applyTerm(stmt[2]))
54 except BindingUnknown:
55 continue
56 yield bound
47 57
48 def _applyTerm(self, term: Node): 58 def _applyTerm(self, term: Node):
49 if isinstance(term, (Variable, BNode)): 59 if isinstance(term, (Variable, BNode)):
50 if term in self.binding: 60 if term in self.binding:
51 return self.binding[term] 61 return self.binding[term]
62 else:
63 raise BindingUnknown()
52 return term 64 return term
53 65
54 def applyFunctions(self, lhs) -> Graph: 66 def applyFunctions(self, lhs) -> Graph:
55 """may grow the binding with some results""" 67 """may grow the binding with some results"""
56 usedByFuncs = Graph() 68 usedByFuncs = Graph()
308 320
309 def __init__(self) -> None: 321 def __init__(self) -> None:
310 self.rules = ConjunctiveGraph() 322 self.rules = ConjunctiveGraph()
311 323
312 def setRules(self, g: ConjunctiveGraph): 324 def setRules(self, g: ConjunctiveGraph):
313 self.rules = g 325 self.rules = ConjunctiveGraph()
326 for stmt in g:
327 if stmt[1] == LOG['implies']:
328 self.rules.add(stmt)
329 # others should go to a default working set?
314 330
315 def infer(self, graph: Graph): 331 def infer(self, graph: Graph):
316 """ 332 """
317 returns new graph of inferred statements. 333 returns new graph of inferred statements.
318 """ 334 """
340 return implied 356 return implied
341 357
342 def _iterateAllRules(self, workingSet: Graph, implied: Graph): 358 def _iterateAllRules(self, workingSet: Graph, implied: Graph):
343 for i, r in enumerate(self.rules): 359 for i, r in enumerate(self.rules):
344 self.logRuleApplicationHeader(workingSet, i, r) 360 self.logRuleApplicationHeader(workingSet, i, r)
345 if r[1] == LOG['implies']: 361 applyRule(Lhs(r[0]), r[2], workingSet, implied)
346 applyRule(Lhs(r[0]), r[2], workingSet, implied)
347 else:
348 log.info(f'{INDENT*2} {r} not a rule?')
349 362
350 def logRuleApplicationHeader(self, workingSet, i, r): 363 def logRuleApplicationHeader(self, workingSet, i, r):
351 if not log.isEnabledFor(logging.DEBUG): 364 if not log.isEnabledFor(logging.DEBUG):
352 return 365 return
353 366