You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by Kenneth Keefe <kj...@illinois.edu> on 2020/05/11 22:56:03 UTC

Help with inference rules

I am pretty new to using Jena and OWL. I have read many great tutorials
regarding RDF and OWL. The focus of those tutorials has largely been how to
structure the ontology and define restrictions on properties and such.
However, I have not been able to find good tutorials that explain how
inference is done and how I can define my own inference rules. I'm
wondering if I am simply not searching for the right thing.

Regardless, here is a significant example that I think will really help me
get started with inference using Jena. I created a minimal example to
enable discussion. Here is a pastebin:  https://pastebin.com/ScTGcbcZ

The ontology has two classes, RosterEntry and Person and three data
properties, Signature (associated with RosterEntry), and FirstName and
LastName (both associated with Person). The example also has two
RosterEntry individuals with signatures of "Bob Smith" and "Sally Jones."

I would like to write a rule that causes Jena to infer the following new
facts:

<owl:Individual>
>         <rdf:type
>             rdf:resource="http://example.com/ont/roster/Person" />
>         <hasFirstName>Bob</hasFirstName>

        <hasLastName>Smith</hasLastName>

    </owl:Individual>


<owl:Individual>
>         <rdf:type
>             rdf:resource="http://example.com/ont/roster/Person" />
>         <hasFirstName>Sally</hasFirstName>

        <hasLastName>Jones</hasLastName>

    </owl:Individual>


How do I do that? Full answers or nudges in the right direction are both
very welcome. Thank you!

Ken

Re: Help with inference rules

Posted by Kenneth Keefe <kj...@illinois.edu>.
Thank you! That was what I needed and I have learned quite a bit.

Here is the rule I ended up using:

@prefix ro: <http://example.com/ont/roster/>.
>
>  [r1: (?x rdf:type ro:RosterEntry), (?x ro:hasSignature ?sig), regex(?sig,
> '(.*) (.*)', ?first, ?last), uriConcat('
> http://example.com/ont/roster/people/', ?first, ?last, ?y) -> (?y
> ro:hasFirstName ?first),  (?y ro:hasLastName ?last),  (?y rdf:type
> ro:Person)]


With that rule, the inferred model contains:

http://example.com/ont/roster/people/BobSmith type Person .
> http://example.com/ont/roster/people/BobSmith hasLastName "Smith" .
> http://example.com/ont/roster/people/BobSmith hasFirstName "Bob" .
> http://example.com/ont/roster/people/SallyJones type Person .
> http://example.com/ont/roster/people/SallyJones hasLastName "Jones" .
> http://example.com/ont/roster/people/SallyJones hasFirstName "Sally" .
> http://example.com/ont/roster/ versionIRI .
> http://example.com/ont/roster/ type Ontology .
> http://example.com/ont/roster/RosterEntry type Class .
> http://example.com/ont/roster/bobEntry hasSignature "Bob Smith" .
> http://example.com/ont/roster/bobEntry type RosterEntry .
> http://example.com/ont/roster/bobEntry type NamedIndividual .
> http://example.com/ont/roster/Person type Class .
> http://example.com/ont/roster/hasLastName range string .
> http://example.com/ont/roster/hasLastName domain Person .
> http://example.com/ont/roster/hasLastName type DatatypeProperty .
> http://example.com/ont/roster/sallyEntry hasSignature "Sally Jones" .
> http://example.com/ont/roster/sallyEntry type RosterEntry .
> http://example.com/ont/roster/sallyEntry type NamedIndividual .
> http://example.com/ont/roster/hasSignature range string .
> http://example.com/ont/roster/hasSignature domain RosterEntry .
> http://example.com/ont/roster/hasSignature type DatatypeProperty .
> http://example.com/ont/roster/hasFirstName range string .
> http://example.com/ont/roster/hasFirstName domain Person .
> http://example.com/ont/roster/hasFirstName type DatatypeProperty .


On Wed, May 27, 2020 at 2:14 AM Dave Reynolds <da...@gmail.com>
wrote:

