Mercurial > code > home > repos > homeauto
comparison service/mqtt_to_rdf/inference.py @ 1600:89a50242cb5e
cleanup internal names, imports
author | drewp@bigasterisk.com |
---|---|
date | Sun, 05 Sep 2021 22:50:15 -0700 |
parents | abbf0eb0e640 |
children | 30463df12d89 |
comparison
equal
deleted
inserted
replaced
1599:abbf0eb0e640 | 1600:89a50242cb5e |
---|---|
97 def verify(self, lhs: 'Lhs', workingSet: ReadOnlyWorkingSet, usedByFuncs: Graph) -> bool: | 97 def verify(self, lhs: 'Lhs', workingSet: ReadOnlyWorkingSet, usedByFuncs: Graph) -> bool: |
98 """Can this lhs be true all at once in workingSet? Does it match with these bindings?""" | 98 """Can this lhs be true all at once in workingSet? Does it match with these bindings?""" |
99 boundLhs = list(self.apply(lhs.graph)) | 99 boundLhs = list(self.apply(lhs.graph)) |
100 boundUsedByFuncs = list(self.apply(usedByFuncs)) | 100 boundUsedByFuncs = list(self.apply(usedByFuncs)) |
101 | 101 |
102 self.logVerifyBanner(boundLhs, workingSet, boundUsedByFuncs) | 102 self._logVerifyBanner(boundLhs, workingSet, boundUsedByFuncs) |
103 | 103 |
104 for stmt in boundLhs: | 104 for stmt in boundLhs: |
105 log.debug(f'{INDENT*4} check for {stmt}') | 105 log.debug(f'{INDENT*4} check for {stmt}') |
106 | 106 |
107 if stmt in boundUsedByFuncs: | 107 if stmt in boundUsedByFuncs: |
111 else: | 111 else: |
112 log.debug(f'{INDENT*5} stmt not known to be true') | 112 log.debug(f'{INDENT*5} stmt not known to be true') |
113 return False | 113 return False |
114 return True | 114 return True |
115 | 115 |
116 def logVerifyBanner(self, boundLhs, workingSet: ReadOnlyWorkingSet, boundUsedByFuncs): | 116 def _logVerifyBanner(self, boundLhs, workingSet: ReadOnlyWorkingSet, boundUsedByFuncs): |
117 if not log.isEnabledFor(logging.DEBUG): | 117 if not log.isEnabledFor(logging.DEBUG): |
118 return | 118 return |
119 log.debug(f'{INDENT*4}/ verify all bindings against this boundLhs:') | 119 log.debug(f'{INDENT*4}/ verify all bindings against this boundLhs:') |
120 for stmt in sorted(boundLhs): | 120 for stmt in sorted(boundLhs): |
121 log.debug(f'{INDENT*4}|{INDENT} {stmt}') | 121 log.debug(f'{INDENT*4}|{INDENT} {stmt}') |
151 def findCandidateBindings(self, workingSet: ReadOnlyWorkingSet) -> Iterator[CandidateBinding]: | 151 def findCandidateBindings(self, workingSet: ReadOnlyWorkingSet) -> Iterator[CandidateBinding]: |
152 """bindings that fit the LHS of a rule, using statements from workingSet and functions | 152 """bindings that fit the LHS of a rule, using statements from workingSet and functions |
153 from LHS""" | 153 from LHS""" |
154 log.debug(f'{INDENT*3} nodesToBind: {self.lhsBindables}') | 154 log.debug(f'{INDENT*3} nodesToBind: {self.lhsBindables}') |
155 | 155 |
156 if not self.allStaticStatementsMatch(workingSet): | 156 if not self._allStaticStatementsMatch(workingSet): |
157 return | 157 return |
158 | 158 |
159 candidateTermMatches: Dict[BindableTerm, Set[Node]] = self.allCandidateTermMatches(workingSet) | 159 candidateTermMatches: Dict[BindableTerm, Set[Node]] = self._allCandidateTermMatches(workingSet) |
160 | 160 |
161 orderedVars, orderedValueSets = organize(candidateTermMatches) | 161 orderedVars, orderedValueSets = _organize(candidateTermMatches) |
162 | 162 |
163 self.logCandidates(orderedVars, orderedValueSets) | 163 self._logCandidates(orderedVars, orderedValueSets) |
164 | 164 |
165 log.debug(f'{INDENT*3} trying all permutations:') | 165 log.debug(f'{INDENT*3} trying all permutations:') |
166 | 166 |
167 for perm in itertools.product(*orderedValueSets): | 167 for perm in itertools.product(*orderedValueSets): |
168 binding = CandidateBinding(dict(zip(orderedVars, perm))) | 168 binding = CandidateBinding(dict(zip(orderedVars, perm))) |
177 if not binding.verify(self, workingSet, usedByFuncs): | 177 if not binding.verify(self, workingSet, usedByFuncs): |
178 log.debug(f'{INDENT*4} this binding did not verify') | 178 log.debug(f'{INDENT*4} this binding did not verify') |
179 continue | 179 continue |
180 yield binding | 180 yield binding |
181 | 181 |
182 def allStaticStatementsMatch(self, workingSet: ReadOnlyWorkingSet) -> bool: | 182 def _allStaticStatementsMatch(self, workingSet: ReadOnlyWorkingSet) -> bool: |
183 for ruleStmt in self.staticRuleStmts: | 183 for ruleStmt in self.staticRuleStmts: |
184 if ruleStmt not in workingSet: | 184 if ruleStmt not in workingSet: |
185 log.debug(f'{INDENT*3} {ruleStmt} not in working set- skip rule') | 185 log.debug(f'{INDENT*3} {ruleStmt} not in working set- skip rule') |
186 return False | 186 return False |
187 return True | 187 return True |
188 | 188 |
189 def allCandidateTermMatches(self, workingSet: ReadOnlyWorkingSet) -> Dict[BindableTerm, Set[Node]]: | 189 def _allCandidateTermMatches(self, workingSet: ReadOnlyWorkingSet) -> Dict[BindableTerm, Set[Node]]: |
190 """the total set of terms each variable could possibly match""" | 190 """the total set of terms each variable could possibly match""" |
191 | 191 |
192 candidateTermMatches: Dict[BindableTerm, Set[Node]] = defaultdict(set) | 192 candidateTermMatches: Dict[BindableTerm, Set[Node]] = defaultdict(set) |
193 for lhsStmt in self.graph: | 193 for lhsStmt in self.graph: |
194 log.debug(f'{INDENT*4} possibles for this lhs stmt: {lhsStmt}') | 194 log.debug(f'{INDENT*4} possibles for this lhs stmt: {lhsStmt}') |
230 for stmt in self.graph: | 230 for stmt in self.graph: |
231 if stmt not in usedByFuncs: | 231 if stmt not in usedByFuncs: |
232 g.add(stmt) | 232 g.add(stmt) |
233 return g | 233 return g |
234 | 234 |
235 def logCandidates(self, orderedVars, orderedValueSets): | 235 def _logCandidates(self, orderedVars, orderedValueSets): |
236 if not log.isEnabledFor(logging.DEBUG): | 236 if not log.isEnabledFor(logging.DEBUG): |
237 return | 237 return |
238 log.debug(f'{INDENT*3} resulting candidate terms:') | 238 log.debug(f'{INDENT*3} resulting candidate terms:') |
239 for v, vals in zip(orderedVars, orderedValueSets): | 239 for v, vals in zip(orderedVars, orderedValueSets): |
240 log.debug(f'{INDENT*4} {v!r} could be:') | 240 log.debug(f'{INDENT*4} {v!r} could be:') |
252 """ | 252 """ |
253 | 253 |
254 @staticmethod | 254 @staticmethod |
255 def findEvals(graph: Graph) -> Iterator['Evaluation']: | 255 def findEvals(graph: Graph) -> Iterator['Evaluation']: |
256 for stmt in graph.triples((None, MATH['sum'], None)): | 256 for stmt in graph.triples((None, MATH['sum'], None)): |
257 operands, operandsStmts = parseList(graph, stmt[0]) | 257 operands, operandsStmts = _parseList(graph, stmt[0]) |
258 yield Evaluation(operands, stmt, operandsStmts) | 258 yield Evaluation(operands, stmt, operandsStmts) |
259 | 259 |
260 for stmt in graph.triples((None, MATH['greaterThan'], None)): | 260 for stmt in graph.triples((None, MATH['greaterThan'], None)): |
261 yield Evaluation([stmt[0], stmt[2]], stmt, []) | 261 yield Evaluation([stmt[0], stmt[2]], stmt, []) |
262 | 262 |
355 log.info(f'{INDENT*1} {st}') | 355 log.info(f'{INDENT*1} {st}') |
356 return implied | 356 return implied |
357 | 357 |
358 def _iterateAllRules(self, workingSet: Graph, implied: Graph): | 358 def _iterateAllRules(self, workingSet: Graph, implied: Graph): |
359 for i, r in enumerate(self.rules): | 359 for i, r in enumerate(self.rules): |
360 self.logRuleApplicationHeader(workingSet, i, r) | 360 self._logRuleApplicationHeader(workingSet, i, r) |
361 applyRule(Lhs(r[0]), r[2], workingSet, implied) | 361 _applyRule(Lhs(r[0]), r[2], workingSet, implied) |
362 | 362 |
363 def logRuleApplicationHeader(self, workingSet, i, r): | 363 def _logRuleApplicationHeader(self, workingSet, i, r): |
364 if not log.isEnabledFor(logging.DEBUG): | 364 if not log.isEnabledFor(logging.DEBUG): |
365 return | 365 return |
366 | 366 |
367 log.debug('') | 367 log.debug('') |
368 log.debug(f'{INDENT*2} workingSet:') | 368 log.debug(f'{INDENT*2} workingSet:') |
373 log.debug(f'{INDENT*2}-applying rule {i}') | 373 log.debug(f'{INDENT*2}-applying rule {i}') |
374 log.debug(f'{INDENT*3} rule def lhs: {graphDump(r[0])}') | 374 log.debug(f'{INDENT*3} rule def lhs: {graphDump(r[0])}') |
375 log.debug(f'{INDENT*3} rule def rhs: {graphDump(r[2])}') | 375 log.debug(f'{INDENT*3} rule def rhs: {graphDump(r[2])}') |
376 | 376 |
377 | 377 |
378 def applyRule(lhs: Lhs, rhs: Graph, workingSet: Graph, implied: Graph): | 378 def _applyRule(lhs: Lhs, rhs: Graph, workingSet: Graph, implied: Graph): |
379 for binding in lhs.findCandidateBindings(ReadOnlyGraphAggregate([workingSet])): | 379 for binding in lhs.findCandidateBindings(ReadOnlyGraphAggregate([workingSet])): |
380 log.debug(f'{INDENT*3} rule has a working binding:') | 380 log.debug(f'{INDENT*3} rule has a working binding:') |
381 | 381 |
382 for lhsBoundStmt in binding.apply(lhs.graphWithoutEvals(binding)): | 382 for lhsBoundStmt in binding.apply(lhs.graphWithoutEvals(binding)): |
383 log.debug(f'{INDENT*5} adding {lhsBoundStmt=}') | 383 log.debug(f'{INDENT*5} adding {lhsBoundStmt=}') |
386 log.debug(f'{INDENT*5} adding {newStmt=}') | 386 log.debug(f'{INDENT*5} adding {newStmt=}') |
387 workingSet.add(newStmt) | 387 workingSet.add(newStmt) |
388 implied.add(newStmt) | 388 implied.add(newStmt) |
389 | 389 |
390 | 390 |
391 def parseList(graph, subj) -> Tuple[List[Node], Set[Triple]]: | 391 def _parseList(graph, subj) -> Tuple[List[Node], Set[Triple]]: |
392 """"Do like Collection(g, subj) but also return all the | 392 """"Do like Collection(g, subj) but also return all the |
393 triples that are involved in the list""" | 393 triples that are involved in the list""" |
394 out = [] | 394 out = [] |
395 used = set() | 395 used = set() |
396 cur = subj | 396 cur = subj |
415 lines = cast(bytes, g.serialize(format='n3')).decode('utf8').splitlines() | 415 lines = cast(bytes, g.serialize(format='n3')).decode('utf8').splitlines() |
416 lines = [line for line in lines if not line.startswith('@prefix')] | 416 lines = [line for line in lines if not line.startswith('@prefix')] |
417 return ' '.join(lines) | 417 return ' '.join(lines) |
418 | 418 |
419 | 419 |
420 def organize(candidateTermMatches: Dict[BindableTerm, Set[Node]]) -> Tuple[List[BindableTerm], List[List[Node]]]: | 420 def _organize(candidateTermMatches: Dict[BindableTerm, Set[Node]]) -> Tuple[List[BindableTerm], List[List[Node]]]: |
421 items = list(candidateTermMatches.items()) | 421 items = list(candidateTermMatches.items()) |
422 items.sort() | 422 items.sort() |
423 orderedVars: List[BindableTerm] = [] | 423 orderedVars: List[BindableTerm] = [] |
424 orderedValueSets: List[List[Node]] = [] | 424 orderedValueSets: List[List[Node]] = [] |
425 for v, vals in items: | 425 for v, vals in items: |