I have an API that receive a JSON document with classes, properties and axioms of an ontology. The file looks like this:
{
"id": "https://onto4alleditor.com/pt/idDoProjeto",
"filetype": "OWL",
"classes": [{
"Name": "Homem",
"SubClassOf": ["Pessoa"],
"DisjointWith": ["Mulher"],
"Annotation": [{"Annotation":"Homo sapiens do sexo masculino.", "Language":"pt"},
{"Annotation": "Male homo sapiens.", "Language": "en"}]
},
{
"Name": "Mulher",
"Constraint": ["Mulher EquivalentTo: (NOT Homem)"],
"SubClassOf": ["Pessoa"]
}
]
}
The variable Constraint is an expression obtained from the Expression Editor of the Protegé. I'm trying to to add this expression to my OWLOntology object, but I'm receiving the following error:
Encountered Mulher at line 1 column 1. Expected one of:
Class name
Object property name
Data property name
inv
Functional
inverse
InverseFunctional
(
Asymmetric
Transitive
Irreflexive
{
Symmetric
Reflexive
Mulher is a class of my ontology, thus the error doesn't make sense. I'm not sure why this is happening, as I believe my code is initializing the parser properly (I'm using the Manchester Parser to do the job).Here follows my code:
private void loadClassConstraints(JSONArray constraints){
ManchesterOWLSyntaxParser parser = OWLManager.createManchesterParser();
parser.setDefaultOntology(this.ont);
for (int i = 0; i < constraints.length(); i++) {
parser.setStringToParse(constraints.getString(i));
this.ont.add(parser.parseAxiom());
}
}
What is going wrong? I couldn't find enough documentation on the internet which applies to my problem.Thanks in advance for any help.
The issue here is that parsing the axiom relies on an OWLEntityChecker implementation to convert strings to class or property expressions, in this case Mulher
to the entity as declared in your ontology, e.g., urn:test:Mulher
.
There is an example on how to configure this in the OWLAPI tracker: https://github.com/owlcs/owlapi/issues/507
Protege uses a similar mechanism but it has its own OWLEntityChecker implementations, which wouldn't be available to you if you're only using OWLAPI.
The example below uses a naive implementation of OWLEntityChecker which will use the fragment of the IRIs for all entities in the ontology to identify the entities; this is limited, because in real ontologies the IRI fragments can easily clash or be missing. However it might help, if the example on the bug tracker isn't good enough.
OWLOntologyManager m = OWLManager.createOWLOntologyManager();
OWLDataFactory df = m.getOWLDataFactory();
OWLOntology ont = m.createOntology(IRI.create("urn:test:test"));
ont.add(df.getOWLDeclarationAxiom(df.getOWLClass("urn:test:Mulher")));
ont.add(df.getOWLDeclarationAxiom(df.getOWLClass("urn:test:Homem")));
ManchesterOWLSyntaxParser parser = OWLManager.createManchesterParser();
parser.setDefaultOntology(ont);
final Map<String, OWLEntity> map = new HashMap<>();
ont.signature().forEach(x -> map.put(x.getIRI().getFragment(), x));
parser.setOWLEntityChecker(new OWLEntityChecker() {
private <T> T v(String name, Class<T> t) {
OWLEntity e = map.get(name);
if (t.isInstance(e)) {
return t.cast(e);
}
return null;
}
@Override
public OWLObjectProperty getOWLObjectProperty(String name) {
return v(name, OWLObjectProperty.class);
}
@Override
public OWLNamedIndividual getOWLIndividual(String name) {
return v(name, OWLNamedIndividual.class);
}
@Override
public OWLDatatype getOWLDatatype(String name) {
return v(name, OWLDatatype.class);
}
@Override
public OWLDataProperty getOWLDataProperty(String name) {
return v(name, OWLDataProperty.class);
}
@Override
public OWLClass getOWLClass(String name) {
return v(name, OWLClass.class);
}
@Override
public OWLAnnotationProperty getOWLAnnotationProperty(String name) {
return v(name, OWLAnnotationProperty.class);
}
});
parser.setStringToParse("Mulher EquivalentTo: (NOT Homem)");
OWLAxiom parseAxiom = parser.parseAxiom();
System.out.println("of.main() " + parseAxiom);
ont.add(parseAxiom);