> On 27/05/2020 04:54, Kenneth Keefe wrote:
> > Thank you! Can you suggest any texts that teach how to effectively write
> > inference rules for Jena?
>
> I don't know of any though no doubt there's the odd blog post example.
>
> > However, I'm not having success changing the node URIs. When I change the
> > rule to this:
> >
> >   [r1: (?x rdf:type ro:RosterEntry), (?x ro:hasSignature ?sig),
> regex(?sig,
> >> '(.*) (.*)', ?first, ?last), makeSkolem(?y, ?x), uriConcat('
> >> http://example.com/ont/roster/people/', ?first, ?last, ?y) -> (?y
> >> ro:hasFirstName ?first),  (?y ro:hasLastName ?last),  (?y rdf:type
> >> ro:Person)]
> >
> >
> > Jena doesn't seem to infer any new nodes.
> Why have both makeSkolem and uriConcat? You either want to create a URI
> resource as your subject or create a bNode. That's trying to make it
> both, which can never happen so the rule never fires.
>
> > I tried separating it into another rule:
> >
> >   [r1: (?x rdf:type ro:RosterEntry), (?x ro:hasSignature ?sig),
> regex(?sig,
> >> '(.*) (.*)', ?first, ?last), makeSkolem(?y, ?x) -> (?y ro:hasFirstName
> >> ?first),  (?y ro:hasLastName ?last),  (?y rdf:type ro:Person)]
> >>   [r2: (?x rdf:type ro:Person), (?x ro:hasFirstName ?first), (?x
> >> ro:hasLastName ?last), uriConcat('http://example.com/ont/roster/people/
> ',
> >> ?first, ?last, ?y) -> print('woot', ?y)]
> >
> >
> > What is strange is that with the second rule, the inference engine prints
> > out:
> >
> > 'woot' <http://example.com/ont/roster/people/BobSmith>
> > 'woot' <http://example.com/ont/roster/people/SallyJones>
> >
> > But, when I listStatements and print out the InfModel,
> >
> > I get the same node URIs:
> >
> > 1PXx9jabIZ6w9mfO0GygJA== type Person .
> >> 1PXx9jabIZ6w9mfO0GygJA== hasLastName "Jones" .
> >> 1PXx9jabIZ6w9mfO0GygJA== hasFirstName "Sally" .
> >> lOqL7Rx2Lwv5OK6BWD/jSA== type Person .
> >> lOqL7Rx2Lwv5OK6BWD/jSA== hasLastName "Smith" .
> >> lOqL7Rx2Lwv5OK6BWD/jSA== hasFirstName "Bob" .
> >
> >
> > So, does uriConcat not set the node's uri permanently?
>
> Ah, I think you might be imaging that uriConcat somehow rewrites the
> node in an RDF graph so it has a name. No. Like all the rule builtins
> all it does is bind a value to a variable or, if the variable already
> has a value, then test it matches.
>
> So just should just need something like (untested):
>
>   [r1: (?x rdf:type ro:RosterEntry),
>        (?x ro:hasSignature ?sig),
>        regex(?sig, '(.*) (.*)', ?first, ?last),
>       uriConcat('http://example.com/ont/roster/people/', ?first, ?last,
> ?y)
>     -> (?y ro:hasFirstName ?first),
>        (?y ro:hasLastName ?last),
>        (?y rdf:type ro:Person)]
>
> Dave
>
> > On Sun, May 24, 2020 at 6:03 AM Dave Reynolds <dave.e.reynolds@gmail.com
> >
> > wrote:
> >
> >> Sorry, only just noticed this question. Responses below:
> >>
> >> On 20/05/2020 10:41, Kenneth Keefe wrote:
> >>> Thanks for all the help so far! I've made some good progress on this
> >>> example I'm trying to forge. Here are the files for this example:
> >>>
> >>> Ontology: https://cioi.iti.illinois.edu/ont/examples/roster.owl
> >>> Rules: https://cioi.iti.illinois.edu/ont/examples/roster.rules
> >>>
> >>> Using this code:
> >>>
> >>> OntModel model =
> >> ModelFactory.*createOntologyModel*(OntModelSpec.*OWL_MEM*);
> >>>
> >>> model.read("file:roster.owl");
> >>>
> >>> List<Rule> rules = Rule.*rulesFromURL*("file:roster.rules");
> >>>
> >>> Reasoner reasoner = new GenericRuleReasoner(rules);
> >>>
> >>> InfModel inf = ModelFactory.*createInfModel*(reasoner, model);
> >>>
> >>>
> >>> printAllStatements(inf);
> >>>
> >>> I get this output (I use the LocalName for the predicates and objects
> for
> >>> readability):
> >>>
> >>> b04230c7-55dc-4e08-92d7-26559c0c478f hasLastName "Smith" .
> >>> c33de24f-82f1-4aa2-a78e-73201341b274 type Person .
> >>> c812ff54-30bf-49e7-8e35-3544dad096b7 hasFirstName "Sally" .
> >>> 16b7a887-2fb9-4bdb-a529-34ca8b3137e4 hasFirstName "Bob" .
> >>> b31eb7d5-a8ad-469e-ae83-366bdf46fd72 hasLastName "Jones" .
> >>> 8b46f0c7-4eb2-41e2-8789-8967e8f63eec type Person .
> >>> http://example.com/ont/roster/ versionIRI .
> >>> http://example.com/ont/roster/ type Ontology .
> >>> http://example.com/ont/roster/RosterEntry type Class .
> >>> http://example.com/ont/roster/bobEntry hasSignature "Bob Smith" .
> >>> http://example.com/ont/roster/bobEntry type RosterEntry .
> >>> http://example.com/ont/roster/bobEntry type NamedIndividual .
> >>> http://example.com/ont/roster/Person type Class .
> >>> http://example.com/ont/roster/hasLastName range string .
> >>> http://example.com/ont/roster/hasLastName domain Person .
> >>> http://example.com/ont/roster/hasLastName type DatatypeProperty .
> >>> http://example.com/ont/roster/sallyEntry hasSignature "Sally Jones" .
> >>> http://example.com/ont/roster/sallyEntry type RosterEntry .
> >>> http://example.com/ont/roster/sallyEntry type NamedIndividual .
> >>> http://example.com/ont/roster/hasSignature range string .
> >>> http://example.com/ont/roster/hasSignature domain RosterEntry .
> >>> http://example.com/ont/roster/hasSignature type DatatypeProperty .
> >>> http://example.com/ont/roster/hasFirstName range string .
> >>> http://example.com/ont/roster/hasFirstName domain Person .
> >>> http://example.com/ont/roster/hasFirstName type DatatypeProperty .
> >>>
> >>> Here are my questions:
> >>>
> >>> Focusing on just the Bob Smith entry:
> >>>
> >>> b04230c7-55dc-4e08-92d7-26559c0c478f hasLastName "Smith" .
> >>> c33de24f-82f1-4aa2-a78e-73201341b274 type Person .
> >>> 16b7a887-2fb9-4bdb-a529-34ca8b3137e4 hasFirstName "Bob" .
> >>>
> >>> 1. Are these unique ids of anonymous nodes?
> >>
> >> Yes.
> >>
> >>> 2. Why are they not identical across these three lines?
> >>
> >> Because your ?y variable hasn't been bound in the rule body, each triple
> >> pattern finds there's no value for ?y and separately treats it as a
> bNode.
> >>
> >> If you want a shared bNode then use makeTemp(?y) in the body (or
> >> makeSoklem).
> >>
> >>> 3. Is there a way to name these new nodes in the rule? For example,
> make
> >>> the new node http://example.com/ont/roster/people/BobSmith.
> >>
> >> Sure, use uriConcat, something like (untested):
> >>
> >>      uriConcat('http://example.com/ont/roster/people/', ?first, ?last,
> >> ?y) -> ...
> >>
> >> Dave
> >>
> >>>
> >>> Thank you!
> >>>
> >>> Ken
> >>>
> >>>
> >>>
> >>>
> >>>
> >>> On Tue, May 12, 2020 at 1:44 AM Lorenz Buehmann <
> >>> buehmann@informatik.uni-leipzig.de> wrote:
> >>>
> >>>> Hi,
> >>>>
> >>>> I think the rule would be basically
> >>>>
> >>>> [r1: (?x rdf:type ex:RosterEntry), (?x ex:hasSignature ?sig),
> >>>> regex(?sig, '(.*) (.*)', ?first, ?last)  -> (?x ex:hasFirstName
> >>>> ?first),  (?x ex:hasLastName ?last),  (?x rdf:type ex:Person) ) ]
> >>>>
> >>>> Note, it's untested and you have to define your prefix ex: in the
> rules
> >>>> file. You might also have to adapt the regex pattern to cover
> different
> >>>> white space chars.
> >>>>
> >>>> On 12.05.20 00:56, Kenneth Keefe wrote:
> >>>>> I am pretty new to using Jena and OWL. I have read many great
> tutorials
> >>>>> regarding RDF and OWL. The focus of those tutorials has largely been
> >> how
> >>>> to
> >>>>> structure the ontology and define restrictions on properties and
> such.
> >>>>> However, I have not been able to find good tutorials that explain how
> >>>>> inference is done and how I can define my own inference rules. I'm
> >>>>> wondering if I am simply not searching for the right thing.
> >>>>>
> >>>>> Regardless, here is a significant example that I think will really
> help
> >>>> me
> >>>>> get started with inference using Jena. I created a minimal example to
> >>>>> enable discussion. Here is a pastebin:
> https://pastebin.com/ScTGcbcZ
> >>>>>
> >>>>> The ontology has two classes, RosterEntry and Person and three data
> >>>>> properties, Signature (associated with RosterEntry), and FirstName
> and
> >>>>> LastName (both associated with Person). The example also has two
> >>>>> RosterEntry individuals with signatures of "Bob Smith" and "Sally
> >> Jones."
> >>>>>
> >>>>> I would like to write a rule that causes Jena to infer the following
> >> new
> >>>>> facts:
> >>>>>
> >>>>> <owl:Individual>
> >>>>>>           <rdf:type
> >>>>>>               rdf:resource="http://example.com/ont/roster/Person"
> />
> >>>>>>           <hasFirstName>Bob</hasFirstName>
> >>>>>           <hasLastName>Smith</hasLastName>
> >>>>>
> >>>>>       </owl:Individual>
> >>>>>
> >>>>>
> >>>>> <owl:Individual>
> >>>>>>           <rdf:type
> >>>>>>               rdf:resource="http://example.com/ont/roster/Person"
> />
> >>>>>>           <hasFirstName>Sally</hasFirstName>
> >>>>>           <hasLastName>Jones</hasLastName>
> >>>>>
> >>>>>       </owl:Individual>
> >>>>>
> >>>>>
> >>>>> How do I do that? Full answers or nudges in the right direction are
> >> both
> >>>>> very welcome. Thank you!
> >>>>>
> >>>>> Ken
> >>>>>
> >>>>
> >>>>
> >>>
> >>
> >
> >
>


