Mercurial > repos > shellac > guppy_basecaller
diff env/lib/python3.7/site-packages/rdflib/paths.py @ 5:9b1c78e6ba9c draft default tip
"planemo upload commit 6c0a8142489327ece472c84e558c47da711a9142"
| author | shellac |
|---|---|
| date | Mon, 01 Jun 2020 08:59:25 -0400 |
| parents | 79f47841a781 |
| children |
line wrap: on
line diff
--- a/env/lib/python3.7/site-packages/rdflib/paths.py Thu May 14 16:47:39 2020 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,516 +0,0 @@ -from rdflib.py3compat import PY3, format_doctest_out - -__doc__ = format_doctest_out(""" - -This module implements the SPARQL 1.1 Property path operators, as -defined in: - -http://www.w3.org/TR/sparql11-query/#propertypaths - -In SPARQL the syntax is as follows: - -+--------------------+-------------------------------------------------+ -|Syntax | Matches | -+====================+=================================================+ -|iri | An IRI. A path of length one. | -+--------------------+-------------------------------------------------+ -|^elt | Inverse path (object to subject). | -+--------------------+-------------------------------------------------+ -|elt1 / elt2 | A sequence path of elt1 followed by elt2. | -+--------------------+-------------------------------------------------+ -|elt1 | elt2 | A alternative path of elt1 or elt2 | -| | (all possibilities are tried). | -+--------------------+-------------------------------------------------+ -|elt* | A path that connects the subject and object | -| | of the path by zero or more matches of elt. | -+--------------------+-------------------------------------------------+ -|elt+ | A path that connects the subject and object | -| | of the path by one or more matches of elt. | -+--------------------+-------------------------------------------------+ -|elt? | A path that connects the subject and object | -| | of the path by zero or one matches of elt. | -+--------------------+-------------------------------------------------+ -|!iri or | Negated property set. An IRI which is not one of| -|!(iri\ :sub:`1`\ | | iri\ :sub:`1`...iri\ :sub:`n`. | -|... |iri\ :sub:`n`) | !iri is short for !(iri). | -+--------------------+-------------------------------------------------+ -|!^iri or | Negated property set where the excluded matches | -|!(^iri\ :sub:`1`\ | | are based on reversed path. That is, not one of | -|... |^iri\ :sub:`n`)| iri\ :sub:`1`...iri\ :sub:`n` as reverse paths. | -| | !^iri is short for !(^iri). | -+--------------------+-------------------------------------------------+ -|!(iri\ :sub:`1`\ | | A combination of forward and reverse | -|...|iri\ :sub:`j`\ || properties in a negated property set. | -|^iri\ :sub:`j+1`\ | | | -|... |^iri\ :sub:`n`)| | -+--------------------+-------------------------------------------------+ -|(elt) | A group path elt, brackets control precedence. | -+--------------------+-------------------------------------------------+ - -This module is used internally be the SPARQL engine, but they property paths -can also be used to query RDFLib Graphs directly. - -Where possible the SPARQL syntax is mapped to python operators, and property -path objects can be constructed from existing URIRefs. - ->>> from rdflib import Graph, Namespace - ->>> foaf=Namespace('http://xmlns.com/foaf/0.1/') - ->>> ~foaf.knows -Path(~http://xmlns.com/foaf/0.1/knows) - ->>> foaf.knows/foaf.name -Path(http://xmlns.com/foaf/0.1/knows / http://xmlns.com/foaf/0.1/name) - ->>> foaf.name|foaf.firstName -Path(http://xmlns.com/foaf/0.1/name | http://xmlns.com/foaf/0.1/firstName) - -Modifiers (?, *, +) are done using * (the multiplication operator) and -the strings '*', '?', '+', also defined as constants in this file. - ->>> foaf.knows*OneOrMore -Path(http://xmlns.com/foaf/0.1/knows+) - -The path objects can also be used with the normal graph methods. - -First some example data: - ->>> g=Graph() - ->>> g=g.parse(data=''' -... @prefix : <ex:> . -... -... :a :p1 :c ; :p2 :f . -... :c :p2 :e ; :p3 :g . -... :g :p3 :h ; :p2 :j . -... :h :p3 :a ; :p2 :g . -... -... :q :px :q . -... -... ''', format='n3') # doctest: +ELLIPSIS - ->>> e=Namespace('ex:') - -Graph contains: ->>> (e.a, e.p1/e.p2, e.e) in g -True - -Graph generator functions, triples, subjects, objects, etc. : - ->>> list(g.objects(e.c, (e.p3*OneOrMore)/e.p2)) # doctest: +NORMALIZE_WHITESPACE -[rdflib.term.URIRef(%(u)s'ex:j'), rdflib.term.URIRef(%(u)s'ex:g'), - rdflib.term.URIRef(%(u)s'ex:f')] - -A more complete set of tests: - ->>> list(evalPath(g, (None, e.p1/e.p2, None)))==[(e.a, e.e)] -True ->>> list(evalPath(g, (e.a, e.p1|e.p2, None)))==[(e.a,e.c), (e.a,e.f)] -True ->>> list(evalPath(g, (e.c, ~e.p1, None))) == [ (e.c, e.a) ] -True ->>> list(evalPath(g, (e.a, e.p1*ZeroOrOne, None))) == [(e.a, e.a), (e.a, e.c)] -True ->>> list(evalPath(g, (e.c, e.p3*OneOrMore, None))) == [ -... (e.c, e.g), (e.c, e.h), (e.c, e.a)] -True ->>> list(evalPath(g, (e.c, e.p3*ZeroOrMore, None))) == [(e.c, e.c), -... (e.c, e.g), (e.c, e.h), (e.c, e.a)] -True ->>> list(evalPath(g, (e.a, -e.p1, None))) == [(e.a, e.f)] -True ->>> list(evalPath(g, (e.a, -(e.p1|e.p2), None))) == [] -True ->>> list(evalPath(g, (e.g, -~e.p2, None))) == [(e.g, e.j)] -True ->>> list(evalPath(g, (e.e, ~(e.p1/e.p2), None))) == [(e.e, e.a)] -True ->>> list(evalPath(g, (e.a, e.p1/e.p3/e.p3, None))) == [(e.a, e.h)] -True - ->>> list(evalPath(g, (e.q, e.px*OneOrMore, None))) -[(rdflib.term.URIRef(%(u)s'ex:q'), rdflib.term.URIRef(%(u)s'ex:q'))] - ->>> list(evalPath(g, (None, e.p1|e.p2, e.c))) -[(rdflib.term.URIRef(%(u)s'ex:a'), rdflib.term.URIRef(%(u)s'ex:c'))] - ->>> list(evalPath(g, (None, ~e.p1, e.a))) == [ (e.c, e.a) ] -True ->>> list(evalPath(g, (None, e.p1*ZeroOrOne, e.c))) # doctest: +NORMALIZE_WHITESPACE -[(rdflib.term.URIRef(%(u)s'ex:c'), rdflib.term.URIRef(%(u)s'ex:c')), - (rdflib.term.URIRef(%(u)s'ex:a'), rdflib.term.URIRef(%(u)s'ex:c'))] - ->>> list(evalPath(g, (None, e.p3*OneOrMore, e.a))) # doctest: +NORMALIZE_WHITESPACE -[(rdflib.term.URIRef(%(u)s'ex:h'), rdflib.term.URIRef(%(u)s'ex:a')), - (rdflib.term.URIRef(%(u)s'ex:g'), rdflib.term.URIRef(%(u)s'ex:a')), - (rdflib.term.URIRef(%(u)s'ex:c'), rdflib.term.URIRef(%(u)s'ex:a'))] - ->>> list(evalPath(g, (None, e.p3*ZeroOrMore, e.a))) # doctest: +NORMALIZE_WHITESPACE -[(rdflib.term.URIRef(%(u)s'ex:a'), rdflib.term.URIRef(%(u)s'ex:a')), - (rdflib.term.URIRef(%(u)s'ex:h'), rdflib.term.URIRef(%(u)s'ex:a')), - (rdflib.term.URIRef(%(u)s'ex:g'), rdflib.term.URIRef(%(u)s'ex:a')), - (rdflib.term.URIRef(%(u)s'ex:c'), rdflib.term.URIRef(%(u)s'ex:a'))] - ->>> list(evalPath(g, (None, -e.p1, e.f))) == [(e.a, e.f)] -True ->>> list(evalPath(g, (None, -(e.p1|e.p2), e.c))) == [] -True ->>> list(evalPath(g, (None, -~e.p2, e.j))) == [(e.g, e.j)] -True ->>> list(evalPath(g, (None, ~(e.p1/e.p2), e.a))) == [(e.e, e.a)] -True ->>> list(evalPath(g, (None, e.p1/e.p3/e.p3, e.h))) == [(e.a, e.h)] -True - ->>> list(evalPath(g, (e.q, e.px*OneOrMore, None))) -[(rdflib.term.URIRef(%(u)s'ex:q'), rdflib.term.URIRef(%(u)s'ex:q'))] - ->>> list(evalPath(g, (e.c, (e.p2|e.p3)*ZeroOrMore, e.j))) -[(rdflib.term.URIRef(%(u)s'ex:c'), rdflib.term.URIRef(%(u)s'ex:j'))] - -No vars specified: - ->>> sorted(list(evalPath(g, (None, e.p3*OneOrMore, None)))) #doctest: +NORMALIZE_WHITESPACE -[(rdflib.term.URIRef(%(u)s'ex:c'), rdflib.term.URIRef(%(u)s'ex:a')), - (rdflib.term.URIRef(%(u)s'ex:c'), rdflib.term.URIRef(%(u)s'ex:g')), - (rdflib.term.URIRef(%(u)s'ex:c'), rdflib.term.URIRef(%(u)s'ex:h')), - (rdflib.term.URIRef(%(u)s'ex:g'), rdflib.term.URIRef(%(u)s'ex:a')), - (rdflib.term.URIRef(%(u)s'ex:g'), rdflib.term.URIRef(%(u)s'ex:h')), - (rdflib.term.URIRef(%(u)s'ex:h'), rdflib.term.URIRef(%(u)s'ex:a'))] - -.. versionadded:: 4.0 - -""") - - -from rdflib.term import URIRef, Node - - -# property paths - -ZeroOrMore = '*' -OneOrMore = '+' -ZeroOrOne = '?' - - -class Path(object): - def eval(self, graph, subj=None, obj=None): - raise NotImplementedError() - - def __hash__(self): - return hash(repr(self)) - - def __eq__(self, other): - return repr(self) == repr(other) - - def __lt__(self, other): - if not isinstance(other, (Path, Node)): - raise TypeError('unorderable types: %s() < %s()' % ( - repr(self), repr(other))) - return repr(self) < repr(other) - - def __le__(self, other): - if not isinstance(other, (Path, Node)): - raise TypeError('unorderable types: %s() < %s()' % ( - repr(self), repr(other))) - return repr(self) <= repr(other) - - def __ne__(self, other): - return not self == other - - def __gt__(self, other): - return not self <= other - - def __ge__(self, other): - return not self < other - - -class InvPath(Path): - - def __init__(self, arg): - self.arg = arg - - def eval(self, graph, subj=None, obj=None): - for s, o in evalPath(graph, (obj, self.arg, subj)): - yield o, s - - def __repr__(self): - return "Path(~%s)" % (self.arg,) - - def n3(self): - return '^%s' % self.arg.n3() - - -class SequencePath(Path): - def __init__(self, *args): - self.args = [] - for a in args: - if isinstance(a, SequencePath): - self.args += a.args - else: - self.args.append(a) - - def eval(self, graph, subj=None, obj=None): - def _eval_seq(paths, subj, obj): - if paths[1:]: - for s, o in evalPath(graph, (subj, paths[0], None)): - for r in _eval_seq(paths[1:], o, obj): - yield s, r[1] - - else: - for s, o in evalPath(graph, (subj, paths[0], obj)): - yield s, o - - def _eval_seq_bw(paths, subj, obj): - if paths[:-1]: - for s, o in evalPath(graph, (None, paths[-1], obj)): - for r in _eval_seq(paths[:-1], subj, s): - yield r[0], o - - else: - for s, o in evalPath(graph, (subj, paths[0], obj)): - yield s, o - - if subj: - return _eval_seq(self.args, subj, obj) - elif obj: - return _eval_seq_bw(self.args, subj, obj) - else: # no vars bound, we can start anywhere - return _eval_seq(self.args, subj, obj) - - def __repr__(self): - return "Path(%s)" % " / ".join(str(x) for x in self.args) - - def n3(self): - return '/'.join(a.n3() for a in self.args) - - -class AlternativePath(Path): - def __init__(self, *args): - self.args = [] - for a in args: - if isinstance(a, AlternativePath): - self.args += a.args - else: - self.args.append(a) - - def eval(self, graph, subj=None, obj=None): - for x in self.args: - for y in evalPath(graph, (subj, x, obj)): - yield y - - def __repr__(self): - return "Path(%s)" % " | ".join(str(x) for x in self.args) - - def n3(self): - return '|'.join(a.n3() for a in self.args) - - - -class MulPath(Path): - def __init__(self, path, mod): - self.path = path - self.mod = mod - - if mod == ZeroOrOne: - self.zero = True - self.more = False - elif mod == ZeroOrMore: - self.zero = True - self.more = True - elif mod == OneOrMore: - self.zero = False - self.more = True - else: - raise Exception('Unknown modifier %s' % mod) - - def eval(self, graph, subj=None, obj=None, first=True): - if self.zero and first: - if subj and obj: - if subj == obj: - yield (subj, obj) - elif subj: - yield (subj, subj) - elif obj: - yield (obj, obj) - - def _fwd(subj=None, obj=None, seen=None): - seen.add(subj) - - for s, o in evalPath(graph, (subj, self.path, None)): - if not obj or o == obj: - yield s, o - if self.more: - if o in seen: - continue - for s2, o2 in _fwd(o, obj, seen): - yield s, o2 - - def _bwd(subj=None, obj=None, seen=None): - seen.add(obj) - - for s, o in evalPath(graph, (None, self.path, obj)): - if not subj or subj == s: - yield s, o - if self.more: - if s in seen: - continue - - for s2, o2 in _bwd(None, s, seen): - yield s2, o - - def _fwdbwd(): - if self.zero: - seen1 = set() - # According to the spec, ALL nodes are possible solutions - # (even literals) - # we cannot do this without going through ALL triples - # unless we keep an index of all terms somehow - # but lets just hope this query doesnt happen very often... - for s, o in graph.subject_objects(None): - if s not in seen1: - seen1.add(s) - yield s, s - if o not in seen1: - seen1.add(o) - yield o, o - - for s, o in evalPath(graph, (None, self.path, None)): - if not self.more: - yield s, o - else: - seen = set() - f = list(_fwd(s, None, seen)) # cache or recompute? - for s3, o3 in _bwd(None, o, seen): - for s2, o2 in f: - yield s3, o2 # ? - - done = set() # the spec does by defn. not allow duplicates - if subj: - for x in _fwd(subj, obj, set()): - if x not in done: - done.add(x) - yield x - elif obj: - for x in _bwd(subj, obj, set()): - if x not in done: - done.add(x) - yield x - else: - for x in _fwdbwd(): - if x not in done: - done.add(x) - yield x - - def __repr__(self): - return "Path(%s%s)" % (self.path, self.mod) - - def n3(self): - return '%s%s' % (self.path, self.mod) - - - -class NegatedPath(Path): - def __init__(self, arg): - if isinstance(arg, (URIRef, InvPath)): - self.args = [arg] - elif isinstance(arg, AlternativePath): - self.args = arg.args - else: - raise Exception( - 'Can only negate URIRefs, InvPaths or ' + - 'AlternativePaths, not: %s' % (arg,)) - - def eval(self, graph, subj=None, obj=None): - for s, p, o in graph.triples((subj, None, obj)): - for a in self.args: - if isinstance(a, URIRef): - if p == a: - break - elif isinstance(a, InvPath): - if (o, a.arg, s) in graph: - break - else: - raise Exception('Invalid path in NegatedPath: %s' % a) - else: - yield s, o - - def __repr__(self): - return "Path(! %s)" % ",".join(str(x) for x in self.args) - - def n3(self): - return '!(%s)' % ('|'.join(self.args)) - - -class PathList(list): - pass - - -def path_alternative(self, other): - """ - alternative path - """ - if not isinstance(other, (URIRef, Path)): - raise Exception('Only URIRefs or Paths can be in paths!') - return AlternativePath(self, other) - - -def path_sequence(self, other): - """ - sequence path - """ - if not isinstance(other, (URIRef, Path)): - raise Exception('Only URIRefs or Paths can be in paths!') - return SequencePath(self, other) - - -def evalPath(graph, t): - return ((s, o) for s, p, o in graph.triples(t)) - -def mul_path(p, mul): - """ - cardinality path - """ - return MulPath(p, mul) - - -def inv_path(p): - """ - inverse path - """ - return InvPath(p) - - -def neg_path(p): - """ - negated path - """ - return NegatedPath(p) - - - -if __name__ == '__main__': - - import doctest - doctest.testmod() -else: - # monkey patch - # (these cannot be directly in terms.py - # as it would introduce circular imports) - - URIRef.__or__ = path_alternative - URIRef.__mul__ = mul_path - URIRef.__invert__ = inv_path - URIRef.__neg__ = neg_path - URIRef.__truediv__ = path_sequence - if not PY3: - URIRef.__div__ = path_sequence - - Path.__invert__ = inv_path - Path.__neg__ = neg_path - Path.__mul__ = mul_path - Path.__or__ = path_alternative - Path.__truediv__ = path_sequence - if not PY3: - Path.__div__ = path_sequence
