comparison service/mqtt_to_rdf/inference/candidate_binding.py @ 1727:23e6154e6c11

file moves
author drewp@bigasterisk.com
date Tue, 20 Jun 2023 23:26:24 -0700
parents service/mqtt_to_rdf/candidate_binding.py@3cf7f313b285
children
comparison
equal deleted inserted replaced
1726:7d3797ed6681 1727:23e6154e6c11
1 import logging
2 from dataclasses import dataclass
3 from typing import Dict, Iterable, Iterator, Union
4
5 from rdflib import Graph
6 from rdflib.term import Node, Variable
7
8 from inference.inference_types import (BindableTerm, BindingUnknown, RuleUnboundBnode, Triple)
9
10 log = logging.getLogger('cbind')
11 INDENT = ' '
12
13
14 class BindingConflict(ValueError): # might be the same as `Inconsistent`
15 pass
16
17
18 @dataclass
19 class CandidateBinding:
20 binding: Dict[BindableTerm, Node]
21
22 def __post_init__(self):
23 for n in self.binding.values():
24 if isinstance(n, RuleUnboundBnode):
25 raise TypeError(repr(self))
26
27 def __repr__(self):
28 b = " ".join("%r=%r" % (var, value) for var, value in sorted(self.binding.items()))
29 return f'CandidateBinding({b})'
30
31 def key(self):
32 """note this is only good for the current value, and self.binding is mutable"""
33 return tuple(sorted(self.binding.items()))
34
35 def apply(self, g: Union[Graph, Iterable[Triple]], returnBoundStatementsOnly=True) -> Iterator[Triple]:
36 for stmt in g:
37 try:
38 bound = (
39 self.applyTerm(stmt[0], returnBoundStatementsOnly), #
40 self.applyTerm(stmt[1], returnBoundStatementsOnly), #
41 self.applyTerm(stmt[2], returnBoundStatementsOnly))
42 except BindingUnknown:
43 if log.isEnabledFor(logging.DEBUG):
44 log.debug(f'{INDENT*7} CB.apply cant bind {stmt} using {self.binding}')
45
46 continue
47 if log.isEnabledFor(logging.DEBUG):
48 log.debug(f'{INDENT*7} CB.apply took {stmt} to {bound}')
49
50 yield bound
51
52 def applyTerm(self, term: Node, failUnbound=True):
53 if isinstance(term, (Variable, RuleUnboundBnode)):
54 if term in self.binding:
55 return self.binding[term]
56 else:
57 if failUnbound:
58 raise BindingUnknown()
59 return term
60
61 def addNewBindings(self, newBindings: 'CandidateBinding'):
62 for k, v in newBindings.binding.items():
63 if k in self.binding and self.binding[k] != v:
64 raise BindingConflict(f'thought {k} would be {self.binding[k]} but another Evaluation said it should be {v}')
65 self.binding[k] = v
66
67 def copy(self):
68 return CandidateBinding(self.binding.copy())
69
70 def contains(self, term: BindableTerm):
71 return term in self.binding