-- 
-------
Ken Keefe
Senior Software Engineer
Information Trust Institute
University of Illinois at Urbana-Champaign
1308 W. Main St.
CSL 225
Urbana, Illinois 61801, USA
Phone: 217-244-3203
Web: https://www.perform.illinois.edu/~kjkeefe
Email: kjkeefe@illinois.edu

Re: Help with inference rules

Posted by Dave Reynolds <da...@gmail.com>.
On 27/05/2020 04:54, Kenneth Keefe wrote:
> Thank you! Can you suggest any texts that teach how to effectively write
> inference rules for Jena? 

I don't know of any though no doubt there's the odd blog post example.

> However, I'm not having success changing the node URIs. When I change the
> rule to this:
> 
>   [r1: (?x rdf:type ro:RosterEntry), (?x ro:hasSignature ?sig), regex(?sig,
>> '(.*) (.*)', ?first, ?last), makeSkolem(?y, ?x), uriConcat('
>> http://example.com/ont/roster/people/', ?first, ?last, ?y) -> (?y
>> ro:hasFirstName ?first),  (?y ro:hasLastName ?last),  (?y rdf:type
>> ro:Person)]
> 
> 
> Jena doesn't seem to infer any new nodes.
Why have both makeSkolem and uriConcat? You either want to create a URI 
resource as your subject or create a bNode. That's trying to make it 
both, which can never happen so the rule never fires.

> I tried separating it into another rule:
> 
>   [r1: (?x rdf:type ro:RosterEntry), (?x ro:hasSignature ?sig), regex(?sig,
>> '(.*) (.*)', ?first, ?last), makeSkolem(?y, ?x) -> (?y ro:hasFirstName
>> ?first),  (?y ro:hasLastName ?last),  (?y rdf:type ro:Person)]
>>   [r2: (?x rdf:type ro:Person), (?x ro:hasFirstName ?first), (?x
>> ro:hasLastName ?last), uriConcat('http://example.com/ont/roster/people/',
>> ?first, ?last, ?y) -> print('woot', ?y)]
> 
> 
> What is strange is that with the second rule, the inference engine prints
> out:
> 
> 'woot' <http://example.com/ont/roster/people/BobSmith>
> 'woot' <http://example.com/ont/roster/people/SallyJones>
> 
> But, when I listStatements and print out the InfModel,
> 
> I get the same node URIs:
> 
> 1PXx9jabIZ6w9mfO0GygJA== type Person .
>> 1PXx9jabIZ6w9mfO0GygJA== hasLastName "Jones" .
>> 1PXx9jabIZ6w9mfO0GygJA== hasFirstName "Sally" .
>> lOqL7Rx2Lwv5OK6BWD/jSA== type Person .
>> lOqL7Rx2Lwv5OK6BWD/jSA== hasLastName "Smith" .
>> lOqL7Rx2Lwv5OK6BWD/jSA== hasFirstName "Bob" .
> 
> 
> So, does uriConcat not set the node's uri permanently?

Ah, I think you might be imaging that uriConcat somehow rewrites the 
node in an RDF graph so it has a name. No. Like all the rule builtins 
all it does is bind a value to a variable or, if the variable already 
has a value, then test it matches.

So just should just need something like (untested):

  [r1: (?x rdf:type ro:RosterEntry),
       (?x ro:hasSignature ?sig),
       regex(?sig, '(.*) (.*)', ?first, ?last),
      uriConcat('http://example.com/ont/roster/people/', ?first, ?last, ?y)
    -> (?y ro:hasFirstName ?first),
       (?y ro:hasLastName ?last),
       (?y rdf:type ro:Person)]

Dave

> On Sun, May 24, 2020 at 6:03 AM Dave Reynolds <da...@gmail.com>
> wrote:
> 
>> Sorry, only just noticed this question. Responses below:
>>
>> On 20/05/2020 10:41, Kenneth Keefe wrote:
>>> Thanks for all the help so far! I've made some good progress on this
>>> example I'm trying to forge. Here are the files for this example:
>>>
>>> Ontology: https://cioi.iti.illinois.edu/ont/examples/roster.owl
>>> Rules: https://cioi.iti.illinois.edu/ont/examples/roster.rules
>>>
>>> Using this code:
>>>
>>> OntModel model =
>> ModelFactory.*createOntologyModel*(OntModelSpec.*OWL_MEM*);
>>>
>>> model.read("file:roster.owl");
>>>
>>> List<Rule> rules = Rule.*rulesFromURL*("file:roster.rules");
>>>
>>> Reasoner reasoner = new GenericRuleReasoner(rules);
>>>
>>> InfModel inf = ModelFactory.*createInfModel*(reasoner, model);
>>>
>>>
>>> printAllStatements(inf);
>>>
>>> I get this output (I use the LocalName for the predicates and objects for
>>> readability):
>>>
>>> b04230c7-55dc-4e08-92d7-26559c0c478f hasLastName "Smith" .
>>> c33de24f-82f1-4aa2-a78e-73201341b274 type Person .
>>> c812ff54-30bf-49e7-8e35-3544dad096b7 hasFirstName "Sally" .
>>> 16b7a887-2fb9-4bdb-a529-34ca8b3137e4 hasFirstName "Bob" .
>>> b31eb7d5-a8ad-469e-ae83-366bdf46fd72 hasLastName "Jones" .
>>> 8b46f0c7-4eb2-41e2-8789-8967e8f63eec type Person .
>>> http://example.com/ont/roster/ versionIRI .
>>> http://example.com/ont/roster/ type Ontology .
>>> http://example.com/ont/roster/RosterEntry type Class .
>>> http://example.com/ont/roster/bobEntry hasSignature "Bob Smith" .
>>> http://example.com/ont/roster/bobEntry type RosterEntry .
>>> http://example.com/ont/roster/bobEntry type NamedIndividual .
>>> http://example.com/ont/roster/Person type Class .
>>> http://example.com/ont/roster/hasLastName range string .
>>> http://example.com/ont/roster/hasLastName domain Person .
>>> http://example.com/ont/roster/hasLastName type DatatypeProperty .
>>> http://example.com/ont/roster/sallyEntry hasSignature "Sally Jones" .
>>> http://example.com/ont/roster/sallyEntry type RosterEntry .
>>> http://example.com/ont/roster/sallyEntry type NamedIndividual .
>>> http://example.com/ont/roster/hasSignature range string .
>>> http://example.com/ont/roster/hasSignature domain RosterEntry .
>>> http://example.com/ont/roster/hasSignature type DatatypeProperty .
>>> http://example.com/ont/roster/hasFirstName range string .
>>> http://example.com/ont/roster/hasFirstName domain Person .
>>> http://example.com/ont/roster/hasFirstName type DatatypeProperty .
>>>
>>> Here are my questions:
>>>
>>> Focusing on just the Bob Smith entry:
>>>
>>> b04230c7-55dc-4e08-92d7-26559c0c478f hasLastName "Smith" .
>>> c33de24f-82f1-4aa2-a78e-73201341b274 type Person .
>>> 16b7a887-2fb9-4bdb-a529-34ca8b3137e4 hasFirstName "Bob" .
>>>
>>> 1. Are these unique ids of anonymous nodes?
>>
>> Yes.
>>
>>> 2. Why are they not identical across these three lines?
>>
>> Because your ?y variable hasn't been bound in the rule body, each triple
>> pattern finds there's no value for ?y and separately treats it as a bNode.
>>
>> If you want a shared bNode then use makeTemp(?y) in the body (or
>> makeSoklem).
>>
>>> 3. Is there a way to name these new nodes in the rule? For example, make
>>> the new node http://example.com/ont/roster/people/BobSmith.
>>
>> Sure, use uriConcat, something like (untested):
>>
>>      uriConcat('http://example.com/ont/roster/people/', ?first, ?last,
>> ?y) -> ...
>>
>> Dave
>>
>>>
>>> Thank you!
>>>
>>> Ken
>>>
>>>
>>>
>>>
>>>
>>> On Tue, May 12, 2020 at 1:44 AM Lorenz Buehmann <
>>> buehmann@informatik.uni-leipzig.de> wrote:
>>>
>>>> Hi,
>>>>
>>>> I think the rule would be basically
>>>>
>>>> [r1: (?x rdf:type ex:RosterEntry), (?x ex:hasSignature ?sig),
>>>> regex(?sig, '(.*) (.*)', ?first, ?last)  -> (?x ex:hasFirstName
>>>> ?first),  (?x ex:hasLastName ?last),  (?x rdf:type ex:Person) ) ]
>>>>
>>>> Note, it's untested and you have to define your prefix ex: in the rules
>>>> file. You might also have to adapt the regex pattern to cover different
>>>> white space chars.
>>>>
>>>> On 12.05.20 00:56, Kenneth Keefe wrote:
>>>>> I am pretty new to using Jena and OWL. I have read many great tutorials
>>>>> regarding RDF and OWL. The focus of those tutorials has largely been
>> how
>>>> to
>>>>> structure the ontology and define restrictions on properties and such.
>>>>> However, I have not been able to find good tutorials that explain how
>>>>> inference is done and how I can define my own inference rules. I'm
>>>>> wondering if I am simply not searching for the right thing.
>>>>>
>>>>> Regardless, here is a significant example that I think will really help
>>>> me
>>>>> get started with inference using Jena. I created a minimal example to
>>>>> enable discussion. Here is a pastebin:  https://pastebin.com/ScTGcbcZ
>>>>>
>>>>> The ontology has two classes, RosterEntry and Person and three data
>>>>> properties, Signature (associated with RosterEntry), and FirstName and
>>>>> LastName (both associated with Person). The example also has two
>>>>> RosterEntry individuals with signatures of "Bob Smith" and "Sally
>> Jones."
>>>>>
>>>>> I would like to write a rule that causes Jena to infer the following
>> new
>>>>> facts:
>>>>>
>>>>> <owl:Individual>
>>>>>>           <rdf:type
>>>>>>               rdf:resource="http://example.com/ont/roster/Person" />
>>>>>>           <hasFirstName>Bob</hasFirstName>
>>>>>           <hasLastName>Smith</hasLastName>
>>>>>
>>>>>       </owl:Individual>
>>>>>
>>>>>
>>>>> <owl:Individual>
>>>>>>           <rdf:type
>>>>>>               rdf:resource="http://example.com/ont/roster/Person" />
>>>>>>           <hasFirstName>Sally</hasFirstName>
>>>>>           <hasLastName>Jones</hasLastName>
>>>>>
>>>>>       </owl:Individual>
>>>>>
>>>>>
>>>>> How do I do that? Full answers or nudges in the right direction are
>> both
>>>>> very welcome. Thank you!
>>>>>
>>>>> Ken
>>>>>
>>>>
>>>>
>>>
>>
> 
> 

