GithubHelp home page GithubHelp logo

Comments (3)

edmondchuc avatar edmondchuc commented on June 20, 2024 1

Perhaps this runnable example will explain it clearer.

from rdflib import Graph
from rdflib.compare import isomorphic

data = """
    <urn:object> <urn:hasPart> _:internal-bnode-id-1 .
    _:internal-bnode-id-1 <urn:value> "..." .
"""

skolem_graph = Graph().parse(data=data, format="ntriples").skolemize()
graph = Graph().parse(data=data, format="ntriples")

assert isomorphic(skolem_graph.de_skolemize(), graph)

# The output should contain the skolem IRI
# <https://rdflib.github.io/.well-known/genid/rdflib/internal-bnode-id-1>
# but instead, we get something like:
#
#     <https://rdflib.github.io/.wellknown/genid/rdflib/N19d54f84f7e84ba8a270ddb627e92cdb> <urn:value> "..." .
#     <urn:object> <urn:hasPart> <https://rdflib.github.io/.well-known/genid/rdflib/N19d54f84f7e84ba8a270ddb627e92cdb> .
#
# where N19d54f84f7e84ba8a270ddb627e92cdb is the remapped blank node id by RDFLib.
skolem_graph.print(format="ntriples")

If we are able to skolemize blank nodes at parse time, we should expect an output like this:

<urn:object> <urn:hasPart> <https://rdflib.github.io/.well-known/genid/rdflib/internal-bnode-id-1> .
<https://rdflib.github.io/.well-known/genid/rdflib/internal-bnode-id-1> <urn:value> "..." .

Essentially, without a change to the logic at parse time, it's impossible to skolemize blank nodes and preserve the identifiers in the original data.

from rdflib.

WhiteGobo avatar WhiteGobo commented on June 20, 2024

I'll look into this. But it seems to me, as we had to work on both the store and on the parser for that.

I havent tried this and im sure there are some problems with that but:
Have you tried other means to skolemize your graph? for example create a skolemized version of your graph per hand an reusing the resulting bnode_context?

Something like this:

from rdflib import Graph
from rdflib.compare import isomorphic

bnode_context_A: MutableMapping[str, BNode] = {}
in_graph = Graph().parse("data.nt", format="ntriples", bnode_context=bnode_context_A)
bnode_context_B = {}
skolem_graph = Graph()
for ax in in_graph:
  for x in ax:
    if x not in bnode_context_B:
      bnode_context_B[x] = skolemize(x)
  skolem_graph.add((bnode_context_B.get(x, x) for x in ax))
bnode_context = {k, bnode_context_B[v] for k, v in bnode_context_A.items()}

graph = Graph().parse("data.nt", format="ntriples")

assert isomorphic(in_graph, graph)

I havent looked into how to get this then to work:

# I can use skolem_graph across systems with the blank node identifiers preserved from the original data.nt file.
skolem_graph.serialize(format="ntriples")

But you should be able to load now with persistent skolemization:

#This sould be the same graph as skolem_graph:
new_graph = Graph().parse("data.nt", format="ntriples", bnode_context=bnode_context)

from rdflib.

WhiteGobo avatar WhiteGobo commented on June 20, 2024

Would it be enough to use an identity mapping for bnode_context?

from rdflib import Graph, BNode
from rdflib.compare import isomorphic

data = """
    <urn:object> <urn:hasPart> _:internal-bnode-id-1 .
    _:internal-bnode-id-1 <urn:value> "..." .
"""

from typing import MutableMapping
class IdMap(MutableMapping[str, BNode]):
    def __init__(self, dct=None):
        self.dct = {} if dct is None else dct 

    def __getitem__(self, key: str) -> BNode:
        return self.dct.setdefault(key, BNode(key))

    def __setitem__(self, key: str, value: BNode):
        self.dct[key] = value

    def __delitem__(self, key: str):
        return self.dct.__delitem__(key)

    def __iter__(self):
        return iter(self.dct)

    def __len__(self) -> int:
        return len(self.dct)


skolem_graph = Graph().parse(data=data, format="ntriples", bnode_context=IdMap())
for x in skolem_graph:
    print(x)

Im not sure how to make a transparent implemention of skolemization during parsing. I would rather invest time into the documentation of skolemization in rdflib and have a recipe of this somewhere.

from rdflib.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.