You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tinkerpop.apache.org by "Marko A. Rodriguez (JIRA)" <ji...@apache.org> on 2015/10/09 20:13:05 UTC

[jira] [Updated] (TINKERPOP3-881) [Proposal] A Process-Based Graph Reasoner

     [ https://issues.apache.org/jira/browse/TINKERPOP3-881?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Marko A. Rodriguez updated TINKERPOP3-881:
------------------------------------------
    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:

{code}
marko--ancestor-->jose--ancestor-->fernando--ancestor-->someSpanishDude
{code}

Then when you did the following query:

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

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:

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

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?

{code}
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=b
  ...other stuff
  .create();
{code}

Here are some links to study:

* https://jena.apache.org/documentation/inference/#the-owl-reasoner
* http://owl.man.ac.uk/2003/why/latest/

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


  was:
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:

{code}
marko--ancestor-->jose--ancestor-->fernando--ancestor-->someSpanishDude
{code}

Then when you did the following query:

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

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:

{code}
g.V.has('name','marko').repeat(out('ancestor')).name
{code}

In essence, "transitive" means {{repeat(...).until(false)}} (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?

{code}
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=b
  ...other stuff
  .create();
{code}

Here are some links to study:

* https://jena.apache.org/documentation/inference/#the-owl-reasoner
* http://owl.man.ac.uk/2003/why/latest/

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



> [Proposal] A Process-Based Graph Reasoner
> -----------------------------------------
>
>                 Key: TINKERPOP3-881
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP3-881
>             Project: TinkerPop 3
>          Issue Type: New Feature
>          Components: process
>            Reporter: Marko A. Rodriguez
>            Assignee: Marko A. Rodriguez
>
> 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:
> {code}
> marko--ancestor-->jose--ancestor-->fernando--ancestor-->someSpanishDude
> {code}
> Then when you did the following query:
> {code}
> gremlin> g.V.has('name','marko').out('ancestor').name
> ==>jose
> ==>fernando
> ==>someSpanishDude
> {code}
> 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:
> {code}
> g.V.has('name','marko').repeat(out('ancestor')).emit().name
> {code}
> 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?
> {code}
> 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=b
>   ...other stuff
>   .create();
> {code}
> Here are some links to study:
> * https://jena.apache.org/documentation/inference/#the-owl-reasoner
> * http://owl.man.ac.uk/2003/why/latest/
> In my experience, you can do a lot with support for the basics: transitive, symmetric, etc.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)