Re: Help with inference rules

Posted by Kenneth Keefe <kj...@illinois.edu>.
Thank you! Can you suggest any texts that teach how to effectively write
inference rules for Jena? Also, I have made good progress on the Roster
example, but I'm stuck on the new node URI:

I'm successfully creating a new bNode from my rule now, but I'm having
trouble defining the node's URI.

When I use this rule:

 [r1: (?x rdf:type ro:RosterEntry), (?x ro:hasSignature ?sig), regex(?sig,
> '(.*) (.*)', ?first, ?last), makeSkolem(?y, ?x) -> (?y ro:hasFirstName
> ?first),  (?y ro:hasLastName ?last),  (?y rdf:type ro:Person)]


Jena infers two new nodes like I was hoping for:

1PXx9jabIZ6w9mfO0GygJA== type Person .
> 1PXx9jabIZ6w9mfO0GygJA== hasLastName "Jones" .
> 1PXx9jabIZ6w9mfO0GygJA== hasFirstName "Sally" .
> lOqL7Rx2Lwv5OK6BWD/jSA== type Person .
> lOqL7Rx2Lwv5OK6BWD/jSA== hasLastName "Smith" .
> lOqL7Rx2Lwv5OK6BWD/jSA== hasFirstName "Bob" .


However, I'm not having success changing the node URIs. When I change the
rule to this:

 [r1: (?x rdf:type ro:RosterEntry), (?x ro:hasSignature ?sig), regex(?sig,
> '(.*) (.*)', ?first, ?last), makeSkolem(?y, ?x), uriConcat('
> http://example.com/ont/roster/people/', ?first, ?last, ?y) -> (?y
> ro:hasFirstName ?first),  (?y ro:hasLastName ?last),  (?y rdf:type
> ro:Person)]


Jena doesn't seem to infer any new nodes.

I tried separating it into another rule:

 [r1: (?x rdf:type ro:RosterEntry), (?x ro:hasSignature ?sig), regex(?sig,
> '(.*) (.*)', ?first, ?last), makeSkolem(?y, ?x) -> (?y ro:hasFirstName
> ?first),  (?y ro:hasLastName ?last),  (?y rdf:type ro:Person)]
>  [r2: (?x rdf:type ro:Person), (?x ro:hasFirstName ?first), (?x
> ro:hasLastName ?last), uriConcat('http://example.com/ont/roster/people/',
> ?first, ?last, ?y) -> print('woot', ?y)]


What is strange is that with the second rule, the inference engine prints
out:

'woot' <http://example.com/ont/roster/people/BobSmith>
'woot' <http://example.com/ont/roster/people/SallyJones>

But, when I listStatements and print out the InfModel,

I get the same node URIs:

1PXx9jabIZ6w9mfO0GygJA== type Person .
> 1PXx9jabIZ6w9mfO0GygJA== hasLastName "Jones" .
> 1PXx9jabIZ6w9mfO0GygJA== hasFirstName "Sally" .
> lOqL7Rx2Lwv5OK6BWD/jSA== type Person .
> lOqL7Rx2Lwv5OK6BWD/jSA== hasLastName "Smith" .
> lOqL7Rx2Lwv5OK6BWD/jSA== hasFirstName "Bob" .


So, does uriConcat not set the node's uri permanently?







On Sun, May 24, 2020 at 6:03 AM Dave Reynolds <da...@gmail.com>
wrote:

