Mercurial > code > home > repos > homeauto
comparison service/mqtt_to_rdf/lhs_evaluation.py @ 1636:3252bdc284bc
rm dead code from previous tries
author | drewp@bigasterisk.com |
---|---|
date | Mon, 13 Sep 2021 00:18:47 -0700 |
parents | ba59cfc3c747 |
children | ec3f98d0c1d8 |
comparison
equal
deleted
inserted
replaced
1635:22d481f0a924 | 1636:3252bdc284bc |
---|---|
1 import logging | 1 import logging |
2 from decimal import Decimal | 2 from decimal import Decimal |
3 from typing import Dict, Iterable, Iterator, List, Set, Tuple | 3 from typing import List, Set, Tuple |
4 | 4 |
5 from prometheus_client import Summary | 5 from prometheus_client import Summary |
6 from rdflib import RDF, Graph, Literal, Namespace, URIRef | 6 from rdflib import RDF, Literal, Namespace, URIRef |
7 from rdflib.term import Node, Variable | 7 from rdflib.term import Node |
8 | 8 |
9 from candidate_binding import CandidateBinding | 9 from inference_types import Triple |
10 from inference import CandidateBinding | |
11 from inference_types import BindableTerm, EvaluationFailed, Triple | |
12 | 10 |
13 log = logging.getLogger('infer') | 11 log = logging.getLogger('infer') |
14 | 12 |
15 INDENT = ' ' | 13 INDENT = ' ' |
16 | 14 |
17 ROOM = Namespace("http://projects.bigasterisk.com/room/") | 15 ROOM = Namespace("http://projects.bigasterisk.com/room/") |
18 LOG = Namespace('http://www.w3.org/2000/10/swap/log#') | 16 LOG = Namespace('http://www.w3.org/2000/10/swap/log#') |
19 MATH = Namespace('http://www.w3.org/2000/10/swap/math#') | 17 MATH = Namespace('http://www.w3.org/2000/10/swap/math#') |
20 | |
21 # Graph() makes a BNode if you don't pass | |
22 # identifier, which can be a bottleneck. | |
23 GRAPH_ID = URIRef('dont/care') | |
24 | |
25 | |
26 # alternate name LhsComponent | |
27 class Evaluation: | |
28 """some lhs statements need to be evaluated with a special function | |
29 (e.g. math) and then not considered for the rest of the rule-firing | |
30 process. It's like they already 'matched' something, so they don't need | |
31 to match a statement from the known-true working set. | |
32 | |
33 One Evaluation instance is for one function call. | |
34 """ | |
35 | |
36 @staticmethod | |
37 def findEvals(graph: Graph) -> Iterator['Evaluation']: | |
38 for stmt in graph.triples((None, MATH['sum'], None)): | |
39 operands, operandsStmts = parseList(graph, stmt[0]) | |
40 yield Evaluation(operands, stmt, operandsStmts) | |
41 | |
42 for stmt in graph.triples((None, MATH['greaterThan'], None)): | |
43 yield Evaluation([stmt[0], stmt[2]], stmt, []) | |
44 | |
45 for stmt in graph.triples((None, ROOM['asFarenheit'], None)): | |
46 yield Evaluation([stmt[0]], stmt, []) | |
47 | |
48 # internal, use findEvals | |
49 def __init__(self, operands: List[Node], mainStmt: Triple, otherStmts: Iterable[Triple]) -> None: | |
50 self.operands = operands | |
51 self.operandsStmts = Graph(identifier=GRAPH_ID) | |
52 self.operandsStmts += otherStmts # may grow | |
53 self.operandsStmts.add(mainStmt) | |
54 self.stmt = mainStmt | |
55 | |
56 def resultBindings(self, inputBindings: CandidateBinding) -> Tuple[CandidateBinding, Graph]: | |
57 """under the bindings so far, what would this evaluation tell us, and which stmts would be consumed from doing so?""" | |
58 pred = self.stmt[1] | |
59 objVar: Node = self.stmt[2] | |
60 boundOperands = [] | |
61 for op in self.operands: | |
62 if isinstance(op, Variable): | |
63 try: | |
64 op = inputBindings.binding[op] | |
65 except KeyError: | |
66 return CandidateBinding(binding={}), self.operandsStmts | |
67 | |
68 boundOperands.append(op) | |
69 | |
70 if pred == MATH['sum']: | |
71 obj = Literal(sum(map(numericNode, boundOperands))) | |
72 if not isinstance(objVar, Variable): | |
73 raise TypeError(f'expected Variable, got {objVar!r}') | |
74 res = CandidateBinding({objVar: obj}) | |
75 elif pred == ROOM['asFarenheit']: | |
76 if len(boundOperands) != 1: | |
77 raise ValueError(":asFarenheit takes 1 subject operand") | |
78 f = Literal(Decimal(numericNode(boundOperands[0])) * 9 / 5 + 32) | |
79 if not isinstance(objVar, Variable): | |
80 raise TypeError(f'expected Variable, got {objVar!r}') | |
81 res = CandidateBinding({objVar: f}) | |
82 elif pred == MATH['greaterThan']: | |
83 if not (numericNode(boundOperands[0]) > numericNode(boundOperands[1])): | |
84 raise EvaluationFailed() | |
85 res= CandidateBinding({}) | |
86 else: | |
87 raise NotImplementedError(repr(pred)) | |
88 | |
89 return res, self.operandsStmts | |
90 | 18 |
91 | 19 |
92 def numericNode(n: Node): | 20 def numericNode(n: Node): |
93 if not isinstance(n, Literal): | 21 if not isinstance(n, Literal): |
94 raise TypeError(f'expected Literal, got {n=}') | 22 raise TypeError(f'expected Literal, got {n=}') |