In your example code you have an OntModel which is specified to include a reasoner using the default OWL rules. You then have an InfModel on top of that with your own rule. So the OWL rules are generating entailments from the domain declarations for born_in which are then visible through your enclosing rule InfModel.

I'm not sure exactly want you want to achieve ...

If you want an OntModel interface but with just your rule(s) then one easy way is to generate your own OntModelSpec based off OWL_MEM and attach your reasoner to it using setReasoner, then use that to create your OntModel. Don't bother with a separate InfModel. That way you just have one layer of model and avoid any confusion from nesting models.

If you just want a plaing InfModel interface with just your rules then you can create the InfModel as you are doing over either a plain Model or over an OntModel with no second reasoning layer.

If you want OWL inference and then want to run your own rules on top of that then the setup you have is one way to do that.

Comments inline below ...

On 20/01/2020 10:06, Luis Enrique Ramos García wrote:
Dear friends of jena community,


I am testing the syntax of apache jena rules, with a very simple example,
where I create the following model and  classes:


   OntModel m = ModelFactory.createOntologyModel();

OntClass c0 = m.createClass( NS + "c0" );
OntClass c1 = m.createClass( NS + "c1" );
OntClass c2 = m.createClass( NS + "c2" );

and the following individuals as members of the its respective classes:

//creation of individual

Individual i0 = m.createIndividual( NS + "individual0", c0 );
Individual i1 = m.createIndividual( NS + "individual1", c1 );

  when I run the rule, that says:

if individual* i? *is member of c0, then has to be member of *c2*

String *ruleSrc* = "[rule1: (?a
http://www.w3.org/1999/02/22-rdf-syntax-ns#type www.example.com#c0) -> "
+ "(?a http://www.w3.org/1999/02/22-rdf-syntax-ns#type www.example.com#c2)
]";

More readable if you use the builtin prefixes like rdf:type

Also www.example.com# is a (scheme-) relative URL, not that it matters in this case but better to get used to using absolute URLs including the http:// bit.


the rule is triggered as expected and give me the following result:

  [www.example.com#individual0,
http://www.w3.org/1999/02/22-rdf-syntax-ns#type, www.example.com#c2]>

Nevertheless, when I add more information to the model, and say that
individuals i0 and i1 have birthday:

i0.addProperty(born_in, date1.toString());
i1.addProperty(born_in, date2.toString());

The behavior of rule output changed, and I obtain a different result:
<ModelCom  org.apache.jena.reasoner.rulesys.impl [
www.example.com#individual1, http://www.w3.org/1999/02/22-rdf-syntax-ns#type,
www.example.com#c2] [www.example.com#individual0,
http://www.w3.org/1999/02/22-rdf-syntax-ns#type, www.example.com#c2]>

Where individual 1 is declared as member of c2, it means that individual1
is member of c0, something that I did not declared.

You did but indirectly. You declared that the domain of born_in includes c0 and c1. So the with-OWL-inference OntModel will deduce, among other things:

   :i0 rdf:type  :c0

Then your own rule, runing in the InfModel, sees that and since it states that anything of type c0 is also of type c2 it deduces that:

   :i0 rdf:type  :c2


I changed model declaration as follows:

   OntModel m = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);

and obtained the expected result, however the documentation says there is
not reasoning there,

Correct. That way the OntModel itself is not doing any reasoning, so the only reasoning you see out of your InfModel is from your own rule set and nothing more. Just one reasoner in play.

thus I implemented a reasoner model and obtained an
unexpected result again.

Don't follow what you did but it shoulds no different from what you show below with two layers of inference one on top of the other.

My main concern is that when I inspect the *asserted model , *I see it
contains individual 1 declared as part of c0, something that, according to
my understanding should not occur, because I have not declared that.

The based model you are giving to the InfModel is the OntModel *with OWL inference* (by virtue of the OWL_DL_MEM_RULE_INF spec). It is not an "asserted model".

In general avoid having lots of layers of different models with multiple reasoners runing other the top of each other unless that is absolutely what you need.

Dave


Any comment and recommendation is welcomed.

Bellow is the whole java code.


Luis Ramos


****************************************CODE
**********************************************

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.apache.jena.ontology.DatatypeProperty;
import org.apache.jena.ontology.Individual;
import org.apache.jena.ontology.OntClass;
import org.apache.jena.ontology.OntModel;
import org.apache.jena.ontology.OntModelSpec;
import org.apache.jena.rdf.model.InfModel;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.reasoner.Reasoner;
import org.apache.jena.reasoner.rulesys.GenericRuleReasoner;
import org.apache.jena.reasoner.rulesys.Rule;
import org.apache.jena.vocabulary.XSD;

public class OntGenRule {

public static void main(String[] args) throws ParseException {

String URL = "www.example.com";
String NS = URL+"#";
String rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns";;


String rdf_ns = rdf+"#";

//creation of the model

OntModel m = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);

//addition of classes

OntClass c0 = m.createClass( NS + "c0" );
OntClass c1 = m.createClass( NS + "c1" );
OntClass c2 = m.createClass( NS + "c2" );

//creation of individual

Individual i0 = m.createIndividual( NS + "individual0", c0 );

Individual i1 = m.createIndividual( NS + "individual1", c1 );



//date property

DatatypeProperty born_in = m.createDatatypeProperty( NS + "birthday" );
born_in.addDomain( m.getOntClass( NS + "c0" ) );
born_in.addDomain( m.getOntClass( NS + "c1" ) );

born_in.addRange( XSD.dateTime );

//create a date

SimpleDateFormat sdf = new SimpleDateFormat("dd-M-yyyy
hh:mm:ss");//-uncomment for test
String date1toString = "31-08-1982 10:20:56";//-uncomment for test
String date2toString = "12-02-1977 10:20:56";//-uncomment for test


Date date1 = sdf.parse(date1toString);//-uncomment for test

Date date2 = sdf.parse(date2toString);//-uncomment for test

//addition of date to individuals

i0.addProperty(born_in, date1.toString());//-uncomment for test

i1.addProperty(born_in, date2.toString());//-uncomment for test


//System.out.println(p0.getProperty(born_in).getObject());

//System.out.println(p1.getProperty(born_in).getObject());

OntModel testModel =
ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM_RULE_INF,
m);//onto model, to hold ontology


String ruleSrc = "[rule1: (?a
http://www.w3.org/1999/02/22-rdf-syntax-ns#type www.example.com#c0) -> "
+ "(?a http://www.w3.org/1999/02/22-rdf-syntax-ns#type www.example.com#c2)
]";

List rules = Rule.parseRules(ruleSrc);

Reasoner reasoner = new GenericRuleReasoner(rules);

InfModel inf = ModelFactory.createInfModel(reasoner, testModel);

Model deducedM = ModelFactory.createOntologyModel();

deducedM = inf.getDeductionsModel();

System.out.println(testModel);

System.out.println(deducedM);


}

}

Reply via email to