> Sorry, only just noticed this question. Responses below:
>
> On 20/05/2020 10:41, Kenneth Keefe wrote:
> > Thanks for all the help so far! I've made some good progress on this
> > example I'm trying to forge. Here are the files for this example:
> >
> > Ontology: https://cioi.iti.illinois.edu/ont/examples/roster.owl
> > Rules: https://cioi.iti.illinois.edu/ont/examples/roster.rules
> >
> > Using this code:
> >
> > OntModel model =
> ModelFactory.*createOntologyModel*(OntModelSpec.*OWL_MEM*);
> >
> > model.read("file:roster.owl");
> >
> > List<Rule> rules = Rule.*rulesFromURL*("file:roster.rules");
> >
> > Reasoner reasoner = new GenericRuleReasoner(rules);
> >
> > InfModel inf = ModelFactory.*createInfModel*(reasoner, model);
> >
> >
> > printAllStatements(inf);
> >
> > I get this output (I use the LocalName for the predicates and objects for
> > readability):
> >
> > b04230c7-55dc-4e08-92d7-26559c0c478f hasLastName "Smith" .
> > c33de24f-82f1-4aa2-a78e-73201341b274 type Person .
> > c812ff54-30bf-49e7-8e35-3544dad096b7 hasFirstName "Sally" .
> > 16b7a887-2fb9-4bdb-a529-34ca8b3137e4 hasFirstName "Bob" .
> > b31eb7d5-a8ad-469e-ae83-366bdf46fd72 hasLastName "Jones" .
> > 8b46f0c7-4eb2-41e2-8789-8967e8f63eec type Person .
> > http://example.com/ont/roster/ versionIRI .
> > http://example.com/ont/roster/ type Ontology .
> > http://example.com/ont/roster/RosterEntry type Class .
> > http://example.com/ont/roster/bobEntry hasSignature "Bob Smith" .
> > http://example.com/ont/roster/bobEntry type RosterEntry .
> > http://example.com/ont/roster/bobEntry type NamedIndividual .
> > http://example.com/ont/roster/Person type Class .
> > http://example.com/ont/roster/hasLastName range string .
> > http://example.com/ont/roster/hasLastName domain Person .
> > http://example.com/ont/roster/hasLastName type DatatypeProperty .
> > http://example.com/ont/roster/sallyEntry hasSignature "Sally Jones" .
> > http://example.com/ont/roster/sallyEntry type RosterEntry .
> > http://example.com/ont/roster/sallyEntry type NamedIndividual .
> > http://example.com/ont/roster/hasSignature range string .
> > http://example.com/ont/roster/hasSignature domain RosterEntry .
> > http://example.com/ont/roster/hasSignature type DatatypeProperty .
> > http://example.com/ont/roster/hasFirstName range string .
> > http://example.com/ont/roster/hasFirstName domain Person .
> > http://example.com/ont/roster/hasFirstName type DatatypeProperty .
> >
> > Here are my questions:
> >
> > Focusing on just the Bob Smith entry:
> >
> > b04230c7-55dc-4e08-92d7-26559c0c478f hasLastName "Smith" .
> > c33de24f-82f1-4aa2-a78e-73201341b274 type Person .
> > 16b7a887-2fb9-4bdb-a529-34ca8b3137e4 hasFirstName "Bob" .
> >
> > 1. Are these unique ids of anonymous nodes?
>
> Yes.
>
> > 2. Why are they not identical across these three lines?
>
> Because your ?y variable hasn't been bound in the rule body, each triple
> pattern finds there's no value for ?y and separately treats it as a bNode.
>
> If you want a shared bNode then use makeTemp(?y) in the body (or
> makeSoklem).
>
> > 3. Is there a way to name these new nodes in the rule? For example, make
> > the new node http://example.com/ont/roster/people/BobSmith.
>
> Sure, use uriConcat, something like (untested):
>
>     uriConcat('http://example.com/ont/roster/people/', ?first, ?last,
> ?y) -> ...
>
> Dave
>
> >
> > Thank you!
> >
> > Ken
> >
> >
> >
> >
> >
> > On Tue, May 12, 2020 at 1:44 AM Lorenz Buehmann <
> > buehmann@informatik.uni-leipzig.de> wrote:
> >
> >> Hi,
> >>
> >> I think the rule would be basically
> >>
> >> [r1: (?x rdf:type ex:RosterEntry), (?x ex:hasSignature ?sig),
> >> regex(?sig, '(.*) (.*)', ?first, ?last)  -> (?x ex:hasFirstName
> >> ?first),  (?x ex:hasLastName ?last),  (?x rdf:type ex:Person) ) ]
> >>
> >> Note, it's untested and you have to define your prefix ex: in the rules
> >> file. You might also have to adapt the regex pattern to cover different
> >> white space chars.
> >>
> >> On 12.05.20 00:56, Kenneth Keefe wrote:
> >>> I am pretty new to using Jena and OWL. I have read many great tutorials
> >>> regarding RDF and OWL. The focus of those tutorials has largely been
> how
> >> to
> >>> structure the ontology and define restrictions on properties and such.
> >>> However, I have not been able to find good tutorials that explain how
> >>> inference is done and how I can define my own inference rules. I'm
> >>> wondering if I am simply not searching for the right thing.
> >>>
> >>> Regardless, here is a significant example that I think will really help
> >> me
> >>> get started with inference using Jena. I created a minimal example to
> >>> enable discussion. Here is a pastebin:  https://pastebin.com/ScTGcbcZ
> >>>
> >>> The ontology has two classes, RosterEntry and Person and three data
> >>> properties, Signature (associated with RosterEntry), and FirstName and
> >>> LastName (both associated with Person). The example also has two
> >>> RosterEntry individuals with signatures of "Bob Smith" and "Sally
> Jones."
> >>>
> >>> I would like to write a rule that causes Jena to infer the following
> new
> >>> facts:
> >>>
> >>> <owl:Individual>
> >>>>          <rdf:type
> >>>>              rdf:resource="http://example.com/ont/roster/Person" />
> >>>>          <hasFirstName>Bob</hasFirstName>
> >>>          <hasLastName>Smith</hasLastName>
> >>>
> >>>      </owl:Individual>
> >>>
> >>>
> >>> <owl:Individual>
> >>>>          <rdf:type
> >>>>              rdf:resource="http://example.com/ont/roster/Person" />
> >>>>          <hasFirstName>Sally</hasFirstName>
> >>>          <hasLastName>Jones</hasLastName>
> >>>
> >>>      </owl:Individual>
> >>>
> >>>
> >>> How do I do that? Full answers or nudges in the right direction are
> both
> >>> very welcome. Thank you!
> >>>
> >>> Ken
> >>>
> >>
> >>
> >
>


-- 
-------
Ken Keefe
Senior Software Engineer
Information Trust Institute
University of Illinois at Urbana-Champaign
1308 W. Main St.
CSL 225
Urbana, Illinois 61801, USA
Phone: 217-244-3203
Web: https://www.perform.illinois.edu/~kjkeefe
Email: kjkeefe@illinois.edu

Re: Help with inference rules

Posted by Dave Reynolds <da...@gmail.com>.
Sorry, only just noticed this question. Responses below:

