Mercurial > code > home > repos > homeauto
comparison service/mqtt_to_rdf/inference.py @ 1614:97b2c3cfdb83
refactor: inline an odometer algorithm in place of itertools.product
author | drewp@bigasterisk.com |
---|---|
date | Mon, 06 Sep 2021 23:04:34 -0700 |
parents | 03ed8c9abd5b |
children | bcfa368e5498 |
comparison
equal
deleted
inserted
replaced
1613:03ed8c9abd5b | 1614:97b2c3cfdb83 |
---|---|
85 return True | 85 return True |
86 | 86 |
87 def _possibleBindings(self, workingSet, stats) -> Iterator['BoundLhs']: | 87 def _possibleBindings(self, workingSet, stats) -> Iterator['BoundLhs']: |
88 """this yields at least the working bindings, and possibly others""" | 88 """this yields at least the working bindings, and possibly others""" |
89 candidateTermMatches: Dict[BindableTerm, Set[Node]] = self._allCandidateTermMatches(workingSet) | 89 candidateTermMatches: Dict[BindableTerm, Set[Node]] = self._allCandidateTermMatches(workingSet) |
90 | 90 for bindRow in self._product(candidateTermMatches): |
91 try: | |
92 yield BoundLhs(self, bindRow) | |
93 except EvaluationFailed: | |
94 stats['permCountFailingEval'] += 1 | |
95 | |
96 def _product(self, candidateTermMatches: Dict[BindableTerm, Set[Node]]) -> Iterator[CandidateBinding]: | |
91 orderedVars, orderedValueSets = _organize(candidateTermMatches) | 97 orderedVars, orderedValueSets = _organize(candidateTermMatches) |
92 self._logCandidates(orderedVars, orderedValueSets) | 98 self._logCandidates(orderedVars, orderedValueSets) |
93 | |
94 log.debug(f'{INDENT*3} trying all permutations:') | 99 log.debug(f'{INDENT*3} trying all permutations:') |
95 for valueSet in itertools.product(*orderedValueSets): | 100 if not orderedValueSets: |
96 try: | 101 yield CandidateBinding({}) |
97 yield BoundLhs(self, CandidateBinding(dict(zip(orderedVars, valueSet)))) | 102 return |
98 except EvaluationFailed: | 103 if not orderedValueSets or not all(orderedValueSets): |
99 stats['permCountFailingEval'] += 1 | 104 # some var or bnode has no options at all |
105 return | |
106 rings: List[Iterator[Node]] = [itertools.cycle(valSet) for valSet in orderedValueSets] | |
107 currentSet: List[Node] = [next(ring) for ring in rings] | |
108 starts = [valSet[-1] for valSet in orderedValueSets] | |
109 while True: | |
110 for col, curr in enumerate(currentSet): | |
111 currentSet[col] = next(rings[col]) | |
112 log.debug(repr(currentSet)) | |
113 yield CandidateBinding(dict(zip(orderedVars, currentSet))) | |
114 if curr is not starts[col]: | |
115 break | |
116 if col == len(orderedValueSets) - 1: | |
117 return | |
100 | 118 |
101 def _allCandidateTermMatches(self, workingSet: ReadOnlyWorkingSet) -> Dict[BindableTerm, Set[Node]]: | 119 def _allCandidateTermMatches(self, workingSet: ReadOnlyWorkingSet) -> Dict[BindableTerm, Set[Node]]: |
102 """the total set of terms each variable could possibly match""" | 120 """the total set of terms each variable could possibly match""" |
103 | 121 |
104 candidateTermMatches: Dict[BindableTerm, Set[Node]] = defaultdict(set) | 122 candidateTermMatches: Dict[BindableTerm, Set[Node]] = defaultdict(set) |