All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.semanticweb.owlapi.profiles.OWL2DLProfile Maven / Gradle / Ivy

/*
 * This file is part of the OWL API.
 *
 * The contents of this file are subject to the LGPL License, Version 3.0.
 *
 * Copyright (C) 2011, The University of Manchester
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses/.
 *
 *
 * Alternatively, the contents of this file may be used under the terms of the Apache License, Version 2.0
 * in which case, the provisions of the Apache License Version 2.0 are applicable instead of those above.
 *
 * Copyright 2011, University of Manchester
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.semanticweb.owlapi.profiles;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAnnotationProperty;
import org.semanticweb.owlapi.model.OWLAsymmetricObjectPropertyAxiom;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLDataIntersectionOf;
import org.semanticweb.owlapi.model.OWLDataOneOf;
import org.semanticweb.owlapi.model.OWLDataProperty;
import org.semanticweb.owlapi.model.OWLDataUnionOf;
import org.semanticweb.owlapi.model.OWLDatatype;
import org.semanticweb.owlapi.model.OWLDatatypeDefinitionAxiom;
import org.semanticweb.owlapi.model.OWLDifferentIndividualsAxiom;
import org.semanticweb.owlapi.model.OWLDisjointClassesAxiom;
import org.semanticweb.owlapi.model.OWLDisjointDataPropertiesAxiom;
import org.semanticweb.owlapi.model.OWLDisjointObjectPropertiesAxiom;
import org.semanticweb.owlapi.model.OWLDisjointUnionAxiom;
import org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom;
import org.semanticweb.owlapi.model.OWLEquivalentDataPropertiesAxiom;
import org.semanticweb.owlapi.model.OWLEquivalentObjectPropertiesAxiom;
import org.semanticweb.owlapi.model.OWLFunctionalObjectPropertyAxiom;
import org.semanticweb.owlapi.model.OWLHasKeyAxiom;
import org.semanticweb.owlapi.model.OWLInverseFunctionalObjectPropertyAxiom;
import org.semanticweb.owlapi.model.OWLIrreflexiveObjectPropertyAxiom;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLObject;
import org.semanticweb.owlapi.model.OWLObjectExactCardinality;
import org.semanticweb.owlapi.model.OWLObjectHasSelf;
import org.semanticweb.owlapi.model.OWLObjectIntersectionOf;
import org.semanticweb.owlapi.model.OWLObjectMaxCardinality;
import org.semanticweb.owlapi.model.OWLObjectMinCardinality;
import org.semanticweb.owlapi.model.OWLObjectOneOf;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
import org.semanticweb.owlapi.model.OWLObjectUnionOf;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyID;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.model.OWLSameIndividualAxiom;
import org.semanticweb.owlapi.model.OWLSubDataPropertyOfAxiom;
import org.semanticweb.owlapi.model.OWLSubPropertyChainOfAxiom;
import org.semanticweb.owlapi.util.OWLObjectPropertyManager;
import org.semanticweb.owlapi.util.OWLOntologyWalker;
import org.semanticweb.owlapi.util.OWLOntologyWalkerVisitor;
import org.semanticweb.owlapi.vocab.Namespaces;
import org.semanticweb.owlapi.vocab.OWL2Datatype;

/**
 * @author Matthew Horridge, The University of Manchester, Information
 *         Management Group, Date: 02-Aug-2009
 */
public class OWL2DLProfile implements OWLProfile {

    @Override
    public String getName() {
        return "OWL 2 DL";
    }

    @Override
    public IRI getIRI() {
        return OWL2_DL;
    }

    @Override
    public OWLProfileReport checkOntology(OWLOntology ontology) {
        OWL2Profile owl2Profile = new OWL2Profile();
        OWLProfileReport report = owl2Profile.checkOntology(ontology);
        Set violations = new LinkedHashSet();
        if (!report.isInProfile()) {
            // We won't be in the OWL 2 DL Profile then!
            violations.addAll(report.getViolations());
        }
        OWLOntologyProfileWalker ontologyWalker = new OWLOntologyProfileWalker(
                ontology.getImportsClosure());
        OWL2DLProfileObjectVisitor visitor = new OWL2DLProfileObjectVisitor(
                ontologyWalker, ontology.getOWLOntologyManager());
        ontologyWalker.walkStructure(visitor);
        violations.addAll(visitor.getProfileViolations());
        return new OWLProfileReport(this, violations);
    }

