Mercurial > code > home > repos > homeauto
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()) |