Mercurial > code > home > repos > homeauto
comparison service/mqtt_to_rdf/inference.py @ 1596:4e795ed3a693
more cleanup, especially around Evaluation
author | drewp@bigasterisk.com |
---|---|
date | Sun, 05 Sep 2021 01:52:53 -0700 |
parents | e58bcfa66093 |
children | 387a9cb66517 |
comparison
equal
deleted
inserted
replaced
1595:413a280828bf | 1596:4e795ed3a693 |
---|---|
5 import itertools | 5 import itertools |
6 import logging | 6 import logging |
7 from collections import defaultdict | 7 from collections import defaultdict |
8 from dataclasses import dataclass, field | 8 from dataclasses import dataclass, field |
9 from decimal import Decimal | 9 from decimal import Decimal |
10 from typing import Dict, Iterator, List, Set, Tuple, Union, cast | 10 from typing import Dict, Iterable, Iterator, List, Set, Tuple, Union, cast |
11 | 11 |
12 from prometheus_client import Summary | 12 from prometheus_client import Summary |
13 from rdflib import RDF, BNode, Graph, Literal, Namespace, URIRef | 13 from rdflib import RDF, BNode, Graph, Literal, Namespace, URIRef |
14 from rdflib.graph import ConjunctiveGraph, ReadOnlyGraphAggregate | 14 from rdflib.graph import ConjunctiveGraph, ReadOnlyGraphAggregate |
15 from rdflib.term import Node, Variable | 15 from rdflib.term import Node, Variable |
239 | 239 |
240 @staticmethod | 240 @staticmethod |
241 def findEvals(lhs: Lhs) -> Iterator['Evaluation']: | 241 def findEvals(lhs: Lhs) -> Iterator['Evaluation']: |
242 for stmt in lhs.graph.triples((None, MATH['sum'], None)): | 242 for stmt in lhs.graph.triples((None, MATH['sum'], None)): |
243 operands, operandsStmts = parseList(lhs.graph, stmt[0]) | 243 operands, operandsStmts = parseList(lhs.graph, stmt[0]) |
244 g = Graph() | 244 yield Evaluation(operands, stmt, operandsStmts) |
245 g += operandsStmts | |
246 yield Evaluation(operands, g, stmt) | |
247 | 245 |
248 for stmt in lhs.graph.triples((None, MATH['greaterThan'], None)): | 246 for stmt in lhs.graph.triples((None, MATH['greaterThan'], None)): |
249 g = Graph() | 247 yield Evaluation([stmt[0], stmt[2]], stmt, []) |
250 g.add(stmt) | |
251 yield Evaluation([stmt[0], stmt[2]], g, stmt) | |
252 | 248 |
253 for stmt in lhs.graph.triples((None, ROOM['asFarenheit'], None)): | 249 for stmt in lhs.graph.triples((None, ROOM['asFarenheit'], None)): |
254 g = Graph() | 250 yield Evaluation([stmt[0]], stmt, []) |
255 g.add(stmt) | |
256 yield Evaluation([stmt[0]], g, stmt) | |
257 | 251 |
258 # internal, use findEvals | 252 # internal, use findEvals |
259 def __init__(self, operands: List[Node], operandsStmts: Graph, stmt: Triple) -> None: | 253 def __init__(self, operands: List[Node], mainStmt: Triple, otherStmts: Iterable[Triple]) -> None: |
260 self.operands = operands | 254 self.operands = operands |
261 self.operandsStmts = operandsStmts # may grow | 255 self.operandsStmts = Graph() |
262 self.stmt = stmt | 256 self.operandsStmts += otherStmts # may grow |
257 self.operandsStmts.add(mainStmt) | |
258 self.stmt = mainStmt | |
263 | 259 |
264 def resultBindings(self, inputBindings) -> Tuple[Dict[BindableTerm, Node], Graph]: | 260 def resultBindings(self, inputBindings) -> Tuple[Dict[BindableTerm, Node], Graph]: |
265 """under the bindings so far, what would this evaluation tell us, and which stmts would be consumed from doing so?""" | 261 """under the bindings so far, what would this evaluation tell us, and which stmts would be consumed from doing so?""" |
266 pred = self.stmt[1] | 262 pred = self.stmt[1] |
267 objVar: Node = self.stmt[2] | 263 objVar: Node = self.stmt[2] |
268 boundOperands = [] | 264 boundOperands = [] |
269 for o in self.operands: | 265 for op in self.operands: |
270 if isinstance(o, Variable): | 266 if isinstance(op, Variable): |
271 try: | 267 try: |
272 o = inputBindings[o] | 268 op = inputBindings[op] |
273 except KeyError: | 269 except KeyError: |
274 return {}, self.operandsStmts | 270 return {}, self.operandsStmts |
275 | 271 |
276 boundOperands.append(o) | 272 boundOperands.append(op) |
277 | 273 |
278 if pred == MATH['sum']: | 274 if pred == MATH['sum']: |
279 obj = Literal(sum(map(numericNode, boundOperands))) | 275 obj = Literal(sum(map(numericNode, boundOperands))) |
280 self.operandsStmts.add(self.stmt) | |
281 if not isinstance(objVar, Variable): | 276 if not isinstance(objVar, Variable): |
282 raise TypeError(f'expected Variable, got {objVar!r}') | 277 raise TypeError(f'expected Variable, got {objVar!r}') |
283 return {objVar: obj}, self.operandsStmts | 278 res: Dict[BindableTerm, Node] = {objVar: obj} |
284 elif pred == ROOM['asFarenheit']: | 279 elif pred == ROOM['asFarenheit']: |
285 if len(boundOperands) != 1: | 280 if len(boundOperands) != 1: |
286 raise ValueError(":asFarenheit takes 1 subject operand") | 281 raise ValueError(":asFarenheit takes 1 subject operand") |
287 f = Literal(Decimal(numericNode(boundOperands[0])) * 9 / 5 + 32) | 282 f = Literal(Decimal(numericNode(boundOperands[0])) * 9 / 5 + 32) |
288 if not isinstance(objVar, Variable): | 283 if not isinstance(objVar, Variable): |
289 raise TypeError(f'expected Variable, got {objVar!r}') | 284 raise TypeError(f'expected Variable, got {objVar!r}') |
290 return {objVar: f}, self.operandsStmts | 285 res: Dict[BindableTerm, Node] = {objVar: f} |
291 elif pred == MATH['greaterThan']: | 286 elif pred == MATH['greaterThan']: |
292 if not (numericNode(boundOperands[0]) > numericNode(boundOperands[1])): | 287 if not (numericNode(boundOperands[0]) > numericNode(boundOperands[1])): |
293 raise EvaluationFailed() | 288 raise EvaluationFailed() |
294 return {}, self.operandsStmts | 289 res: Dict[BindableTerm, Node] = {} |
295 else: | 290 else: |
296 raise NotImplementedError(repr(pred)) | 291 raise NotImplementedError(repr(pred)) |
292 | |
293 return res, self.operandsStmts | |
297 | 294 |
298 | 295 |
299 def numericNode(n: Node): | 296 def numericNode(n: Node): |
300 if not isinstance(n, Literal): | 297 if not isinstance(n, Literal): |
301 raise TypeError(f'expected Literal, got {n=}') | 298 raise TypeError(f'expected Literal, got {n=}') |
411 orderedValues: List[Node] = list(vals) | 408 orderedValues: List[Node] = list(vals) |
412 orderedValues.sort(key=str) | 409 orderedValues.sort(key=str) |
413 orderedValueSets.append(orderedValues) | 410 orderedValueSets.append(orderedValues) |
414 | 411 |
415 return orderedVars, orderedValueSets | 412 return orderedVars, orderedValueSets |
416 | |
417 | |
418 def isStatic(spo: Triple): | |
419 for t in spo: | |
420 if isinstance(t, (Variable, BNode)): | |
421 return False | |
422 return True |