Uploaded image for project: 'TinkerPop'
  1. TinkerPop
  2. TINKERPOP-881

[Proposal] A Process-Based Graph Reasoner

VotersWatch issueWatchersLinkCloneUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Major
    • Resolution: Later
    • 3.0.2-incubating
    • None
    • process
    • None

    Description

      This would be a big initiative, so its more than "just a ticket," but it would be a neat idea.

      A reasoner allows someone to express implicit edges/properties in the graph. For instance, it is possible to say that ancestor is transitive. If there was an explicit graph structure like:

      marko--ancestor-->jose--ancestor-->fernando--ancestor-->someSpanishDude
      

      Then when you did the following query:

      gremlin> g.V.has('name','marko').out('ancestor').name
      ==>jose
      ==>fernando
      ==>someSpanishDude
      

      That is, because it is declared the ancestor is transitive, the implicit marko-ancestor->someSpanishDude is generated. Now, there are two types of reasoners: structure and process.

      A structure reasoner will infer all the entailments of the schema when the graph is modified (added to or deleted from). Thus, what is implicit is made explicit and put into the graph. With this model, your data set has more data than what was explicitly put into it.

      A process reasoner will infer all the entailments of the schema as it pertains to the current query being executed. Thus, what is implicit is made explicit at query runtime. With this model, you data set contains only what was explicitly inserted.

      These two models either make a sacrifice of space or time.

      If we wanted just a process reasoner, then this could be a ReasoningStrategy extends DecorationStrategy. Where the above ancestor query would be rewritten as:

      g.V.has('name','marko').repeat(out('ancestor')).emit().name
      

      In essence, "transitive" means repeat(...).until(false).emit() (loop until you can loop no more).

      I prefer the process reasoner model as its less cumbersome and potentially damaging to the integrity of the underlying data set. Moreover, it can be "easily" implemented as a TraversalStrategy.

      The next question is, how is the reasoning schema (ontology) specified? Perhaps via a builder?

      ReasoningStrategy.build().
        .transitive("ancestor")
        .subEdge("hasPet","likes") // if I have a pet dog, I like dogs.
        .symmetric("friend") // a.friend.b implies b.friend.c
        .functional("marriedTo") // a.marriedTo.b, c.marriedTo.b ==> a=c
        ...other stuff
        .create();
      

      Here are some links to study:

      In my experience, you can do a lot with support for the basics: transitive, symmetric, etc.

      Attachments

        Activity

          This comment will be Viewable by All Users Viewable by All Users
          Cancel

          People

            Unassigned Unassigned
            okram Marko A. Rodriguez
            Votes:
            1 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Slack

                Issue deployment