On 20/05/2020 10:41, Kenneth Keefe wrote:
> Thanks for all the help so far! I've made some good progress on this
> example I'm trying to forge. Here are the files for this example:
> 
> Ontology: https://cioi.iti.illinois.edu/ont/examples/roster.owl
> Rules: https://cioi.iti.illinois.edu/ont/examples/roster.rules
> 
> Using this code:
> 
> OntModel model = ModelFactory.*createOntologyModel*(OntModelSpec.*OWL_MEM*);
> 
> model.read("file:roster.owl");
> 
> List<Rule> rules = Rule.*rulesFromURL*("file:roster.rules");
> 
> Reasoner reasoner = new GenericRuleReasoner(rules);
> 
> InfModel inf = ModelFactory.*createInfModel*(reasoner, model);
> 
> 
> printAllStatements(inf);
> 
> I get this output (I use the LocalName for the predicates and objects for
> readability):
> 
> b04230c7-55dc-4e08-92d7-26559c0c478f hasLastName "Smith" .
> c33de24f-82f1-4aa2-a78e-73201341b274 type Person .
> c812ff54-30bf-49e7-8e35-3544dad096b7 hasFirstName "Sally" .
> 16b7a887-2fb9-4bdb-a529-34ca8b3137e4 hasFirstName "Bob" .
> b31eb7d5-a8ad-469e-ae83-366bdf46fd72 hasLastName "Jones" .
> 8b46f0c7-4eb2-41e2-8789-8967e8f63eec type Person .
> http://example.com/ont/roster/ versionIRI .
> http://example.com/ont/roster/ type Ontology .
> http://example.com/ont/roster/RosterEntry type Class .
> http://example.com/ont/roster/bobEntry hasSignature "Bob Smith" .
> http://example.com/ont/roster/bobEntry type RosterEntry .
> http://example.com/ont/roster/bobEntry type NamedIndividual .
> http://example.com/ont/roster/Person type Class .
> http://example.com/ont/roster/hasLastName range string .
> http://example.com/ont/roster/hasLastName domain Person .
> http://example.com/ont/roster/hasLastName type DatatypeProperty .
> http://example.com/ont/roster/sallyEntry hasSignature "Sally Jones" .
> http://example.com/ont/roster/sallyEntry type RosterEntry .
> http://example.com/ont/roster/sallyEntry type NamedIndividual .
> http://example.com/ont/roster/hasSignature range string .
> http://example.com/ont/roster/hasSignature domain RosterEntry .
> http://example.com/ont/roster/hasSignature type DatatypeProperty .
> http://example.com/ont/roster/hasFirstName range string .
> http://example.com/ont/roster/hasFirstName domain Person .
> http://example.com/ont/roster/hasFirstName type DatatypeProperty .
> 
> Here are my questions:
> 
> Focusing on just the Bob Smith entry:
> 
> b04230c7-55dc-4e08-92d7-26559c0c478f hasLastName "Smith" .
> c33de24f-82f1-4aa2-a78e-73201341b274 type Person .
> 16b7a887-2fb9-4bdb-a529-34ca8b3137e4 hasFirstName "Bob" .
> 
> 1. Are these unique ids of anonymous nodes?

Yes.

> 2. Why are they not identical across these three lines?

Because your ?y variable hasn't been bound in the rule body, each triple 
pattern finds there's no value for ?y and separately treats it as a bNode.

If you want a shared bNode then use makeTemp(?y) in the body (or 
makeSoklem).

> 3. Is there a way to name these new nodes in the rule? For example, make
> the new node http://example.com/ont/roster/people/BobSmith.

Sure, use uriConcat, something like (untested):

    uriConcat('http://example.com/ont/roster/people/', ?first, ?last, 
?y) -> ...

Dave

> 
> Thank you!
> 
> Ken
> 
> 
> 
> 
> 
> On Tue, May 12, 2020 at 1:44 AM Lorenz Buehmann <
> buehmann@informatik.uni-leipzig.de> wrote:
> 
>> Hi,
>>
>> I think the rule would be basically
>>
>> [r1: (?x rdf:type ex:RosterEntry), (?x ex:hasSignature ?sig),
>> regex(?sig, '(.*) (.*)', ?first, ?last)  -> (?x ex:hasFirstName
>> ?first),  (?x ex:hasLastName ?last),  (?x rdf:type ex:Person) ) ]
>>
>> Note, it's untested and you have to define your prefix ex: in the rules
>> file. You might also have to adapt the regex pattern to cover different
>> white space chars.
>>
>> On 12.05.20 00:56, Kenneth Keefe wrote:
>>> I am pretty new to using Jena and OWL. I have read many great tutorials
>>> regarding RDF and OWL. The focus of those tutorials has largely been how
>> to
>>> structure the ontology and define restrictions on properties and such.
>>> However, I have not been able to find good tutorials that explain how
>>> inference is done and how I can define my own inference rules. I'm
>>> wondering if I am simply not searching for the right thing.
>>>
>>> Regardless, here is a significant example that I think will really help
>> me
>>> get started with inference using Jena. I created a minimal example to
>>> enable discussion. Here is a pastebin:  https://pastebin.com/ScTGcbcZ
>>>
>>> The ontology has two classes, RosterEntry and Person and three data
>>> properties, Signature (associated with RosterEntry), and FirstName and
>>> LastName (both associated with Person). The example also has two
>>> RosterEntry individuals with signatures of "Bob Smith" and "Sally Jones."
>>>
>>> I would like to write a rule that causes Jena to infer the following new
>>> facts:
>>>
>>> <owl:Individual>
>>>>          <rdf:type
>>>>              rdf:resource="http://example.com/ont/roster/Person" />
>>>>          <hasFirstName>Bob</hasFirstName>
>>>          <hasLastName>Smith</hasLastName>
>>>
>>>      </owl:Individual>
>>>
>>>
>>> <owl:Individual>
>>>>          <rdf:type
>>>>              rdf:resource="http://example.com/ont/roster/Person" />
>>>>          <hasFirstName>Sally</hasFirstName>
>>>          <hasLastName>Jones</hasLastName>
>>>
>>>      </owl:Individual>
>>>
>>>
>>> How do I do that? Full answers or nudges in the right direction are both
>>> very welcome. Thank you!
>>>
>>> Ken
>>>
>>
>>
> 

Re: Help with inference rules

Posted by Kenneth Keefe <kj...@illinois.edu>.
Thanks for all the help so far! I've made some good progress on this
example I'm trying to forge. Here are the files for this example:

Ontology: https://cioi.iti.illinois.edu/ont/examples/roster.owl
Rules: https://cioi.iti.illinois.edu/ont/examples/roster.rules

Using this code:

OntModel model = ModelFactory.*createOntologyModel*(OntModelSpec.*OWL_MEM*);

model.read("file:roster.owl");

List<Rule> rules = Rule.*rulesFromURL*("file:roster.rules");

Reasoner reasoner = new GenericRuleReasoner(rules);

InfModel inf = ModelFactory.*createInfModel*(reasoner, model);


printAllStatements(inf);

I get this output (I use the LocalName for the predicates and objects for
readability):

b04230c7-55dc-4e08-92d7-26559c0c478f hasLastName "Smith" .
c33de24f-82f1-4aa2-a78e-73201341b274 type Person .
c812ff54-30bf-49e7-8e35-3544dad096b7 hasFirstName "Sally" .
16b7a887-2fb9-4bdb-a529-34ca8b3137e4 hasFirstName "Bob" .
b31eb7d5-a8ad-469e-ae83-366bdf46fd72 hasLastName "Jones" .
8b46f0c7-4eb2-41e2-8789-8967e8f63eec type Person .
http://example.com/ont/roster/ versionIRI .
http://example.com/ont/roster/ type Ontology .
http://example.com/ont/roster/RosterEntry type Class .
http://example.com/ont/roster/bobEntry hasSignature "Bob Smith" .
http://example.com/ont/roster/bobEntry type RosterEntry .
http://example.com/ont/roster/bobEntry type NamedIndividual .
http://example.com/ont/roster/Person type Class .
http://example.com/ont/roster/hasLastName range string .
http://example.com/ont/roster/hasLastName domain Person .
http://example.com/ont/roster/hasLastName type DatatypeProperty .
http://example.com/ont/roster/sallyEntry hasSignature "Sally Jones" .
http://example.com/ont/roster/sallyEntry type RosterEntry .
http://example.com/ont/roster/sallyEntry type NamedIndividual .
http://example.com/ont/roster/hasSignature range string .
http://example.com/ont/roster/hasSignature domain RosterEntry .
http://example.com/ont/roster/hasSignature type DatatypeProperty .
http://example.com/ont/roster/hasFirstName range string .
http://example.com/ont/roster/hasFirstName domain Person .
http://example.com/ont/roster/hasFirstName type DatatypeProperty .

