def infer(graph: ConjunctiveGraph, rules: ConjunctiveGraph): """ returns new graph of inferred statements. """ log.info( f'Begin inference of graph len={len(graph)} with rules len={len(rules)}:' ) workingSet = ConjunctiveGraph() workingSet.addN(graph.quads()) implied = ConjunctiveGraph() delta = 1 while delta > 0: delta = -len(implied) for r in rules: if r[1] == LOG['implies']: containsSetup = all(st in workingSet for st in r[0]) if containsSetup: log.info(f' Rule {r[0]} -> present={containsSetup}') for st in r[0]: log.info( f' {st[0].n3()} {st[1].n3()} {st[2].n3()}') log.info(f' ...implies {len(r[2])} statements') if containsSetup: for st in r[2]: workingSet.add(st) implied.add(st) else: log.info(f' {r}') delta += len(implied) log.info(f' this inference round added {delta} more implied stmts') log.info(f'{len(implied)} stmts implied:') for st in implied: log.info(f' {st}') return implied # based on fuxi/tools/rdfpipe.py target = Graph() tokenSet = generateTokenSet(graph) with _dontChangeRulesStore(rules): network = ReteNetwork(rules, inferredTarget=target) network.feedFactsToAdd(tokenSet) return target
def testSerialize(self): s1 = URIRef('store:1') r1 = URIRef('resource:1') r2 = URIRef('resource:2') label = URIRef('predicate:label') g1 = Graph(identifier = s1) g1.add((r1, label, Literal("label 1", lang="en"))) g1.add((r1, label, Literal("label 2"))) s2 = URIRef('store:2') g2 = Graph(identifier = s2) g2.add((r2, label, Literal("label 3"))) g = ConjunctiveGraph() for s,p,o in g1.triples((None, None, None)): g.addN([(s,p,o,g1)]) for s,p,o in g2.triples((None, None, None)): g.addN([(s,p,o,g2)]) r3 = URIRef('resource:3') g.add((r3, label, Literal(4))) r = g.serialize(format='trix') g3 = ConjunctiveGraph() from StringIO import StringIO g3.parse(StringIO(r), format='trix') for q in g3.quads((None,None,None)): # TODO: Fix once getGraph/getContext is in conjunctive graph if isinstance(q[3].identifier, URIRef): tg=Graph(store=g.store, identifier=q[3].identifier) else: # BNode, this is a bit ugly # we cannot match the bnode to the right graph automagically # here I know there is only one anonymous graph, # and that is the default one, but this is not always the case tg=g.default_context self.assertTrue(q[0:3] in tg)
def testSerialize(self): s1 = URIRef('store:1') r1 = URIRef('resource:1') r2 = URIRef('resource:2') label = URIRef('predicate:label') g1 = Graph(identifier=s1) g1.add((r1, label, Literal("label 1", lang="en"))) g1.add((r1, label, Literal("label 2"))) s2 = URIRef('store:2') g2 = Graph(identifier=s2) g2.add((r2, label, Literal("label 3"))) g = ConjunctiveGraph() for s, p, o in g1.triples((None, None, None)): g.addN([(s, p, o, g1)]) for s, p, o in g2.triples((None, None, None)): g.addN([(s, p, o, g2)]) r3 = URIRef('resource:3') g.add((r3, label, Literal(4))) r = g.serialize(format='trix') g3 = ConjunctiveGraph() from StringIO import StringIO g3.parse(StringIO(r), format='trix') for q in g3.quads((None, None, None)): # TODO: Fix once getGraph/getContext is in conjunctive graph if isinstance(q[3].identifier, URIRef): tg = Graph(store=g.store, identifier=q[3].identifier) else: # BNode, this is a bit ugly # we cannot match the bnode to the right graph automagically # here I know there is only one anonymous graph, # and that is the default one, but this is not always the case tg = g.default_context self.assertTrue(q[0:3] in tg)
def DoTheTestMemory(): ns = Namespace("http://love.com#") # AssertionError: ConjunctiveGraph must be backed by a context aware store. mary = URIRef("http://love.com/lovers/mary") john = URIRef("http://love.com/lovers/john") cmary = URIRef("http://love.com/lovers/context_mary") cjohn = URIRef("http://love.com/lovers/context_john") # my_store = Memory() store_input = IOMemory() gconjunctive = ConjunctiveGraph(store=store_input) gconjunctive.bind("love", ns) # add a graph for Mary's facts to the Conjunctive Graph gmary = Graph(store=store_input, identifier=cmary) # Mary's graph only contains the URI of the person she love, not his cute name gmary.add((mary, ns["hasName"], Literal("Mary"))) gmary.add((mary, ns["loves"], john)) # add a graph for John's facts to the Conjunctive Graph gjohn = Graph(store=store_input, identifier=cjohn) # John's graph contains his cute name gjohn.add((john, ns["hasCuteName"], Literal("Johnny Boy"))) # enumerate contexts print("Input contexts") for c in gconjunctive.contexts(): print("-- %s " % c) # separate graphs if False: print("===================") print("GJOHN") print(gjohn.serialize(format="n3").decode("utf-8")) print("===================") print("GMARY") print(gmary.serialize(format="n3").decode("utf-8")) print("===================") # full graph print("===================") print("GCONJUNCTIVE NATIVE") print(gconjunctive.serialize(format="n3").decode("utf-8")) # query the conjunction of all graphs xx = None for x in gconjunctive[mary:ns.loves / ns.hasCuteName]: xx = x print("Q: Who does Mary love?") print("A: Mary loves {}".format(xx)) # Ensuite, on sauve un seul sous-graphe, puis on le recharge et le resultat doit etre le meme. gjohn.serialize(destination='gjohn_copy.xml', format='xml') gmary.serialize(destination='gmary_copy.xml', format='xml') gjohn_copy = Graph() gjohn_copy.parse('gjohn_copy.xml', format='xml') gmary_copy = Graph() gmary_copy.parse('gmary_copy.xml', format='xml') if True: print("===================") print("GJOHN") print(gjohn_copy.serialize(format="n3").decode("utf-8")) print("===================") print("GMARY") print(gmary_copy.serialize(format="n3").decode("utf-8")) print("===================") print("===================") print("GCONJUNCTIVE WITH QUADS") print(list(gconjunctive.quads(None))) print("===================") gconjunctive.serialize(destination='gconjunctive_copy.xml', format='xml') gconjunctive_copy = ConjunctiveGraph() gconjunctive_copy.parse('gconjunctive_copy.xml', format='xml') print("===================") print("GCONJUNCTIVE AS CONJUNCTIVE") print(gconjunctive_copy.serialize(format="n3").decode("utf-8")) print("Output contexts") for c in gconjunctive_copy.contexts(): print("-- %s " % c) print("===================") gconjunctive_graph_copy = Graph() gconjunctive_graph_copy.parse('gconjunctive_copy.xml', format='xml') print("===================") print("GCONJUNCTIVE AS GRAPH") print(gconjunctive_graph_copy.serialize(format="n3").decode("utf-8")) #print("Output contexts") #for c in gconjunctive_graph_copy.contexts(): # print("-- %s " % c) print("===================")