    private static class OWL2DLProfileObjectVisitor extends
            OWLOntologyWalkerVisitor {

        private OWLObjectPropertyManager objectPropertyManager = null;
        private final OWLOntologyManager manager;
        private final Set profileViolations = new HashSet();

        OWL2DLProfileObjectVisitor(OWLOntologyWalker walker,
                OWLOntologyManager manager) {
            super(walker);
            this.manager = manager;
        }

        public Set getProfileViolations() {
            return new HashSet(profileViolations);
        }

        private OWLObjectPropertyManager getPropertyManager() {
            if (objectPropertyManager == null) {
                objectPropertyManager = new OWLObjectPropertyManager(manager,
                        getCurrentOntology());
            }
            return objectPropertyManager;
        }

        @Override
        public Object visit(OWLDataOneOf node) {
            if (node.getValues().isEmpty()) {
                profileViolations.add(new EmptyOneOfAxiom(getCurrentOntology(),
                        getCurrentAxiom()));
            }
            return null;
        }

        @Override
        public Object visit(OWLDataUnionOf node) {
            if (node.getOperands().size() < 2) {
                profileViolations.add(new InsufficientOperands(
                        getCurrentOntology(), getCurrentAxiom(), node));
            }
            return null;
        }

        @Override
        public Object visit(OWLDataIntersectionOf node) {
            if (node.getOperands().size() < 2) {
                profileViolations.add(new InsufficientOperands(
                        getCurrentOntology(), getCurrentAxiom(), node));
            }
            return null;
        }

        @Override
        public Object visit(OWLObjectIntersectionOf node) {
            if (node.getOperands().size() < 2) {
                profileViolations.add(new InsufficientOperands(
                        getCurrentOntology(), getCurrentAxiom(), node));
            }
            return null;
        }

        @Override
        public Object visit(OWLObjectOneOf node) {
            if (node.getIndividuals().isEmpty()) {
                profileViolations.add(new EmptyOneOfAxiom(getCurrentOntology(),
                        getCurrentAxiom()));
            }
            return null;
        }

        @Override
        public Object visit(OWLObjectUnionOf node) {
            if (node.getOperands().size() < 2) {
                profileViolations.add(new InsufficientOperands(
                        getCurrentOntology(), getCurrentAxiom(), node));
            }
            return null;
        }

        @Override
        public Object visit(OWLEquivalentClassesAxiom node) {
            if (node.getClassExpressions().size() < 2) {
                profileViolations.add(new InsufficientOperands(
                        getCurrentOntology(), node, node));
            }
            return null;
        }

        @Override
        public Object visit(OWLDisjointClassesAxiom node) {
            if (node.getClassExpressions().size() < 2) {
                profileViolations.add(new InsufficientOperands(
                        getCurrentOntology(), node, node));
            }
            return null;
        }

        @Override
        public Object visit(OWLDisjointUnionAxiom node) {
            if (node.getClassExpressions().size() < 2) {
                profileViolations.add(new InsufficientOperands(
                        getCurrentOntology(), node, node));
            }
            return null;
        }

        @Override
        public Object visit(OWLEquivalentObjectPropertiesAxiom node) {
            if (node.getProperties().size() < 2) {
                profileViolations.add(new InsufficientPropertyExpressions(
                        getCurrentOntology(), node));
            }
            return null;
        }

        @Override
        public Object visit(OWLDisjointDataPropertiesAxiom node) {
            if (node.getProperties().size() < 2) {
                profileViolations.add(new InsufficientPropertyExpressions(
                        getCurrentOntology(), node));
            }
            return null;
        }

        @Override
        public Object visit(OWLEquivalentDataPropertiesAxiom node) {
            if (node.getProperties().size() < 2) {
                profileViolations.add(new InsufficientPropertyExpressions(
                        getCurrentOntology(), node));
            }
            return null;
        }

        @Override
        public Object visit(OWLHasKeyAxiom node) {
            if (node.getPropertyExpressions().size() < 1) {
                profileViolations.add(new InsufficientPropertyExpressions(
                        getCurrentOntology(), node));
            }
            return null;
        }

        @Override
        public Object visit(OWLSameIndividualAxiom node) {
            if (node.getIndividuals().size() < 2) {
                profileViolations.add(new InsufficientIndividuals(
                        getCurrentOntology(), node));
            }
            return null;
        }

        @Override
        public Object visit(OWLDifferentIndividualsAxiom node) {
            if (node.getIndividuals().size() < 2) {
                profileViolations.add(new InsufficientIndividuals(
                        getCurrentOntology(), node));
            }
            return null;
        }

        @Override
        public Object visit(OWLOntology ontology) {
            OWLOntologyID ontologyID = ontology.getOntologyID();
            if (!ontologyID.isAnonymous()) {
                if (ontologyID.getOntologyIRI().isReservedVocabulary()) {
                    profileViolations
                            .add(new UseOfReservedVocabularyForOntologyIRI(
                                    getCurrentOntology()));
                }
                IRI versionIRI = ontologyID.getVersionIRI();
                if (versionIRI != null) {
                    if (versionIRI.isReservedVocabulary()) {
                        profileViolations
                                .add(new UseOfReservedVocabularyForVersionIRI(
                                        getCurrentOntology()));
                    }
                }
            }
            objectPropertyManager = null;
            return super.visit(ontology);
        }

        @Override
        public Object visit(OWLClass desc) {
            if (!desc.isBuiltIn()) {
                if (desc.getIRI().isReservedVocabulary()) {
                    profileViolations
                            .add(new UseOfReservedVocabularyForClassIRI(
                                    getCurrentOntology(), getCurrentAxiom(),
                                    desc));
                }
            }
            if (!desc.isBuiltIn()
                    && !getCurrentOntology().isDeclared(desc, true)) {
                profileViolations.add(new UseOfUndeclaredClass(
                        getCurrentOntology(), getCurrentAxiom(), desc));
            }
            if (getCurrentOntology().containsDatatypeInSignature(desc.getIRI())) {
                profileViolations
                        .add(new DatatypeIRIAlsoUsedAsClassIRI(
                                getCurrentOntology(), getCurrentAxiom(), desc
                                        .getIRI()));
            }
            return null;
        }

        @Override
        public Object visit(OWLDatatype datatype) {
            // Each datatype MUST statisfy the following:
            // An IRI used to identify a datatype MUST
            // - Identify a datatype in the OWL 2 datatype map (Section 4.1
            // lists them), or
            // - Have the xsd: prefix, or
            // - Be rdfs:Literal, or
            // - Not be in the reserved vocabulary of OWL 2
            if (!OWL2Datatype.isBuiltIn(datatype.getIRI())) {
                if (!Namespaces.XSD.inNamespace(datatype.getIRI())) {
                    if (!datatype.isTopDatatype()) {
                        if (datatype.getIRI().isReservedVocabulary()) {
                            profileViolations.add(new UseOfUnknownDatatype(
                                    getCurrentOntology(), getCurrentAxiom(),
                                    datatype));
                        }
                    }
                }
                // We also have to declare datatypes that are not built in
                if (!datatype.isTopDatatype() && datatype.isBuiltIn()
                        && getCurrentOntology().isDeclared(datatype, true)) {
                    profileViolations.add(new UseOfUndeclaredDatatype(
                            getCurrentOntology(), getCurrentAxiom(), datatype));
                }
            }
            if (getCurrentOntology().containsClassInSignature(
                    datatype.getIRI(), true)) {
                profileViolations.add(new DatatypeIRIAlsoUsedAsClassIRI(
                        getCurrentOntology(), getCurrentAxiom(), datatype
                                .getIRI()));
            }
            return null;
        }

        @Override
        public Object visit(OWLDatatypeDefinitionAxiom axiom) {
            if (axiom.getDatatype().getIRI().isReservedVocabulary()) {
                profileViolations
                        .add(new UseOfBuiltInDatatypeInDatatypeDefinition(
                                getCurrentOntology(), axiom));
            }
            // Check for cycles
            Set datatypes = new HashSet();
            Set axioms = new LinkedHashSet();
            axioms.add(axiom);
            getDatatypesInSignature(datatypes, axiom.getDataRange(), axioms);
            if (datatypes.contains(axiom.getDatatype())) {
                profileViolations.add(new CycleInDatatypeDefinition(
                        getCurrentOntology(), axiom));
            }
            return null;
        }

        private void getDatatypesInSignature(Set datatypes,
                OWLObject obj, Set axioms) {
            for (OWLDatatype dt : obj.getDatatypesInSignature()) {
                if (datatypes.add(dt)) {
                    for (OWLOntology ont : getCurrentOntology()
                            .getImportsClosure()) {
                        for (OWLDatatypeDefinitionAxiom ax : ont
                                .getDatatypeDefinitions(dt)) {
                            axioms.add(ax);
                            getDatatypesInSignature(datatypes,
                                    ax.getDataRange(), axioms);
                        }
                    }
                }
            }
        }

        @Override
        public Object visit(OWLObjectProperty property) {
            if (!property.isOWLTopObjectProperty()
                    && !property.isOWLBottomObjectProperty()) {
                if (property.getIRI().isReservedVocabulary()) {
                    profileViolations
                            .add(new UseOfReservedVocabularyForObjectPropertyIRI(
                                    getCurrentOntology(), getCurrentAxiom(),
                                    property));
                }
            }
            if (!property.isBuiltIn()
                    && !getCurrentOntology().isDeclared(property, true)) {
                profileViolations.add(new UseOfUndeclaredObjectProperty(
                        getCurrentOntology(), getCurrentAxiom(), property));
            }
            if (getCurrentOntology().containsDataPropertyInSignature(
                    property.getIRI(), true)) {
                profileViolations.add(new IllegalPunning(getCurrentOntology(),
                        getCurrentAxiom(), property.getIRI()));
            }
            if (getCurrentOntology().containsAnnotationPropertyInSignature(
                    property.getIRI(), true)) {
                profileViolations.add(new IllegalPunning(getCurrentOntology(),
                        getCurrentAxiom(), property.getIRI()));
            }
            return null;
        }

        @Override
        public Object visit(OWLDataProperty property) {
            if (!property.isOWLTopDataProperty()
                    && !property.isOWLBottomDataProperty()) {
                if (property.getIRI().isReservedVocabulary()) {
                    profileViolations
                            .add(new UseOfReservedVocabularyForDataPropertyIRI(
                                    getCurrentOntology(), getCurrentAxiom(),
                                    property));
                }
            }
            if (!property.isBuiltIn()
                    && !getCurrentOntology().isDeclared(property, true)) {
                profileViolations.add(new UseOfUndeclaredDataProperty(
                        getCurrentOntology(), getCurrentAxiom(), property));
            }
            if (getCurrentOntology().containsObjectPropertyInSignature(
                    property.getIRI(), true)) {
                profileViolations.add(new IllegalPunning(getCurrentOntology(),
                        getCurrentAxiom(), property.getIRI()));
            }
            if (getCurrentOntology().containsAnnotationPropertyInSignature(
                    property.getIRI(), true)) {
                profileViolations.add(new IllegalPunning(getCurrentOntology(),
                        getCurrentAxiom(), property.getIRI()));
            }
            return null;
        }

        @Override
        public Object visit(OWLAnnotationProperty property) {
            if (!property.isBuiltIn()) {
                if (property.getIRI().isReservedVocabulary()) {
                    profileViolations
                            .add(new UseOfReservedVocabularyForAnnotationPropertyIRI(
                                    getCurrentOntology(), getCurrentAxiom(),
                                    property));
                }
            }
            if (!property.isBuiltIn()
                    && !getCurrentOntology().isDeclared(property, true)) {
                profileViolations.add(new UseOfUndeclaredAnnotationProperty(
                        getCurrentOntology(), getCurrentAxiom(),
                        getCurrentAnnotation(), property));
            }
            if (getCurrentOntology().containsObjectPropertyInSignature(
                    property.getIRI(), true)) {
                profileViolations.add(new IllegalPunning(getCurrentOntology(),
                        getCurrentAxiom(), property.getIRI()));
            }
            if (getCurrentOntology().containsDataPropertyInSignature(
                    property.getIRI(), true)) {
                profileViolations.add(new IllegalPunning(getCurrentOntology(),
                        getCurrentAxiom(), property.getIRI()));
            }
            return null;
        }

        @Override
        public Object visit(OWLNamedIndividual individual) {
            if (!individual.isAnonymous()
                    && individual.getIRI().isReservedVocabulary()) {
                profileViolations
                        .add(new UseOfReservedVocabularyForIndividualIRI(
                                getCurrentOntology(), getCurrentAxiom(),
                                individual));
            }
            return null;
        }

        @Override
        public Object visit(OWLSubDataPropertyOfAxiom axiom) {
            if (axiom.getSubProperty().isOWLTopDataProperty()) {
                profileViolations
                        .add(new UseOfTopDataPropertyAsSubPropertyInSubPropertyAxiom(
                                getCurrentOntology(), axiom));
            }
            return null;
        }

        @Override
        public Object visit(OWLObjectMinCardinality desc) {
            if (getPropertyManager().isNonSimple(desc.getProperty())) {
                profileViolations
                        .add(new UseOfNonSimplePropertyInCardinalityRestriction(
                                getCurrentOntology(), getCurrentAxiom(), desc));
            }
            return null;
        }

        @Override
        public Object visit(OWLObjectMaxCardinality desc) {
            if (getPropertyManager().isNonSimple(desc.getProperty())) {
                profileViolations
                        .add(new UseOfNonSimplePropertyInCardinalityRestriction(
                                getCurrentOntology(), getCurrentAxiom(), desc));
            }
            return null;
        }

        @Override
        public Object visit(OWLObjectExactCardinality desc) {
            if (getPropertyManager().isNonSimple(desc.getProperty())) {
                profileViolations
                        .add(new UseOfNonSimplePropertyInCardinalityRestriction(
                                getCurrentOntology(), getCurrentAxiom(), desc));
            }
            return null;
        }

        @Override
        public Object visit(OWLObjectHasSelf desc) {
            if (getPropertyManager().isNonSimple(desc.getProperty())) {
                profileViolations
                        .add(new UseOfNonSimplePropertyInObjectHasSelf(
                                getCurrentOntology(), getCurrentAxiom(), desc));
            }
            return null;
        }

        @Override
        public Object visit(OWLFunctionalObjectPropertyAxiom axiom) {
            if (getPropertyManager().isNonSimple(axiom.getProperty())) {
                profileViolations
                        .add(new UseOfNonSimplePropertyInFunctionalPropertyAxiom(
                                getCurrentOntology(), axiom));
            }
            return null;
        }

        @Override
        public Object visit(OWLInverseFunctionalObjectPropertyAxiom axiom) {
            if (getPropertyManager().isNonSimple(axiom.getProperty())) {
                profileViolations
                        .add(new UseOfNonSimplePropertyInInverseFunctionalObjectPropertyAxiom(
                                getCurrentOntology(), axiom));
            }
            return null;
        }

        @Override
        public Object visit(OWLIrreflexiveObjectPropertyAxiom axiom) {
            if (getPropertyManager().isNonSimple(axiom.getProperty())) {
                profileViolations
                        .add(new UseOfNonSimplePropertyInIrreflexivePropertyAxiom(
                                getCurrentOntology(), axiom));
            }
            return null;
        }

        @Override
        public Object visit(OWLAsymmetricObjectPropertyAxiom axiom) {
            if (getPropertyManager().isNonSimple(axiom.getProperty())) {
                profileViolations
                        .add(new UseOfNonSimplePropertyInAsymmetricObjectPropertyAxiom(
                                getCurrentOntology(), axiom));
            }
            return null;
        }

        @Override
        public Object visit(OWLDisjointObjectPropertiesAxiom axiom) {
            if (axiom.getProperties().size() < 2) {
                profileViolations.add(new InsufficientPropertyExpressions(
                        getCurrentOntology(), axiom));
            }
            for (OWLObjectPropertyExpression prop : axiom.getProperties()) {
                if (getPropertyManager().isNonSimple(prop)) {
                    profileViolations
                            .add(new UseOfNonSimplePropertyInDisjointPropertiesAxiom(
                                    getCurrentOntology(), axiom, prop));
                }
            }
            return null;
        }

        @Override
        public Object visit(OWLSubPropertyChainOfAxiom axiom) {
            // Restriction on the Property Hierarchy. A strict partial order
            // (i.e., an irreflexive and transitive relation) < on AllOPE(Ax)
            // exists that fulfills the following conditions:
            //
            // OP1 < OP2 if and only if INV(OP1) < OP2 for all object properties
            // OP1 and OP2 occurring in AllOPE(Ax).
            // If OPE1 < OPE2 holds, then OPE2 ->* OPE1 does not hold;
            // Each axiom in Ax of the form SubObjectPropertyOf(
            // ObjectPropertyChain( OPE1 ... OPEn ) OPE ) with n => 2 fulfills
            // the following conditions:
            // OPE is equal to owl:topObjectProperty, or [TOP]
            // n = 2 and OPE1 = OPE2 = OPE, or [TRANSITIVE_PROP]
            // OPEi < OPE for each 1 <= i <= n, or [ALL_SMALLER]
            // OPE1 = OPE and OPEi < OPE for each 2 <= i <= n, or [FIRST_EQUAL]
            // OPEn = OPE and OPEi < OPE for each 1 <= i <= n-1. [LAST_EQUAL]
            if (axiom.getPropertyChain().size() < 2) {
                profileViolations.add(new InsufficientPropertyExpressions(
                        getCurrentOntology(), axiom));
            }
            OWLObjectPropertyExpression superProp = axiom.getSuperProperty();
            if (superProp.isOWLTopObjectProperty()
                    || axiom.isEncodingOfTransitiveProperty()) {
                // TOP or TRANSITIVE_PROP: no violation can occur
                return null;
            }
            List chain = axiom.getPropertyChain();
            final OWLObjectPropertyExpression first = chain.get(0);
            final OWLObjectPropertyExpression last = chain
                    .get(chain.size() - 1);
            // center part of the chain must be smaller in any case
            for (int i = 1; i < chain.size() - 1; i++) {
                if (getPropertyManager().isLessThan(superProp, chain.get(i))) {
                    profileViolations.add(new UseOfPropertyInChainCausesCycle(
                            getCurrentOntology(), axiom, chain.get(i)));
                }
            }
            if (first.equals(superProp)) {
                // first equals, last must be smaller
                if (getPropertyManager().isLessThan(superProp, last)) {
                    profileViolations.add(new UseOfPropertyInChainCausesCycle(
                            getCurrentOntology(), axiom, last));
                }
            } else {
                // first not equal, it must be smaller
                if (getPropertyManager().isLessThan(superProp, first)) {
                    profileViolations.add(new UseOfPropertyInChainCausesCycle(
                            getCurrentOntology(), axiom, first));
                }
            }
            if (last.equals(superProp)) {
                // last equals, first must be smaller
                if (getPropertyManager().isLessThan(superProp, first)) {
                    profileViolations.add(new UseOfPropertyInChainCausesCycle(
                            getCurrentOntology(), axiom, first));
                }
            } else {
                // last not equal, it must be smaller
                if (getPropertyManager().isLessThan(superProp, last)) {
                    profileViolations.add(new UseOfPropertyInChainCausesCycle(
                            getCurrentOntology(), axiom, last));
                }
            }
            // neither first and last equal: they both must be smaller, checked
            // already in the else branches
            return null;
        }
    }
}