Как найти группы логически эквивалентных понятий с помощью Pellet?

На самом деле, я создаю онтологию, определенную на языке OWL2, используя Java-программу с OWL API. Я интегрирую необходимую банку в свой проект, чтобы использовать механизм вывода Pellet. Мой вопрос заключается в том, как я обнаруживаю в своей онтологии группы понятий, которые логически эквивалентны? вот код, который я использую Pellet.

 import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.io.StreamDocumentTarget;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyChange;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.model.OWLOntologyStorageException;
import com.clarkparsia.pellet.owlapiv3.PelletReasoner;
import com.clarkparsia.pellet.owlapiv3.PelletReasonerFactory;
import org.mindswap.pellet.KnowledgeBase;







/**
 *
 * @author hela
 */
public class Owl {

  public  void createNewOnto(List<String[][]> cps, LinkedList<Map<String, String>> rel, String uri ) throws OWLOntologyCreationException,
        OWLOntologyStorageException {
     OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
        OWLDataFactory factory = manager.getOWLDataFactory();
        IRI iri = IRI.create("http://www.co-ode.org/ontologies/Annot2Onto.owl");
        OWLOntology ontology = manager.createOntology(iri); 

OWLObjectProperty subTopicOf =factory.getOWLObjectProperty(IRI.create(iri+"/#sub-topicOf"));
OWLObjectProperty kindOf =factory.getOWLObjectProperty(IRI.create(iri+"/#kindOf"));
OWLClass thing = factory.getOWLClass(IRI.create(iri+"/#OWLThing"));
  manager.addAxiom(ontology, factory.getOWLDeclarationAxiom(thing));
 Set<OWLAxiom> genders = new HashSet<OWLAxiom>();
 for(Map<String, String> rmp : rel){
     Set<OWLNamedIndividual> classes =ontology.getIndividualsInSignature();
  List< OWLNamedIndividual> listc = new ArrayList(classes);
   IRI ir = IRI.create(iri+"/#"+rmp.get("concept1"));
    OWLNamedIndividual c1=null;

 if(ontology.containsClassInSignature(ir)){
     int i=0;

     while(i<listc.size()&& c1==null){
         if(listc.get(i).toString().compareTo("<"+ir.toString()+">")==0){
             c1=listc.get(i);

              manager.addAxiom(ontology, factory.getOWLDeclarationAxiom(c1));
             manager.addAxiom(ontology, factory.getOWLClassAssertionAxiom(thing, c1));
         }


         i++;
     }
 }

 else {
      c1 = factory.getOWLNamedIndividual(IRI.create(iri+"/#"+rmp.get("concept1")));

        //manager.addAxiom(ontology, factory.getOWLDeclarationAxiom(c1));
        manager.addAxiom(ontology, factory.getOWLClassAssertionAxiom(thing, c1));
 }

 IRI ir2 = IRI.create(iri+"/#"+rmp.get("concept2"));
    OWLNamedIndividual c2=null;
 if(ontology.containsIndividualInSignature(ir2)){
     int i=0;

     while(i<listc.size()&& c2==null){

         if(listc.get(i).toString().compareTo("<"+ir2.toString()+">")==0){
             c2=listc.get(i);
              System.out.println("concept2 = "+c2.toString());
             manager.addAxiom(ontology, factory.getOWLDeclarationAxiom(c2));
               manager.addAxiom(ontology, factory.getOWLClassAssertionAxiom(thing, c2));
         }
         i++;
     }
 }

 else{ 
      c2 = factory.getOWLNamedIndividual(IRI.create(iri+"/#"+rmp.get("concept2")));

       //manager.addAxiom(ontology, factory.getOWLDeclarationAxiom(c2));
        manager.addAxiom(ontology, factory.getOWLClassAssertionAxiom(thing, c2));
 }

if(rmp.get("relation").compareTo("kind of")==0){
//domainAxiom = factory.getOWLObjectPropertyDomainAxiom(sorteDe,c1);
//rangeAxiom = factory.getOWLObjectPropertyRangeAxiom(sorteDe,c2);

genders.add(factory.getOWLObjectPropertyAssertionAxiom(kindOf, c1,
                c2));
}

else{

  genders.add(factory.getOWLObjectPropertyAssertionAxiom(subTopicOf, c1,c2));


}

    String[][] cp1 = this.getConcept(cps,rmp.get("concept1"));
    String[][] cp2 = this.getConcept(cps,rmp.get("concept2") );
    cps.remove(cp2);
    cps.remove(cp1);
    // Now we apply the change using the manager.
    //manager.applyChange(addAxiom1);
 }
    List<OWLOntologyChange> la=manager.addAxioms(ontology, genders);
    manager.applyChanges(la);

for(String[][] ct: cps){
    OWLNamedIndividual res=factory.getOWLNamedIndividual(IRI.create(iri+"/#"+ct[0][0]));
       manager.addAxiom(ontology, factory.getOWLDeclarationAxiom(res));
      manager.addAxiom(ontology, factory.getOWLClassAssertionAxiom(thing, res));

}

File file = new File(uri+"/Annot2Onto.owl");
PelletReasoner reasoner = PelletReasonerFactory.getInstance().createNonBufferingReasoner( ontology );
      manager.addOntologyChangeListener( reasoner );
reasoner.flush();
System.out.println(reasoner.isConsistent());
KnowledgeBase kb = reasoner.getKB();
kb.get
    manager.saveOntology(ontology, IRI.create(file.toURI()));
    manager.saveOntology(ontology, new StreamDocumentTarget(System.out));

}
  public String[][] getConcept(List<String[][]> cps, String s){
      String[][] cp =null;
      int i=0;
      while((i<cps.size()) && (cp==null) ){
          if(cps.get(i)[0][0].compareTo(s)==0)
              cp=cps.get(i);
      i++;
      }
      return cp;
  }

Мне нужен код Java для Pellet, который позволяет обнаруживать группы логически эквивалентных понятий. Буду признателен за вашу помощь. заранее спасибо


person user3503945    schedule 05.06.2014    source источник
comment
@Джошуа Тейлор, спасибо. Да, я спрашиваю, как определить x и y с помощью Pellet, где x и y логически эквивалентны. Логически я имею в виду, что в моей онтологии нет этого кода x owl:equivalentClass y   -  person user3503945    schedule 05.06.2014
comment
ПРАВИЛЬНО, но Пелле будет выводить эти триплеты для вас. Если у вас есть OntClass, вы можете перечислить эквивалентные классы, а если вы только что получили InfModel, вы можете перечислитьStatements со свойством owl:equivalentClass.   -  person Joshua Taylor    schedule 05.06.2014
comment
Хорошо, но в моей онтологии есть только один класс, а остальные NamedIndividual. Как я могу определить, какие NamedIndividual логически эквивалентны?   -  person user3503945    schedule 05.06.2014
comment
Вы спрашивали о концепциях. Индивидуумы — это не понятия. Классы — это концепции. Однако применим тот же принцип; вы бы просто искали тройки с предикатом owl:sameAs.   -  person Joshua Taylor    schedule 05.06.2014


Ответы (2)


В OWLAPI все результаты OWLReasoner типа Node и NodeSet состоят из наборов эквивалентных сущностей.

Для OWLNamedIndividual OWLReasoner::getSameIndividuals() возвращает объект Node<OWLNamedIndividual>, который содержит всех индивидуумов, предполагаемых sameAs друг другом.

Также можно запросить экземпляры класса: OWLReasoner::getInstances() вернет NodeSet<OWLIndividual>, который представляет собой набор Node объектов, каждый из которых соответствует набору OWLNamedIndividual объектов, которые также являются sameAs друг другом.

То же самое относится к под/супер/эквивалентным классам и свойствам.

Изменить, чтобы включить комментарии:

Чтобы получить всех именованных индивидуумов в онтологии, сгруппированных по принципу sameAs в классах эквивалентности, подход состоит в том, чтобы запросить все экземпляры owl:Thing

NodeSet<OWLNamedIndividual> individuals = reasoner.getInstances(dataFactory.getOWLThing(), false);

NodeSet содержит узлы (в произвольном порядке); каждый узел содержит OWLNamedIndividual объектов в произвольном порядке. Все индивидуумы в одном узле одинаковы друг с другом, т. е. каждый может считаться представителем своего класса эквивалентности. Не существует понятия канонического представителя.

Аналогично, чтобы получить все классы эквивалентности для OWLClass

NodeSet<OWLClass> classes = reasoner.getSubClasses(dataFactory.getOWLThing(), false);

Это набор Node<OWLClass>, каждый из которых содержит эквивалентные классы. Порядок, в котором узлы находятся в NodeSet, и порядок OWLClasses в узле не играют никакой роли и могут меняться от одного вызова к другому.

Из OWLReasoner javadoc

Узлы Интерфейс Reasoner содержит методы, которые возвращают NodeSet объектов. Это наборы из Node объектов. Узел содержит сущности. Для Node<OWLClass> классов каждый класс в узле эквивалентен другим классам в узле в отношении замыкания импорта корневой онтологии. Для Node<OWLObjectProperty> свойств объекта каждое свойство объекта в узле эквивалентно другим свойствам объекта в узле в отношении замыкания импорта корневой онтологии. Для узла свойств данных каждое свойство данных в узле эквивалентно другим свойствам данных в узле в отношении замыкания импорта корневой онтологии. Для узла именованных индивидуумов каждый индивидуум в узле такой же, как и другие индивидуумы в узле в отношении замыкания импорта корневой онтологии.

person Ignazio    schedule 05.06.2014
comment
Однако для этого потребуется сначала иметь в виду конкретного человека и спросить, что ему равно? Если вы хотите перебрать классы эквивалентности, есть ли простой способ сделать это? (Да, можно перебирать отдельных людей, а затем одних и тех же, сокращая первый шаг, если человек уже рассматривался как один и тот же человек.) - person Joshua Taylor; 06.06.2014
comment
Прямого доступа в интерфейсе OWLReasoner нет, но хитрость состоит в том, чтобы запросить прямые и косвенные экземпляры OWL:Thing. Это должно вернуть всех индивидуумов, аккуратно отсортированных по классам эквивалентности. - person Ignazio; 06.06.2014
comment
Вы имеете в виду, что экземпляры будут упорядочены по классу эквивалентности? (Это интересно, я этого не знал. Это надежное/указанное поведение?) - person Joshua Taylor; 06.06.2014
comment
Не упорядоченные, а сгруппированные по классу эквивалентности. Узел — это, по сути, другое название для этого. Я не уверен, как это указано, но он должен быть надежным - ответственность за создание узлов лежит на рассудителе, поэтому пробег может варьироваться. - person Ignazio; 06.06.2014
comment
Извините, "заказал" был неправильным термином. Вы имеете в виду, что если у нас есть a, b, c, d, e, где a = b = c и d = e, мы получим представителя от {a b c} и представителя от {d e}, или мы получим список всех их, и {a b c} будет появляться последовательно (но без определенного порядка), а {d e} будет появляться последовательно (но без определенного порядка)? - person Joshua Taylor; 06.06.2014
comment
я исправлю ответ - person Ignazio; 06.06.2014
comment
Отличное объяснение! Сначала я не уловил различия Узел/Индивидуум (и я не уверен, знал ли я об этом с самого начала). Это выглядит очень удобно. - person Joshua Taylor; 07.06.2014

Примечание. Подход в этом ответе правильный, но он основан на ошибочном предположении, что использовался Jena API (в исходной версии вопроса было показано не так много кода).

На самом деле это больше вопрос о том, как использовать API Jena для работы с моделями, поскольку Pellet можно использовать с другими API (например, OWLAPI), и то, как вы будете получать эту информацию, будет отличаться в этих случаях. Однако код, который вы показали до сих пор, похоже, использует Jena. Основные подходы, которые следует здесь рассмотреть, следующие:

