def merge_paths(self): def statement_by_x(index, X): for x in self.statements: if isinstance(x, query.triple): if tuple(x)[index] == X: yield x statement_by_subject = functools.partial(statement_by_x, 0) statement_by_object = functools.partial(statement_by_x, 2) merged = True while merged: merged = False for x in self.statements: if isinstance(x, query.triple): s, p, o = x if not isinstance(p, Path): if p.startswith(prefixes.EXPRESS) or p.startswith( prefixes.LIST): S = list(statement_by_object(s)) # assert len(S) == 1 to_append, to_remove = [], [] for s2p2o2 in S: s2, p2, o2 = s2p2o2 if isinstance(p2, SequencePath): # mutable p2.args.append(p) to_append.append( query.triple(self, (s2, p2, o))) else: to_append.append( query.triple( self, (s2, SequencePath(p2, p), o))) if list(statement_by_subject(o2)) == [x]: to_remove.append(s2p2o2) else: pass # print("Not removing", s2p2o2, "because of", list(statement_by_subject(o2))) to_remove.append(x) # print("old\n---") # print(self) self.statements.extend(to_append) for tr in to_remove: self.statements.remove(tr) # print("new\n---") # print(self) merged = True break
def translatePath(p): """ Translate PropertyPath expressions """ if isinstance(p, CompValue): if p.name == 'PathAlternative': if len(p.part) == 1: return p.part[0] else: return AlternativePath(*p.part) elif p.name == 'PathSequence': if len(p.part) == 1: return p.part[0] else: return SequencePath(*p.part) elif p.name == 'PathElt': if not p.mod: return p.part else: if isinstance(p.part, list): if len(p.part) != 1: raise Exception('Denkfehler!') return MulPath(p.part[0], p.mod) else: return MulPath(p.part, p.mod) elif p.name == 'PathEltOrInverse': if isinstance(p.part, list): if len(p.part) != 1: raise Exception('Denkfehler!') return InvPath(p.part[0]) else: return InvPath(p.part) elif p.name == 'PathNegatedPropertySet': if isinstance(p.part, list): return NegatedPath(AlternativePath(*p.part)) else: return NegatedPath(p.part)