Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggested method on Graph for BNode Closure #123

Closed
ghost opened this issue Feb 20, 2012 · 8 comments
Closed

Suggested method on Graph for BNode Closure #123

ghost opened this issue Feb 20, 2012 · 8 comments
Labels
enhancement New feature or request in-resolution
Milestone

Comments

@ghost
Copy link

ghost commented Feb 20, 2012

wwai...@gmail.com, 2010-07-22T16:05:40.000Z

def bnc(self, triple, *av, **kw):
        """                                                                                                                   
        Return the BNode closure(s) for triples that are matched                                                              
        by the given "triple". Any additional positional or keyword                                                           
        arguments are passed to the constructor for the new graph.                                                            
        """
        result = Graph(*av, **kw)
        for s,p,o in self.triples(triple):
            result.add((s,p,o))
            if isinstance(o, BNode):
                result += self.bnc((o, None, None))
        return result

Comment 1 by wwai...@gmail.com

Supporting methods:

    def one(self, triple):
        """
        Return one matching "triple" or "None"
        """
        for statement in self.triples(triple):
            return statement

    def exists(self, triple):
        """
        Return "True" if "triple" exists in the graph, "False" otherwise
        """
        statement = self.one(triple)
        if statement is not None:
            return True
        return False

Comment 2 by wwai...@gmail.com

improved original function that won't loop in case of silly bnode loops (thanks gromgull):

   def bnc(self, triple, *av, **kw):
        """                                                                                                                   
        Return the BNode closure(s) for triples that are matched                                                              
        by the given "triple". Any additional positional or keyword                                                           
        arguments are passed to the constructor for the new graph.                                                            
        """
        result = Graph(*av, **kw)
        for s,p,o in self.triples(triple):
            result.add((s,p,o))
            if isinstance(o, BNode) and not result.exists((o, None, None)):
                result += self.bnc((o, None, None))
        return result

Comment 3 by wwai...@gmail.com

This code comes from:

http://knowledgeforge.net/pdw/ordf/file/tip/ordf/graph.py

Comment 4 by vfaronov

Graphs support the in operator, so exists is unnecessary, I believe.

Comment 5 by drewpca

one() should raise an exception instead of returning None. The functionality is the same either way (though the exception can include a helpful message), but with None, every caller is obligated to check the type of the output. Forgetting to do so will lead to TypeErrors later on (when someone tries to unpack the None value).

'bnc' should have a descriptive name, possibly 'bnode_closure' or 'bnode_closure_graph'. Why doesn't a subject (or predicate) bnode cause recursion? (None, FOAF.name, Literal("Drew")) might be the IFP that I use to find a person, and wouldn't bnode_closure be the right way to get the other triples about that person? If I'm getting the use case wrong, please revise the docstring to explain why only objects are checked for BNode.

@gromgull
Copy link
Member

I think I agree with drew that also getting all triples about subject would be useful. (bnodes as predicates are forbidding in RDF, for some arbitrary reason)

Also, the method should be rewritten to recurse with generators, and only create a graph at top level. Now many graph object may be created.

It would be nice to implement using the transitiveClosure method, but 1. it breaks on loops (#206), and it does not let you have separate conditions for including the triple and recursing.

@joernhees
Copy link
Member

should we maybe also name this Concise Bounded Description?

@uholzer
Copy link
Contributor

uholzer commented Mar 18, 2015

I vote for supporting any kind of node in all positions of the triple (i.e. supporting generalized RDF triples) whenever it does not increase complexity too much. For example, reasoners may produce such triples. The in-memory store supports them.

Maybe it should be configurable in which position blank nodes are followed?

I too, would prefer iterators. Unfortunately, it does not seem straight forward to implement, as you must somehow remember which nodes you have already visited. Another option is to create the graph on the toplevel and hand it down the recursive calls.

@white-gecko
Copy link
Member

I like the bnc idea. maybe it should also include the whole closure of the subject, if it is a blank node.

@nicholascar
Copy link
Member

@gjhiggins we are likely to implement a version of this as a precursor to facilitating SPARQL DESCRIBE queries and a few other things in an rdflib 6.0.0 release around July. If you're keen to be involved in a rejuvenated rdflib release cycle, please be in touch with me or either of the other two new maintainers (@white-gecko or @ashleysommer) or on the mailing list. We'd love to have you with your wealth of rdflib/RDF knowledge involved!

@nicholascar nicholascar added this to the rdflib 6.0.0 milestone Mar 15, 2020
@ghost
Copy link
Author

ghost commented Mar 26, 2020

I don't have any comments on this. My role here was simply one of housekeeping - in this instance, transcribing a suggestion made in the group mailing list.

@nicholascar
Copy link
Member

Thanks for letting us know Graham!

@ghost
Copy link
Author

ghost commented Dec 23, 2021

Implemented in #1502

@ghost ghost closed this as completed Dec 23, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request in-resolution
Projects
None yet
Development

No branches or pull requests

5 participants