  • перечисление всех пар эквивалентных классов
  • для некоторого конкретного класса перечислите все эквивалентные классы

В приведенном ниже коде показано, как сделать и то, и другое. Обратите внимание, что не совсем правильно говорить, что вы перечисляете все эквивалентные классы, потому что их бесконечно много. Например.,

А А А А А

Строго говоря, это выражения класса, и их может быть больше одного. После того, как вы определили, например, AB, на самом деле существует только один класс, так случилось, что есть два выражения класса, которые обозначают этот класс. Это похоже на вопрос: «Какие числа равны 2?» Ответ «только 2», тогда как на вопрос «какие арифметические выражения имеют значение 2?» ответ на это {2, 1+1, 2 1, 4/2, …}. Я указываю на это только потому, что не уверен, какие результаты даст вам Pellet, хотя я ожидаю, что он просто будет искать выражения классов, которые уже присутствуют в вашей онтологии.

import org.mindswap.pellet.jena.PelletReasonerFactory;

import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import com.hp.hpl.jena.vocabulary.OWL;

public class GetEquivalentClassesExample {
    public static void main(String[] args) {
        /*
         * Create an OntModel with an attached Pellet reasoner.
         */
        OntModel model = ModelFactory.createOntologyModel( PelletReasonerFactory.THE_SPEC );

        /*
         * Load your data.
         */
        model.read( "..." );

        /*
         * To list all pairs of equivalent classes, you can just list
         * the statements with the property owl:equivalentClass
         */
        StmtIterator s = model.listStatements( null, OWL.equivalentClass, (RDFNode) null );
        while ( s.hasNext() ) { 
            System.out.println( s.next() );
        }

        /*
         * If you just want the classes that are equivalent to some particular
         * class, you can get a reference to that class, and then ask for its
         * equivalent classes.
         */
        OntClass klass = model.getOntClass( "..." );
        ExtendedIterator<OntClass> c = klass.listEquivalentClasses();
        while ( c.hasNext() ) {
            System.out.println( c.next() );
        }
    }
}
person Joshua Taylor    schedule 05.06.2014
comment
Большое спасибо, но я использую OWL API для создания своей онтологии. Более того, все концепции объявлены как NamedIndividual, потому что у меня есть ObjectProperty, которые должны быть объявлены с несколькими доменами и диапазонами, и это разрешено только для отдельных лиц. Чтобы быть более ясным, я отредактировал свой вопрос, чтобы поделиться с вами кодом, который я создаю онтологию и использую PelletReasoner. В результате я хочу, чтобы метод определял все логически эквивалентные NamedIndividual. - person user3503945; 05.06.2014
comment
Я хотел бы, чтобы вы уточнили, какой API вы использовали в исходном вопросе, и что вы работали с NamedIndividuals. Тем не менее, по-прежнему не так уж сложно составить список равных лиц с помощью OWLAPI. Это должно быть вопросом одних и тех же индивидуальных аксиом… Возможно, я вернусь к этому через некоторое время… - person Joshua Taylor; 05.06.2014
comment
Большое спасибо за твою помощь. Буду признателен, если вы подскажете, как составить список логически равных NamedIndividual. заранее спасибо - person user3503945; 05.06.2014