Here are my questions:

Focusing on just the Bob Smith entry:

b04230c7-55dc-4e08-92d7-26559c0c478f hasLastName "Smith" .
c33de24f-82f1-4aa2-a78e-73201341b274 type Person .
16b7a887-2fb9-4bdb-a529-34ca8b3137e4 hasFirstName "Bob" .

1. Are these unique ids of anonymous nodes?

2. Why are they not identical across these three lines?

3. Is there a way to name these new nodes in the rule? For example, make
the new node http://example.com/ont/roster/people/BobSmith.

Thank you!

Ken





On Tue, May 12, 2020 at 1:44 AM Lorenz Buehmann <
buehmann@informatik.uni-leipzig.de> wrote:

> Hi,
>
> I think the rule would be basically
>
> [r1: (?x rdf:type ex:RosterEntry), (?x ex:hasSignature ?sig),
> regex(?sig, '(.*) (.*)', ?first, ?last)  -> (?x ex:hasFirstName
> ?first),  (?x ex:hasLastName ?last),  (?x rdf:type ex:Person) ) ]
>
> Note, it's untested and you have to define your prefix ex: in the rules
> file. You might also have to adapt the regex pattern to cover different
> white space chars.
>
> On 12.05.20 00:56, Kenneth Keefe wrote:
> > I am pretty new to using Jena and OWL. I have read many great tutorials
> > regarding RDF and OWL. The focus of those tutorials has largely been how
> to
> > structure the ontology and define restrictions on properties and such.
> > However, I have not been able to find good tutorials that explain how
> > inference is done and how I can define my own inference rules. I'm
> > wondering if I am simply not searching for the right thing.
> >
> > Regardless, here is a significant example that I think will really help
> me
> > get started with inference using Jena. I created a minimal example to
> > enable discussion. Here is a pastebin:  https://pastebin.com/ScTGcbcZ
> >
> > The ontology has two classes, RosterEntry and Person and three data
> > properties, Signature (associated with RosterEntry), and FirstName and
> > LastName (both associated with Person). The example also has two
> > RosterEntry individuals with signatures of "Bob Smith" and "Sally Jones."
> >
> > I would like to write a rule that causes Jena to infer the following new
> > facts:
> >
> > <owl:Individual>
> >>         <rdf:type
> >>             rdf:resource="http://example.com/ont/roster/Person" />
> >>         <hasFirstName>Bob</hasFirstName>
> >         <hasLastName>Smith</hasLastName>
> >
> >     </owl:Individual>
> >
> >
> > <owl:Individual>
> >>         <rdf:type
> >>             rdf:resource="http://example.com/ont/roster/Person" />
> >>         <hasFirstName>Sally</hasFirstName>
> >         <hasLastName>Jones</hasLastName>
> >
> >     </owl:Individual>
> >
> >
> > How do I do that? Full answers or nudges in the right direction are both
> > very welcome. Thank you!
> >
> > Ken
> >
>
>

-- 
-------
Ken Keefe
Senior Software Engineer
Information Trust Institute
University of Illinois at Urbana-Champaign
1308 W. Main St.
CSL 225
Urbana, Illinois 61801, USA
Phone: 217-244-3203
Web: https://www.perform.illinois.edu/~kjkeefe
Email: kjkeefe@illinois.edu

Re: Help with inference rules

Posted by Silvio Domingos <si...@gmail.com>.
Dear Ken,

I hope this example helps you:

String rules = "[rule1: (?a eg:p ?b) (?b eg:p ?c) -&gt; (?a eg:p ?c)]";
Reasoner reasoner = new GenericRuleReasoner(Rule.parseRules(rules));
reasoner.setDerivationLogging(true);
InfModel inf = ModelFactory.createInfModel(reasoner, rawData);

You can check more here: https://jena.apache.org/documentation/inference/index.html

On 2020/05/13 01:28:29, Kenneth Keefe <kj...@illinois.edu> wrote: 
> When you are working on rules like this with Jena, what tools do you use to
> test? Is there an IDE for interfacing with Jena and building ontologies?
> 
> Thanks,
> Ken
> 
> On Tue, May 12, 2020 at 1:44 AM Lorenz Buehmann <
> buehmann@informatik.uni-leipzig.de> wrote:
> 
> > Hi,
> >
> > I think the rule would be basically
> >
> > [r1: (?x rdf:type ex:RosterEntry), (?x ex:hasSignature ?sig),
> > regex(?sig, '(.*) (.*)', ?first, ?last)  -> (?x ex:hasFirstName
> > ?first),  (?x ex:hasLastName ?last),  (?x rdf:type ex:Person) ) ]
> >
> > Note, it's untested and you have to define your prefix ex: in the rules
> > file. You might also have to adapt the regex pattern to cover different
> > white space chars.
> >
> > On 12.05.20 00:56, Kenneth Keefe wrote:
> > > I am pretty new to using Jena and OWL. I have read many great tutorials
> > > regarding RDF and OWL. The focus of those tutorials has largely been how
> > to
> > > structure the ontology and define restrictions on properties and such.
> > > However, I have not been able to find good tutorials that explain how
> > > inference is done and how I can define my own inference rules. I'm
> > > wondering if I am simply not searching for the right thing.
> > >
> > > Regardless, here is a significant example that I think will really help
> > me
> > > get started with inference using Jena. I created a minimal example to
> > > enable discussion. Here is a pastebin:  https://pastebin.com/ScTGcbcZ
> > >
> > > The ontology has two classes, RosterEntry and Person and three data
> > > properties, Signature (associated with RosterEntry), and FirstName and
> > > LastName (both associated with Person). The example also has two
> > > RosterEntry individuals with signatures of "Bob Smith" and "Sally Jones."
> > >
> > > I would like to write a rule that causes Jena to infer the following new
> > > facts:
> > >
> > > <owl:Individual>
> > >>         <rdf:type
> > >>             rdf:resource="http://example.com/ont/roster/Person" />
> > >>         <hasFirstName>Bob</hasFirstName>
> > >         <hasLastName>Smith</hasLastName>
> > >
> > >     </owl:Individual>
> > >
> > >
> > > <owl:Individual>
> > >>         <rdf:type
> > >>             rdf:resource="http://example.com/ont/roster/Person" />
> > >>         <hasFirstName>Sally</hasFirstName>
> > >         <hasLastName>Jones</hasLastName>
> > >
> > >     </owl:Individual>
> > >
> > >
> > > How do I do that? Full answers or nudges in the right direction are both
> > > very welcome. Thank you!
> > >
> > > Ken
> > >
> >
> >
> 
> -- 
> -------
> Ken Keefe
> Senior Software Engineer
> Information Trust Institute
> University of Illinois at Urbana-Champaign
> 1308 W. Main St.
> CSL 225
> Urbana, Illinois 61801, USA
> Phone: 217-244-3203
> Web: https://www.perform.illinois.edu/~kjkeefe
> Email: kjkeefe@illinois.edu
> 

Re: Help with inference rules

Posted by Kenneth Keefe <kj...@illinois.edu>.
When you are working on rules like this with Jena, what tools do you use to
test? Is there an IDE for interfacing with Jena and building ontologies?

Thanks,
Ken

On Tue, May 12, 2020 at 1:44 AM Lorenz Buehmann <
buehmann@informatik.uni-leipzig.de> wrote:

