001/**
002 * Copyright (C) 2007 - 2016, Jens Lehmann
003 *
004 * This file is part of DL-Learner.
005 *
006 * DL-Learner is free software; you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation; either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * DL-Learner is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
018 */
019package org.dllearner.reasoning;
020
021import java.util.HashSet;
022import java.util.Set;
023
024import org.semanticweb.owlapi.model.IRI;
025import org.semanticweb.owlapi.model.OWLClass;
026import org.semanticweb.owlapi.model.OWLNamedIndividual;
027import org.semanticweb.owlapi.model.OWLObjectProperty;
028import org.semanticweb.owlapi.model.OWLOntology;
029
030import com.google.common.collect.Sets;
031
032import org.semanticweb.owlapi.model.parameters.Imports;
033import uk.ac.manchester.cs.owl.owlapi.OWLObjectPropertyImpl;
034
035/**
036 * OWL 1 DL required a strict separation between the names of, e.g., classes and individuals. 
037 * OWL 2 DL relaxes this separation somewhat to allow different uses of the same term, 
038 * e.g., Eagle, to be used for both a class, the class of all Eagles, and an individual, 
039 * the individual representing the species Eagle belonging to the (meta)class of all plant and
040 *  animal species. However, OWL 2 DL still imposes certain restrictions: it requires that a name 
041 *  cannot be used for both a class and a datatype and that a name can only be used for one kind 
042 *  of property. The OWL 2 Direct Semantics treats the different uses of the same name as 
043 *  completely separate, as is required in DL reasoners.
044 * @author Lorenz Buehmann
045 *
046 */
047public class OWLPunningDetector {
048        
049        enum PunningType {
050                CLASS_INDIVIDUAL, PROPERTY_INDIVIDUAL, CLASS_PROPERTY 
051        }
052        
053        /**
054         * This object property is used to connect individuals with classes that are also individuals, thus, lead to punning.
055         */
056        public static final OWLObjectProperty punningProperty = new OWLObjectPropertyImpl(IRI.create("http://dl-learner.org/punning/relatedTo"));
057        
058        /**
059         * Checks whether the same IRI denotes both a class and an individual in the ontology.
060         * @param ontology the OWL ontology
061         * @param cls the OWL class
062         * @return TRUE if the class IRI is used also as individual, otherwise FALSE
063         */
064        public static boolean hasPunning(OWLOntology ontology, OWLClass cls){
065                return hasPunning(ontology, cls.getIRI());
066        }
067        
068        /**
069         * Checks whether the ontology contains punning, i.e. entities declared as both, class and individual.
070         * @param ontology the OWL ontology
071         * @return TRUE if there is at least one entity that is both, class and individual, otherwise FALSE
072         */
073        public static boolean hasPunning(OWLOntology ontology){
074                Set<OWLClass> classes = ontology.getClassesInSignature(Imports.INCLUDED);
075                Set<OWLNamedIndividual> individuals = ontology.getIndividualsInSignature(Imports.INCLUDED);
076                
077                Set<IRI> classIRIs = new HashSet<>(classes.size());
078                for (OWLClass cls : classes) {
079                        classIRIs.add(cls.getIRI());
080                }
081                
082                Set<IRI> individualIRIs = new HashSet<>(classes.size());
083                for (OWLNamedIndividual ind : individuals) {
084                        individualIRIs.add(ind.getIRI());
085                }
086                
087                return Sets.intersection(classIRIs, individualIRIs).size() > 0;
088        }
089        
090        /**
091         * Checks whether the same IRI denotes both a class and an individual in the ontology.
092         * @param ontology the OWL ontology
093         * @param iri the entity IRI
094         * @return TRUE if the IRI is used as both, class and individual, otherwise FALSE
095         */
096        public static boolean hasPunning(OWLOntology ontology, IRI iri){
097                boolean isClass = ontology.getClassesInSignature().contains(ontology.getOWLOntologyManager().getOWLDataFactory().getOWLClass(iri));
098                boolean isIndividual = ontology.getIndividualsInSignature().contains(ontology.getOWLOntologyManager().getOWLDataFactory().getOWLNamedIndividual(iri));
099                return isClass && isIndividual;
100        }
101}