Mercurial > code > home > repos > homeauto
changeset 1622:38bd8ef9ef67
add CandidateTermMatches, unused so far
author | drewp@bigasterisk.com |
---|---|
date | Wed, 08 Sep 2021 18:53:26 -0700 |
parents | da235054caa0 |
children | cf901d219007 |
files | service/mqtt_to_rdf/inference.py |
diffstat | 1 files changed, 52 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/service/mqtt_to_rdf/inference.py Wed Sep 08 18:51:18 2021 -0700 +++ b/service/mqtt_to_rdf/inference.py Wed Sep 08 18:53:26 2021 -0700 @@ -7,7 +7,7 @@ import time from collections import defaultdict from dataclasses import dataclass, field -from typing import Dict, Iterator, List, Set, Tuple, Union, cast +from typing import Dict, Iterator, List, Optional, Set, Tuple, Union, cast from prometheus_client import Summary from rdflib import BNode, Graph, Namespace, URIRef @@ -167,6 +167,57 @@ @dataclass +class CandidateTermMatches: + """lazily find the possible matches for this term""" + term: BindableTerm + lhs: Lhs + workingSet: Graph + boundSoFar: CandidateBinding + + def __post_init__(self): + self.results: List[Node] = [] # we have to be able to repeat the results + + res: Set[Node] = set() + for trueStmt in self.workingSet: # all bound + lStmts = list(self.lhsStmtsContainingTerm()) + log.debug(f'{INDENT*4} {trueStmt=} {len(lStmts)}') + for pat in self.boundSoFar.apply(lStmts, returnBoundStatementsOnly=False): + log.debug(f'{INDENT*4} {pat=}') + implied = self._stmtImplies(pat, trueStmt) + if implied is not None: + res.add(implied) + self.results = list(res) + # self.results.sort() + + log.debug(f'{INDENT*3} CandTermMatches: {self.term} {graphDump(self.lhs.graph)} {self.boundSoFar=} ===> {self.results=}') + + def _stmtImplies(self, pat: Triple, trueStmt: Triple) -> Optional[Node]: + """what value, if any, do we learn for our term from this LHS pattern statement and this known-true stmt""" + r = None + for p, t in zip(pat, trueStmt): + if isinstance(p, (Variable, BNode)): + if p != self.term: + # stmt is unbound in more than just our term + continue # unsure what to do - err on the side of too many bindings, since they get rechecked later + if r is None: + r = t + log.debug(f'{INDENT*4} implied term value {p=} {t=}') + elif r != t: + # (?x c ?x) matched with (a b c) doesn't work + return None + return r + + def lhsStmtsContainingTerm(self): + # lhs could precompute this + for lhsStmt in self.lhs.graph: + if self.term in lhsStmt: + yield lhsStmt + + def __iter__(self): + return iter(self.results) + + +@dataclass class BoundLhs: lhs: Lhs binding: CandidateBinding