> Hi,
>
> I think the rule would be basically
>
> [r1: (?x rdf:type ex:RosterEntry), (?x ex:hasSignature ?sig),
> regex(?sig, '(.*) (.*)', ?first, ?last)  -> (?x ex:hasFirstName
> ?first),  (?x ex:hasLastName ?last),  (?x rdf:type ex:Person) ) ]
>
> Note, it's untested and you have to define your prefix ex: in the rules
> file. You might also have to adapt the regex pattern to cover different
> white space chars.
>
> On 12.05.20 00:56, Kenneth Keefe wrote:
> > I am pretty new to using Jena and OWL. I have read many great tutorials
> > regarding RDF and OWL. The focus of those tutorials has largely been how
> to
> > structure the ontology and define restrictions on properties and such.
> > However, I have not been able to find good tutorials that explain how
> > inference is done and how I can define my own inference rules. I'm
> > wondering if I am simply not searching for the right thing.
> >
> > Regardless, here is a significant example that I think will really help
> me
> > get started with inference using Jena. I created a minimal example to
> > enable discussion. Here is a pastebin:  https://pastebin.com/ScTGcbcZ
> >
> > The ontology has two classes, RosterEntry and Person and three data
> > properties, Signature (associated with RosterEntry), and FirstName and
> > LastName (both associated with Person). The example also has two
> > RosterEntry individuals with signatures of "Bob Smith" and "Sally Jones."
> >
> > I would like to write a rule that causes Jena to infer the following new
> > facts:
> >
> > <owl:Individual>
> >>         <rdf:type
> >>             rdf:resource="http://example.com/ont/roster/Person" />
> >>         <hasFirstName>Bob</hasFirstName>
> >         <hasLastName>Smith</hasLastName>
> >
> >     </owl:Individual>
> >
> >
> > <owl:Individual>
> >>         <rdf:type
> >>             rdf:resource="http://example.com/ont/roster/Person" />
> >>         <hasFirstName>Sally</hasFirstName>
> >         <hasLastName>Jones</hasLastName>
> >
> >     </owl:Individual>
> >
> >
> > How do I do that? Full answers or nudges in the right direction are both
> > very welcome. Thank you!
> >
> > Ken
> >
>
>

-- 
-------
Ken Keefe
Senior Software Engineer
Information Trust Institute
University of Illinois at Urbana-Champaign
1308 W. Main St.
CSL 225
Urbana, Illinois 61801, USA
Phone: 217-244-3203
Web: https://www.perform.illinois.edu/~kjkeefe
Email: kjkeefe@illinois.edu

Re: Help with inference rules

Posted by Kenneth Keefe <kj...@illinois.edu>.
This is exactly what I'm trying to do. What language is that rule specified
in? How can I utilize it in Jena?

Thanks!

Ken

On Tue, May 12, 2020 at 1:44 AM Lorenz Buehmann <
buehmann@informatik.uni-leipzig.de> wrote:

> Hi,
>
> I think the rule would be basically
>
> [r1: (?x rdf:type ex:RosterEntry), (?x ex:hasSignature ?sig),
> regex(?sig, '(.*) (.*)', ?first, ?last)  -> (?x ex:hasFirstName
> ?first),  (?x ex:hasLastName ?last),  (?x rdf:type ex:Person) ) ]
>
> Note, it's untested and you have to define your prefix ex: in the rules
> file. You might also have to adapt the regex pattern to cover different
> white space chars.
>
> On 12.05.20 00:56, Kenneth Keefe wrote:
> > I am pretty new to using Jena and OWL. I have read many great tutorials
> > regarding RDF and OWL. The focus of those tutorials has largely been how
> to
> > structure the ontology and define restrictions on properties and such.
> > However, I have not been able to find good tutorials that explain how
> > inference is done and how I can define my own inference rules. I'm
> > wondering if I am simply not searching for the right thing.
> >
> > Regardless, here is a significant example that I think will really help
> me
> > get started with inference using Jena. I created a minimal example to
> > enable discussion. Here is a pastebin:  https://pastebin.com/ScTGcbcZ
> >
> > The ontology has two classes, RosterEntry and Person and three data
> > properties, Signature (associated with RosterEntry), and FirstName and
> > LastName (both associated with Person). The example also has two
> > RosterEntry individuals with signatures of "Bob Smith" and "Sally Jones."
> >
> > I would like to write a rule that causes Jena to infer the following new
> > facts:
> >
> > <owl:Individual>
> >>         <rdf:type
> >>             rdf:resource="http://example.com/ont/roster/Person" />
> >>         <hasFirstName>Bob</hasFirstName>
> >         <hasLastName>Smith</hasLastName>
> >
> >     </owl:Individual>
> >
> >
> > <owl:Individual>
> >>         <rdf:type
> >>             rdf:resource="http://example.com/ont/roster/Person" />
> >>         <hasFirstName>Sally</hasFirstName>
> >         <hasLastName>Jones</hasLastName>
> >
> >     </owl:Individual>
> >
> >
> > How do I do that? Full answers or nudges in the right direction are both
> > very welcome. Thank you!
> >
> > Ken
> >
>
>

-- 
-------
Ken Keefe
Senior Software Engineer
Information Trust Institute
University of Illinois at Urbana-Champaign
1308 W. Main St.
CSL 225
Urbana, Illinois 61801, USA
Phone: 217-244-3203
Web: https://www.perform.illinois.edu/~kjkeefe
Email: kjkeefe@illinois.edu

Re: Help with inference rules

Posted by Lorenz Buehmann <bu...@informatik.uni-leipzig.de>.
Hi,

I think the rule would be basically

[r1: (?x rdf:type ex:RosterEntry), (?x ex:hasSignature ?sig),
regex(?sig, '(.*) (.*)', ?first, ?last)  -> (?x ex:hasFirstName
?first),  (?x ex:hasLastName ?last),  (?x rdf:type ex:Person) ) ]

Note, it's untested and you have to define your prefix ex: in the rules
file. You might also have to adapt the regex pattern to cover different
white space chars.

On 12.05.20 00:56, Kenneth Keefe wrote:
> I am pretty new to using Jena and OWL. I have read many great tutorials
> regarding RDF and OWL. The focus of those tutorials has largely been how to
> structure the ontology and define restrictions on properties and such.
> However, I have not been able to find good tutorials that explain how
> inference is done and how I can define my own inference rules. I'm
> wondering if I am simply not searching for the right thing.
>
> Regardless, here is a significant example that I think will really help me
> get started with inference using Jena. I created a minimal example to
> enable discussion. Here is a pastebin:  https://pastebin.com/ScTGcbcZ
>
> The ontology has two classes, RosterEntry and Person and three data
> properties, Signature (associated with RosterEntry), and FirstName and
> LastName (both associated with Person). The example also has two
> RosterEntry individuals with signatures of "Bob Smith" and "Sally Jones."
>
> I would like to write a rule that causes Jena to infer the following new
> facts:
>
> <owl:Individual>
>>         <rdf:type
>>             rdf:resource="http://example.com/ont/roster/Person" />
>>         <hasFirstName>Bob</hasFirstName>
>         <hasLastName>Smith</hasLastName>
>
>     </owl:Individual>
>
>
> <owl:Individual>
>>         <rdf:type
>>             rdf:resource="http://example.com/ont/roster/Person" />
>>         <hasFirstName>Sally</hasFirstName>
>         <hasLastName>Jones</hasLastName>
>
>     </owl:Individual>
>
>
> How do I do that? Full answers or nudges in the right direction are both
> very welcome. Thank you!
>
> Ken
>