예제 #1
0
파일: inference.py 프로젝트: drewp/homeauto
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
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
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("===================")