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

org.semanticweb.HermiT.structural.ObjectPropertyInclusionManager Maven / Gradle / Ivy

Go to download

HermiT is reasoner for ontologies written using the Web Ontology Language (OWL). Given an OWL file, HermiT can determine whether or not the ontology is consistent, identify subsumption relationships between classes, and much more. This is the maven build of HermiT and is designed for people who wish to use HermiT from within the OWL API. It is now versioned in the main HermiT version repository, although not officially supported by the HermiT developers. The version number of this package is a composite of the HermiT version and an value representing releases of this packaged version. So, 1.3.7.1 is the first release of the mavenized version of HermiT based on the 1.3.7 release of HermiT. This package includes the Jautomata library (http://jautomata.sourceforge.net/), and builds with it directly. This library appears to be no longer under active development, and so a "fork" seems appropriate. No development is intended or anticipated on this code base.

There is a newer version: 1.3.8.4
Show newest version
/* Copyright 2008, 2009, 2010 by the Oxford University Computing Laboratory

   This file is part of HermiT.

   HermiT is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   HermiT 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 Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with HermiT.  If not, see .
 */
package org.semanticweb.HermiT.structural;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.semanticweb.HermiT.graph.Graph;
import org.semanticweb.HermiT.structural.OWLAxioms.ComplexObjectPropertyInclusion;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLClassExpression;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLIndividual;
import org.semanticweb.owlapi.model.OWLIndividualAxiom;
import org.semanticweb.owlapi.model.OWLNegativeObjectPropertyAssertionAxiom;
import org.semanticweb.owlapi.model.OWLObjectAllValuesFrom;
import org.semanticweb.owlapi.model.OWLObjectCardinalityRestriction;
import org.semanticweb.owlapi.model.OWLObjectComplementOf;
import org.semanticweb.owlapi.model.OWLObjectHasSelf;
import org.semanticweb.owlapi.model.OWLObjectInverseOf;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;

import rationals.Automaton;
import rationals.NoSuchStateException;
import rationals.State;
import rationals.Transition;

public class ObjectPropertyInclusionManager {
    protected final Map m_automataByProperty;

    public ObjectPropertyInclusionManager(OWLAxioms axioms) {
        m_automataByProperty=new HashMap();
        createAutomata(m_automataByProperty,axioms.m_complexObjectPropertyExpressions,axioms.m_simpleObjectPropertyInclusions,axioms.m_complexObjectPropertyInclusions);
    }
    public int rewriteNegativeObjectPropertyAssertions(OWLDataFactory factory,OWLAxioms axioms,int replacementIndex) {
        // now object property inclusion manager added all non-simple properties to axioms.m_complexObjectPropertyExpressions
        // now that we know which roles are non-simple, we can decide which negative object property assertions have to be
        // expressed as concept assertions so that transitivity rewriting applies properly. All new concepts for the concept
        // assertions must be normalised, because we are done with the normal normalisation phase.
        Set redundantFacts=new HashSet();
        Set additionalFacts=new HashSet();
        for (OWLIndividualAxiom axiom : axioms.m_facts) {
            if (axiom instanceof OWLNegativeObjectPropertyAssertionAxiom) {
                OWLNegativeObjectPropertyAssertionAxiom negAssertion=(OWLNegativeObjectPropertyAssertionAxiom)axiom;
                OWLObjectPropertyExpression prop=negAssertion.getProperty().getSimplified();
                if (axioms.m_complexObjectPropertyExpressions.contains(prop)) {
                    // turn not op(a b) into
                    // C(a) and not C or forall op not{b}
                    OWLIndividual individual=negAssertion.getObject();
                    // neg. op assertions cannot contain anonymous individuals
                    OWLClass individualConcept=factory.getOWLClass(IRI.create("internal:nom#"+individual.asOWLNamedIndividual().getIRI().toString()));
                    OWLClassExpression notIndividualConcept=factory.getOWLObjectComplementOf(individualConcept);
                    OWLClassExpression allNotIndividualConcept=factory.getOWLObjectAllValuesFrom(prop,notIndividualConcept);
                    OWLClassExpression definition=factory.getOWLClass(IRI.create("internal:def#"+(replacementIndex++)));
                    axioms.m_conceptInclusions.add(new OWLClassExpression[] { factory.getOWLObjectComplementOf(definition), allNotIndividualConcept });
                    additionalFacts.add(factory.getOWLClassAssertionAxiom(definition,negAssertion.getSubject()));
                    additionalFacts.add(factory.getOWLClassAssertionAxiom(individualConcept,individual));
                    redundantFacts.add(negAssertion);
                }
            }
        }
        axioms.m_facts.addAll(additionalFacts);
        axioms.m_facts.removeAll(redundantFacts);
        return replacementIndex;
    }
    public void rewriteAxioms(OWLDataFactory dataFactory,OWLAxioms axioms,int firstReplacementIndex) {
        // Check the asymmetric object properties for simplicity
        for (OWLObjectPropertyExpression objectPropertyExpression : axioms.m_asymmetricObjectProperties)
            if (axioms.m_complexObjectPropertyExpressions.contains(objectPropertyExpression))
                throw new IllegalArgumentException("Non-simple property '"+objectPropertyExpression+"' or its inverse appears in asymmetric object property axiom.");
        // Check the irreflexive object properties for simplicity
        for (OWLObjectPropertyExpression objectPropertyExpression : axioms.m_irreflexiveObjectProperties)
            if (axioms.m_complexObjectPropertyExpressions.contains(objectPropertyExpression))
                throw new IllegalArgumentException("Non-simple property '"+objectPropertyExpression+"' or its inverse appears in irreflexive object property axiom.");
        // Check the disjoint object properties for simplicity
        for (OWLObjectPropertyExpression[] properties : axioms.m_disjointObjectProperties)
            for (int i=0;i replacedDescriptions=new HashMap();
        for (OWLClassExpression[] inclusion : axioms.m_conceptInclusions) {
            for (int index=0;index replacement : replacedDescriptions.entrySet()) {
            Automaton automaton=m_automataByProperty.get(replacement.getKey().getProperty());
            boolean isOfNegativePolarity=(replacement.getValue() instanceof OWLObjectComplementOf);
            // Generate states of the automaton
            Map statesToConcepts=new HashMap();
            for (Object stateObject : automaton.states()) {
                State state=(State)stateObject;
                if (state.isInitial())
                    statesToConcepts.put(state,replacement.getValue());
                else {
                    OWLClassExpression stateConcept=dataFactory.getOWLClass(IRI.create("internal:all#"+(firstReplacementIndex++)));
                    if (isOfNegativePolarity)
                        stateConcept=stateConcept.getComplementNNF();
                    statesToConcepts.put(state,stateConcept);
                }
            }
            // Generate the transitions
            for (Object transitionObject : automaton.delta()) {
                Transition transition=(Transition)transitionObject;
                OWLClassExpression fromStateConcept=statesToConcepts.get(transition.start()).getComplementNNF();
                OWLClassExpression toStateConcept=statesToConcepts.get(transition.end());
                if (transition.label()==null)
                    axioms.m_conceptInclusions.add(new OWLClassExpression[] { fromStateConcept,toStateConcept });
                else {
                    OWLObjectAllValuesFrom consequentAll=dataFactory.getOWLObjectAllValuesFrom((OWLObjectPropertyExpression)transition.label(),toStateConcept);
                    axioms.m_conceptInclusions.add(new OWLClassExpression[] { fromStateConcept,consequentAll });
                }
            }
            // Generate the final states
            OWLClassExpression filler=replacement.getKey().getFiller();
            for (Object finalStateObject : automaton.terminals()) {
                OWLClassExpression finalStateConceptComplement=statesToConcepts.get(finalStateObject).getComplementNNF();
                if (filler.isOWLNothing())
                    axioms.m_conceptInclusions.add(new OWLClassExpression[] { finalStateConceptComplement });
                else
                    axioms.m_conceptInclusions.add(new OWLClassExpression[] { finalStateConceptComplement,filler });
            }
        }
    }
    protected void createAutomata(Map automataByProperty,Set complexObjectPropertyExpressions,Collection simpleObjectPropertyInclusions,Collection complexObjectPropertyInclusions) {
        Map> equivalentPropertiesMap=findEquivalentProperties(simpleObjectPropertyInclusions);
        Set symmetricObjectProperties=findSymmetricProperties(simpleObjectPropertyInclusions);
        Map> inversePropertiesMap=buildInversePropertiesMap(simpleObjectPropertyInclusions);
        Graph propertyDependencyGraph=buildPropertyOrdering(simpleObjectPropertyInclusions,complexObjectPropertyInclusions,equivalentPropertiesMap);
        checkForRegularity(propertyDependencyGraph,equivalentPropertiesMap);

        Graph complexPropertiesDependencyGraph=propertyDependencyGraph.clone();
        Set transitiveProperties=new HashSet();
        Map individualAutomata=buildIndividualAutomata(complexPropertiesDependencyGraph,simpleObjectPropertyInclusions,complexObjectPropertyInclusions,equivalentPropertiesMap,transitiveProperties);
        Set simpleProperties=findSimpleProperties(complexPropertiesDependencyGraph,individualAutomata);

        propertyDependencyGraph.removeElements(simpleProperties);

        complexPropertiesDependencyGraph.removeElements(simpleProperties);
        complexObjectPropertyExpressions.addAll(complexPropertiesDependencyGraph.getElements());
        Set inverseOfComplexProperties = new HashSet();
        for( OWLObjectPropertyExpression complexProp : complexObjectPropertyExpressions )
        	inverseOfComplexProperties.add( complexProp.getInverseProperty().getSimplified() );
        complexObjectPropertyExpressions.addAll(inverseOfComplexProperties);

        connectAllAutomata(automataByProperty,propertyDependencyGraph,inversePropertiesMap,individualAutomata,simpleObjectPropertyInclusions,symmetricObjectProperties,transitiveProperties);
        Map individualAutomataForEquivRoles=new HashMap();
        for (OWLObjectPropertyExpression propExprWithAutomaton : automataByProperty.keySet())
        	if (equivalentPropertiesMap.get(propExprWithAutomaton)!=null) {
        		Automaton autoOfPropExpr = automataByProperty.get(propExprWithAutomaton);
	        	for (OWLObjectPropertyExpression equivProp : equivalentPropertiesMap.get(propExprWithAutomaton)) {
	        		if (!equivProp.equals(propExprWithAutomaton) && !automataByProperty.containsKey(equivProp)) {
	        			Automaton automatonOfEquivalent=(Automaton)autoOfPropExpr.clone();
						individualAutomataForEquivRoles.put(equivProp, automatonOfEquivalent);
						simpleProperties.remove(equivProp);
				        complexObjectPropertyExpressions.add(equivProp);
	        		}
	        		OWLObjectPropertyExpression inverseEquivProp = equivProp.getInverseProperty().getSimplified();
	        		if (!inverseEquivProp.equals(propExprWithAutomaton) && !automataByProperty.containsKey(inverseEquivProp)) {
	        			Automaton automatonOfEquivalent=(Automaton)autoOfPropExpr.clone();
						individualAutomataForEquivRoles.put(inverseEquivProp, getMirroredCopy(automatonOfEquivalent));
						simpleProperties.remove(inverseEquivProp);
				        complexObjectPropertyExpressions.add(inverseEquivProp);
	        		}
	        	}
        	}
        automataByProperty.putAll(individualAutomataForEquivRoles);
    }
    private Set findSymmetricProperties(Collection simpleObjectPropertyInclusions) {
    	Set symmetricProperties = new HashSet();
    	for (OWLObjectPropertyExpression[] inclusion : simpleObjectPropertyInclusions)
    		if (inclusion[1].getInverseProperty().getSimplified().equals(inclusion[0]) || inclusion[1].equals(inclusion[0].getInverseProperty().getSimplified())){
    			symmetricProperties.add( inclusion[0] );
    			symmetricProperties.add( inclusion[0].getInverseProperty().getSimplified() );
    		}
		return symmetricProperties;
	}
	protected Map> buildInversePropertiesMap(Collection simpleObjectPropertyInclusions) {
        Map> inversePropertiesMap=new HashMap>();
        for (OWLObjectPropertyExpression[] inclusion : simpleObjectPropertyInclusions)
            if (inclusion[1] instanceof OWLObjectInverseOf) {
                Set inverseProperties=inversePropertiesMap.get(inclusion[0]);
                if (inverseProperties==null)
                    inverseProperties=new HashSet();
                inverseProperties.add(inclusion[1].getInverseProperty().getSimplified());
                inversePropertiesMap.put(inclusion[0],inverseProperties);
            }
        return inversePropertiesMap;
    }
    protected Map> findEquivalentProperties(Collection simpleObjectPropertyInclusions) {
        Graph propertyDependencyGraph=new Graph();
        Map> equivalentObjectPropertiesMapping=new HashMap>();
        for (OWLObjectPropertyExpression[] inclusion : simpleObjectPropertyInclusions)
            if (!inclusion[0].equals(inclusion[1]) && !inclusion[0].equals(inclusion[1].getInverseProperty().getSimplified()))
                propertyDependencyGraph.addEdge(inclusion[0],inclusion[1]);
        propertyDependencyGraph.transitivelyClose();
        for (OWLObjectPropertyExpression objExpr : propertyDependencyGraph.getElements()) {
            if (propertyDependencyGraph.getSuccessors(objExpr).contains(objExpr) || propertyDependencyGraph.getSuccessors(objExpr).contains(objExpr.getInverseProperty().getSimplified())) {
                Set equivPropertiesSet=new HashSet();
                for (OWLObjectPropertyExpression succ : propertyDependencyGraph.getSuccessors(objExpr)) {
                    if (!succ.equals(objExpr) && (propertyDependencyGraph.getSuccessors(succ).contains(objExpr) || propertyDependencyGraph.getSuccessors(succ).contains(objExpr.getInverseProperty().getSimplified())))
                        equivPropertiesSet.add(succ);
                }
                equivalentObjectPropertiesMapping.put(objExpr,equivPropertiesSet);
            }
        }
        return equivalentObjectPropertiesMapping;
    }
    protected Set findSimpleProperties(Graph complexPropertiesDependencyGraph,Map individualAutomata) {
        Set simpleProperties=new HashSet();

        Graph complexPropertiesDependencyGraphWithInverses=complexPropertiesDependencyGraph.clone();

        for (OWLObjectPropertyExpression complexProperty1 : complexPropertiesDependencyGraph.getElements())
            for (OWLObjectPropertyExpression complexProperty2 : complexPropertiesDependencyGraph.getSuccessors(complexProperty1))
                complexPropertiesDependencyGraphWithInverses.addEdge(complexProperty1.getInverseProperty().getSimplified(),complexProperty2.getInverseProperty().getSimplified());

        Graph invertedGraph=complexPropertiesDependencyGraphWithInverses.getInverse();
        invertedGraph.transitivelyClose();

        for (OWLObjectPropertyExpression properties : invertedGraph.getElements()) {
            boolean hasComplexSubproperty=false;
            for (OWLObjectPropertyExpression subDependingProperties : invertedGraph.getSuccessors(properties)) {
                if (individualAutomata.containsKey(subDependingProperties) || individualAutomata.containsKey(subDependingProperties.getInverseProperty().getSimplified())) {
                    hasComplexSubproperty=true;
                    break;
                }
            }
            if (!hasComplexSubproperty && !individualAutomata.containsKey(properties) && !individualAutomata.containsKey(properties.getInverseProperty().getSimplified()))
                simpleProperties.add(properties);
        }
        return simpleProperties;
    }
    protected void connectAllAutomata(Map completeAutomata,Graph propertyDependencyGraph,Map> inversePropertiesMap,Map individualAutomata,Collection simpleObjectPropertyInclusions, Set symmetricObjectProperties, Set transitiveProperties) {
        Graph transClosedGraph=propertyDependencyGraph.clone();
        transClosedGraph.transitivelyClose();

        Set propertiesToStartRecursion=new HashSet();
        for (OWLObjectPropertyExpression owlProp : transClosedGraph.getElements())
            if (transClosedGraph.getSuccessors(owlProp).isEmpty())
                propertiesToStartRecursion.add(owlProp);

        Graph inversePropertyDependencyGraph=propertyDependencyGraph.getInverse();

        for (OWLObjectPropertyExpression superproperty : propertiesToStartRecursion)
            buildCompleteAutomataForProperties(superproperty,inversePropertiesMap,individualAutomata,completeAutomata,inversePropertyDependencyGraph,symmetricObjectProperties,transitiveProperties);

        for (OWLObjectPropertyExpression property : individualAutomata.keySet())
            if (!completeAutomata.containsKey(property)) {
                Automaton propertyAutomaton=individualAutomata.get(property);
                if ((completeAutomata.containsKey(property.getInverseProperty().getSimplified()) && inversePropertyDependencyGraph.getElements().contains(property.getInverseProperty().getSimplified())) || individualAutomata.containsKey(property.getInverseProperty().getSimplified())) {
                    Automaton inversePropertyAutomaton=completeAutomata.get(property.getInverseProperty().getSimplified());
                    if (inversePropertyAutomaton==null)
                        inversePropertyAutomaton=individualAutomata.get(property.getInverseProperty().getSimplified());
                    increaseAutomatonWithInversePropertyAutomaton(propertyAutomaton,inversePropertyAutomaton);
                }
                completeAutomata.put(property,propertyAutomaton);
            }

        Map extraCompleteAutomataForInverseProperties=new HashMap();
        for (OWLObjectPropertyExpression property : completeAutomata.keySet())
            if (!completeAutomata.containsKey(property.getInverseProperty().getSimplified()))
                extraCompleteAutomataForInverseProperties.put(property.getInverseProperty().getSimplified(),getMirroredCopy(completeAutomata.get(property)));

        completeAutomata.putAll(extraCompleteAutomataForInverseProperties);
        extraCompleteAutomataForInverseProperties.clear();

        for (OWLObjectPropertyExpression property : completeAutomata.keySet())
            if (completeAutomata.containsKey(property) && !completeAutomata.containsKey(property.getInverseProperty().getSimplified()))
                extraCompleteAutomataForInverseProperties.put(property.getInverseProperty().getSimplified(),getMirroredCopy(completeAutomata.get(property)));

        completeAutomata.putAll(extraCompleteAutomataForInverseProperties);
        extraCompleteAutomataForInverseProperties.clear();
    }
    protected void increaseAutomatonWithInversePropertyAutomaton(Automaton propertyAutomaton,Automaton inversePropertyAutomaton) {
        State initialState=(State)propertyAutomaton.initials().iterator().next();
        State finalState=(State)propertyAutomaton.terminals().iterator().next();
        Transition transition=(Transition)propertyAutomaton.deltaFrom(initialState,finalState).iterator().next();
        automataConnector(propertyAutomaton,getMirroredCopy(inversePropertyAutomaton),transition);
    }
    protected Automaton buildCompleteAutomataForProperties(OWLObjectPropertyExpression propertyToBuildAutomatonFor,Map> inversePropertiesMap,Map individualAutomata,Map completeAutomata,Graph inversedPropertyDependencyGraph, Set symmetricObjectProperties, Set transitiveProperties) {
        if (completeAutomata.containsKey(propertyToBuildAutomatonFor))
            return completeAutomata.get(propertyToBuildAutomatonFor);
        else if (completeAutomata.containsKey(propertyToBuildAutomatonFor.getInverseProperty().getSimplified()) && !individualAutomata.containsKey(propertyToBuildAutomatonFor)) {
            Automaton mirroredCopy=getMirroredCopy(completeAutomata.get(propertyToBuildAutomatonFor.getInverseProperty().getSimplified()));
            completeAutomata.put(propertyToBuildAutomatonFor,mirroredCopy);
            return mirroredCopy;
        }
        //if the role has no sub-role which is complex and we need to completely construct its automaton
        if (inversedPropertyDependencyGraph.getSuccessors(propertyToBuildAutomatonFor).isEmpty()) {
            Automaton automatonForLeafProperty=individualAutomata.get(propertyToBuildAutomatonFor);
            //if the individual automaton for the role is empty
            if (automatonForLeafProperty==null) {
                Set inverses=inversePropertiesMap.get(propertyToBuildAutomatonFor);
                boolean noInversePropertyWithAutomaton=true;
                //if it has declared inverse roles
                if (inverses!=null) {
                    for (OWLObjectPropertyExpression inverse : inverses)
                        if (individualAutomata.containsKey(inverse) && !inverse.equals(propertyToBuildAutomatonFor)) {
                            automatonForLeafProperty=getMirroredCopy(buildCompleteAutomataForProperties(inverse,inversePropertiesMap,individualAutomata,completeAutomata,inversedPropertyDependencyGraph, symmetricObjectProperties,transitiveProperties));
                            automatonForLeafProperty=minimizeAndNormalizeAutomaton(automatonForLeafProperty);
                            completeAutomata.put(propertyToBuildAutomatonFor,automatonForLeafProperty);
                            noInversePropertyWithAutomaton=false;
                            break;
                        }
                }
                //else if Inv(R) has an automaton
                else if (individualAutomata.containsKey(propertyToBuildAutomatonFor.getInverseProperty().getSimplified())) {
                    automatonForLeafProperty=getMirroredCopy(buildCompleteAutomataForProperties(propertyToBuildAutomatonFor.getInverseProperty().getSimplified(),inversePropertiesMap,individualAutomata,completeAutomata,inversedPropertyDependencyGraph,symmetricObjectProperties,transitiveProperties));
                    if (!completeAutomata.containsKey(propertyToBuildAutomatonFor)) {
                        automatonForLeafProperty=minimizeAndNormalizeAutomaton(automatonForLeafProperty);
                        completeAutomata.put(propertyToBuildAutomatonFor,automatonForLeafProperty);
                    }
                    else
                        automatonForLeafProperty=completeAutomata.get(propertyToBuildAutomatonFor);
                    noInversePropertyWithAutomaton=false;
                }
                //if no inverse (either declared or Inv(R)) has an automaton
                if (noInversePropertyWithAutomaton) {
                    automatonForLeafProperty=new Automaton();
                    State initial=automatonForLeafProperty.addState(true,false);
                    State accepting=automatonForLeafProperty.addState(false,true);
                    try {
                        automatonForLeafProperty.addTransition(new Transition(initial,propertyToBuildAutomatonFor,accepting));
                    }
                    catch (NoSuchStateException e) {
                        throw new IllegalArgumentException("Could not create automaton for property at the bottom of hierarchy (simple property).");
                    }
                	finalizeConstruction(completeAutomata,propertyToBuildAutomatonFor,automatonForLeafProperty,symmetricObjectProperties,transitiveProperties);
                }
            }
            else {
                if (propertyToBuildAutomatonFor.getInverseProperty().getSimplified().isAnonymous() && individualAutomata.containsKey(propertyToBuildAutomatonFor.getInverseProperty().getSimplified())) {
                    Automaton inversePropertyAutomaton=buildCompleteAutomataForProperties(propertyToBuildAutomatonFor.getInverseProperty().getSimplified(),inversePropertiesMap,individualAutomata,completeAutomata,inversedPropertyDependencyGraph,symmetricObjectProperties,transitiveProperties);
                    increaseAutomatonWithInversePropertyAutomaton(automatonForLeafProperty,getMirroredCopy(inversePropertyAutomaton));
                    if (!completeAutomata.containsKey(propertyToBuildAutomatonFor))
                    	finalizeConstruction(completeAutomata,propertyToBuildAutomatonFor,automatonForLeafProperty,symmetricObjectProperties,transitiveProperties);
                    else
                        automatonForLeafProperty=completeAutomata.get(propertyToBuildAutomatonFor);
                }
                else {
                    increaseWithDefinedInverseIfNecessary(propertyToBuildAutomatonFor,automatonForLeafProperty,inversePropertiesMap,individualAutomata);
                	finalizeConstruction(completeAutomata,propertyToBuildAutomatonFor,automatonForLeafProperty,symmetricObjectProperties,transitiveProperties);
                }
            }
            return automatonForLeafProperty;
        }
        else {
            Automaton biggerPropertyAutomaton=individualAutomata.get(propertyToBuildAutomatonFor);
            if (biggerPropertyAutomaton==null) {
                biggerPropertyAutomaton=new Automaton();
                State initialState=biggerPropertyAutomaton.addState(true,false);
                State finalState=biggerPropertyAutomaton.addState(false,true);
                Transition transition=new Transition(initialState,propertyToBuildAutomatonFor,finalState);
                try {
                    biggerPropertyAutomaton.addTransition(transition);
                }
                catch (NoSuchStateException e) {
                    throw new IllegalArgumentException("Could not create automaton");
                }
                for (OWLObjectPropertyExpression smallerProperty : inversedPropertyDependencyGraph.getSuccessors(propertyToBuildAutomatonFor)) {
                    Automaton smallerPropertyAutomaton=buildCompleteAutomataForProperties(smallerProperty,inversePropertiesMap,individualAutomata,completeAutomata,inversedPropertyDependencyGraph,symmetricObjectProperties,transitiveProperties);
                    automataConnector(biggerPropertyAutomaton,smallerPropertyAutomaton,transition);
                    try {
                        biggerPropertyAutomaton.addTransition(new Transition(initialState,smallerProperty,finalState));
                    }
                    catch (NoSuchStateException e) {
                        throw new IllegalArgumentException("Could not create automaton");
                    }
                }
                if (propertyToBuildAutomatonFor.getInverseProperty().getSimplified().isAnonymous() && individualAutomata.containsKey(propertyToBuildAutomatonFor.getInverseProperty().getSimplified())) {
                    Automaton inversePropertyAutomaton=buildCompleteAutomataForProperties(propertyToBuildAutomatonFor.getInverseProperty().getSimplified(),inversePropertiesMap,individualAutomata,completeAutomata,inversedPropertyDependencyGraph,symmetricObjectProperties,transitiveProperties);
                    increaseAutomatonWithInversePropertyAutomaton(biggerPropertyAutomaton,getMirroredCopy(inversePropertyAutomaton));
                    if (!completeAutomata.containsKey(propertyToBuildAutomatonFor))
                    	finalizeConstruction(completeAutomata,propertyToBuildAutomatonFor,biggerPropertyAutomaton,symmetricObjectProperties,transitiveProperties);
                    else
                        biggerPropertyAutomaton=completeAutomata.get(propertyToBuildAutomatonFor);
                }
                else {
                    increaseWithDefinedInverseIfNecessary(propertyToBuildAutomatonFor,biggerPropertyAutomaton,inversePropertiesMap,individualAutomata);
                    if (!completeAutomata.containsKey(propertyToBuildAutomatonFor))
                    	finalizeConstruction(completeAutomata,propertyToBuildAutomatonFor,biggerPropertyAutomaton,symmetricObjectProperties,transitiveProperties);
                    else
                        biggerPropertyAutomaton=completeAutomata.get(propertyToBuildAutomatonFor);
                }
            }
            else {
                for (OWLObjectPropertyExpression smallerProperty : inversedPropertyDependencyGraph.getSuccessors(propertyToBuildAutomatonFor)) {
                    boolean someInternalTransitionMatched=false;
                    for (Object transitionObject : biggerPropertyAutomaton.delta()) {
                        Transition transition=(Transition)transitionObject;
                        if (transition.label()!=null && transition.label().equals(smallerProperty)) {
                            Automaton smallerPropertyAutomaton=buildCompleteAutomataForProperties(smallerProperty,inversePropertiesMap,individualAutomata,completeAutomata,inversedPropertyDependencyGraph,symmetricObjectProperties,transitiveProperties);
                            if (smallerPropertyAutomaton.delta().size()!=1)
                                automataConnector(biggerPropertyAutomaton,smallerPropertyAutomaton,transition);
                            someInternalTransitionMatched=true;
                        }
                    }
                    if (!someInternalTransitionMatched) {
                        Automaton smallerPropertyAutomaton=buildCompleteAutomataForProperties(smallerProperty,inversePropertiesMap,individualAutomata,completeAutomata,inversedPropertyDependencyGraph,symmetricObjectProperties,transitiveProperties);
                        Transition initial2TerminalTransition=(Transition)biggerPropertyAutomaton.deltaFrom((State)biggerPropertyAutomaton.initials().iterator().next(),(State)biggerPropertyAutomaton.terminals().iterator().next()).iterator().next();
                        automataConnector(biggerPropertyAutomaton,smallerPropertyAutomaton,initial2TerminalTransition);
                    }
                }
            }
            if (propertyToBuildAutomatonFor.getInverseProperty().getSimplified().isAnonymous() && individualAutomata.containsKey(propertyToBuildAutomatonFor.getInverseProperty().getSimplified())) {
                Automaton inversePropertyAutomaton=buildCompleteAutomataForProperties(propertyToBuildAutomatonFor.getInverseProperty().getSimplified(),inversePropertiesMap,individualAutomata,completeAutomata,inversedPropertyDependencyGraph,symmetricObjectProperties,transitiveProperties);
                increaseAutomatonWithInversePropertyAutomaton(biggerPropertyAutomaton,getMirroredCopy(inversePropertyAutomaton));
                if (!completeAutomata.containsKey(propertyToBuildAutomatonFor))
                	finalizeConstruction(completeAutomata,propertyToBuildAutomatonFor,biggerPropertyAutomaton,symmetricObjectProperties,transitiveProperties);
                else
                    biggerPropertyAutomaton=completeAutomata.get(propertyToBuildAutomatonFor);
            }
            else {
                increaseWithDefinedInverseIfNecessary(propertyToBuildAutomatonFor,biggerPropertyAutomaton,inversePropertiesMap,individualAutomata);
                if (!completeAutomata.containsKey(propertyToBuildAutomatonFor))
                	finalizeConstruction(completeAutomata,propertyToBuildAutomatonFor,biggerPropertyAutomaton,symmetricObjectProperties,transitiveProperties);
                else
                    biggerPropertyAutomaton=completeAutomata.get(propertyToBuildAutomatonFor);
            }
            return biggerPropertyAutomaton;
        }
    }
    private void finalizeConstruction(Map completeAutomata,OWLObjectPropertyExpression propertyToBuildAutomatonFor,Automaton biggerPropertyAutomaton,Set symmetricObjectProperties,Set transitiveProperties) {
        try {
        	if (transitiveProperties.contains(propertyToBuildAutomatonFor.getInverseProperty().getSimplified()))
            	biggerPropertyAutomaton.addTransition(new Transition((State)biggerPropertyAutomaton.terminals().iterator().next(),null,(State)biggerPropertyAutomaton.initials().iterator().next()));
        }
        catch (NoSuchStateException e) {
            throw new IllegalArgumentException("Could not create automaton for symmetric property: "+propertyToBuildAutomatonFor);
        }

    	if( symmetricObjectProperties.contains( propertyToBuildAutomatonFor )){
	        Transition basicTransition=new Transition((State)biggerPropertyAutomaton.initials().iterator().next(),propertyToBuildAutomatonFor.getInverseProperty().getSimplified(),(State)biggerPropertyAutomaton.terminals().iterator().next());
	        automataConnector(biggerPropertyAutomaton,getMirroredCopy(biggerPropertyAutomaton),basicTransition);
    	}
    	biggerPropertyAutomaton=minimizeAndNormalizeAutomaton(biggerPropertyAutomaton);
        completeAutomata.put(propertyToBuildAutomatonFor,biggerPropertyAutomaton);
        completeAutomata.put(propertyToBuildAutomatonFor.getInverseProperty().getSimplified(),getMirroredCopy(biggerPropertyAutomaton));
	}
	protected void increaseWithDefinedInverseIfNecessary(OWLObjectPropertyExpression propertyToBuildAutomatonFor,Automaton leafPropertyAutomaton,Map> inversePropertiesMap,Map individualAutomata) {
        Set inverses=inversePropertiesMap.get(propertyToBuildAutomatonFor);
        if (inverses!=null) {
            Automaton inversePropertyAutomaton=null;
            for (OWLObjectPropertyExpression inverse : inverses) {
                if (individualAutomata.containsKey(inverse) && !inverse.equals(propertyToBuildAutomatonFor)) {
                    inversePropertyAutomaton=individualAutomata.get(inverse);
                    increaseAutomatonWithInversePropertyAutomaton(leafPropertyAutomaton,inversePropertyAutomaton);
                }
            }
        }
        else if (individualAutomata.containsKey(propertyToBuildAutomatonFor.getInverseProperty().getSimplified())) {
        	Automaton autoOfInv_Role = individualAutomata.get(propertyToBuildAutomatonFor.getInverseProperty().getSimplified());
        	increaseAutomatonWithInversePropertyAutomaton(leafPropertyAutomaton,autoOfInv_Role);
        }
    }
    protected Automaton minimizeAndNormalizeAutomaton(Automaton automaton) {
    	//This part of the code seemed to have a bug in an ontology given by Birte. The ontology created very large automata and was
    	//extremely difficult to see where the bug was exactly. Either the ToDFA class has a bug or due to state renaming that ToDFA does
    	//state names got mixed up later (a similar thing has happened before) however I could not detect something like that happening now.
    	//Without this code the automata are about double in size than with the code which can cause performance issues in ontologies with
    	//large and complex RIAs, which fortunately does not happen.
//        Reducer minimizerDeterminizer=new Reducer();
//        //if the automaton has more than 350-400 transitions it seems that the determiniser is very slow. In general this code does help to reduce the number of clauses produced.
//        if( automaton.delta().size() > 300 )
//        	return automaton;
//        Normalizer normalizer=new Normalizer();
//        Automaton tempMinimizedAuto=minimizerDeterminizer.transform(automaton);
//        if (tempMinimizedAuto.delta().size()>=automaton.delta().size())
//            return automaton;
//        if (tempMinimizedAuto.initials().size()!=1 || tempMinimizedAuto.terminals().size()!=1)
//            tempMinimizedAuto=normalizer.transform(tempMinimizedAuto);
//        if (tempMinimizedAuto.delta().size()>automaton.delta().size())
            return automaton;
//        return tempMinimizedAuto;
    }
    protected void useStandardAutomataConnector(Automaton biggerPropertyAutomaton,Automaton smallerPropertyAutomaton,Transition transition) {
        Map stateMapper=getDisjointUnion(biggerPropertyAutomaton,smallerPropertyAutomaton);

        State initialState=transition.start();
	    State finalState=transition.end();

	    State oldStartOfSmaller=stateMapper.get(smallerPropertyAutomaton.initials().iterator().next());
	    State oldFinalOfSmaller=stateMapper.get(smallerPropertyAutomaton.terminals().iterator().next());

	    try {
	    	biggerPropertyAutomaton.addTransition(new Transition(initialState,null,oldStartOfSmaller));
	        biggerPropertyAutomaton.addTransition(new Transition(oldFinalOfSmaller,null,finalState));
	    }
	    catch (NoSuchStateException e) {
	    	throw new IllegalArgumentException("Could not build the Complete Automata of non-Simple Properties");
	    }
    }
    protected void automataConnector(Automaton biggerPropertyAutomaton,Automaton smallerPropertyAutomaton,Transition transition) {
    	useStandardAutomataConnector(biggerPropertyAutomaton,smallerPropertyAutomaton,transition);
    }
	protected Set deltaToState(Automaton smallerPropertyAutomaton,State state) {
        Set incommingTrans=new HashSet();
        for (Object transitionObject : smallerPropertyAutomaton.delta()) {
            Transition transition=(Transition)transitionObject;
            if (transition.end().equals(state))
                incommingTrans.add(transition);
        }
        return incommingTrans;
    }
    protected Graph buildPropertyOrdering(Collection simpleObjectPropertyInclusions,Collection complexObjectPropertyInclusions,Map> equivalentPropertiesMap) {
        Graph propertyDependencyGraph=new Graph();
        for (OWLObjectPropertyExpression[] inclusion : simpleObjectPropertyInclusions)
            if (!inclusion[0].equals(inclusion[1]) && !inclusion[0].equals(inclusion[1].getInverseProperty().getSimplified()) && (equivalentPropertiesMap.get(inclusion[0])==null || !equivalentPropertiesMap.get(inclusion[0]).contains(inclusion[1])))
                propertyDependencyGraph.addEdge(inclusion[0],inclusion[1]);
        for (OWLAxioms.ComplexObjectPropertyInclusion inclusion : complexObjectPropertyInclusions) {
            OWLObjectPropertyExpression owlSuperProperty=inclusion.m_superObjectProperty;
            OWLObjectPropertyExpression owlSubPropertyInChain=null;
            OWLObjectPropertyExpression[] owlSubProperties=inclusion.m_subObjectProperties;
            if (owlSubProperties.length!=2 && owlSuperProperty.equals(owlSubProperties[0]) && owlSuperProperty.equals(owlSubProperties[owlSubProperties.length-1]))
                throw new IllegalArgumentException("The given property hierarchy is not regular.");

            for (int i=0;i0 && i propertyDependencyGraph,Map> equivalentPropertiesMap) {
        Graph regularityCheckGraph=propertyDependencyGraph.clone();
        Graph regularityCheckGraphTemp;

        boolean trimmed=false;
        do {
            trimmed=false;
            regularityCheckGraphTemp=regularityCheckGraph.clone();
            for (OWLObjectPropertyExpression prop : regularityCheckGraphTemp.getElements()) {
                for (OWLObjectPropertyExpression succProp : regularityCheckGraphTemp.getSuccessors(prop)) {
                    if (equivalentPropertiesMap.containsKey(prop) && equivalentPropertiesMap.get(prop).contains(succProp)) {
                        for (OWLObjectPropertyExpression succPropSucc : regularityCheckGraphTemp.getSuccessors(succProp)) {
                            if (!prop.equals(succPropSucc))
                                regularityCheckGraph.addEdge(prop,succPropSucc);
                        }
                        trimmed=true;
                        regularityCheckGraph.getSuccessors(prop).remove(succProp);
                    }
                }
            }
        } while (trimmed);

        regularityCheckGraph.transitivelyClose();

        for (OWLObjectPropertyExpression prop : regularityCheckGraph.getElements()) {
            Set successors=regularityCheckGraph.getSuccessors(prop);
            if (successors.contains(prop) || successors.contains(prop.getInverseProperty().getSimplified()))
                throw new IllegalArgumentException("The given property hierarchy is not regular.\nThere is a cyclic dependency involving property "+prop);
        }
    }
    protected Map buildIndividualAutomata(Graph complexPropertiesDependencyGraph,Collection simpleObjectPropertyInclusions,Collection complexObjectPropertyInclusions,Map> equivalentPropertiesMap,Set transitiveProperties) {
        Map automataMap=new HashMap();
        for (OWLAxioms.ComplexObjectPropertyInclusion inclusion : complexObjectPropertyInclusions) {
            OWLObjectPropertyExpression[] subObjectProperties=inclusion.m_subObjectProperties;
            OWLObjectPropertyExpression superObjectProperty=inclusion.m_superObjectProperty;
            Automaton automaton=null;
            State initialState=null;
            State finalState=null;
            if (!automataMap.containsKey(superObjectProperty)) {
                automaton=new Automaton();
                initialState=automaton.addState(true,false);
                finalState=automaton.addState(false,true);
                try {
                    automaton.addTransition(new Transition(initialState,superObjectProperty,finalState));
                }
                catch (NoSuchStateException e) {
                    throw new IllegalArgumentException("Could not create automaton");
                }
            }
            else {
                automaton=automataMap.get(superObjectProperty);
                initialState=(State)automaton.initials().iterator().next();
                finalState=(State)automaton.terminals().iterator().next();
            }
            // RR->R
            if (subObjectProperties.length==2 && subObjectProperties[0].equals(superObjectProperty) && subObjectProperties[1].equals(superObjectProperty)) {
                try {
                    automaton.addTransition(new Transition(finalState,null,initialState));
                    transitiveProperties.add(superObjectProperty);
                }
                catch (NoSuchStateException e) {
                    throw new IllegalArgumentException("Could not create automaton");
                }
            }
            // R S2...Sn->R
            else if (subObjectProperties[0].equals(superObjectProperty)) {
                State fromState=finalState;
                OWLObjectPropertyExpression transitionLabel;
                for (int i=1;iR
            else if (subObjectProperties[subObjectProperties.length-1].equals(superObjectProperty)) {
                State fromState=initialState;
                OWLObjectPropertyExpression transitionLabel;
                for (int i=0;iR
            else {
                State fromState=initialState;
                OWLObjectPropertyExpression transitionLabel;
                for (int i=0;i getDisjointUnion(Automaton automaton1,Automaton automaton2) {
        Map stateMapperUnionInverse=new HashMap();
        for (Object stateObject : automaton2.states())
            stateMapperUnionInverse.put((State)stateObject,automaton1.addState(false,false));

        for (Object transitionObject : automaton2.delta()) {
            Transition transition=(Transition)transitionObject;
            try {
                automaton1.addTransition(new Transition(stateMapperUnionInverse.get(transition.start()),transition.label(),stateMapperUnionInverse.get(transition.end())));
            }
            catch (NoSuchStateException x) {
                throw new IllegalArgumentException("Could not create disjoint union of automata");
            }
        }
        return stateMapperUnionInverse;
    }
    protected Automaton getMirroredCopy(Automaton automaton) {
        Automaton mirroredCopy=new Automaton();
        Map map=new HashMap();
        for (Object stateObject : automaton.states()) {
            State state=(State)stateObject;
            map.put(state,mirroredCopy.addState(state.isTerminal(),state.isInitial()));
        }
        for (Object transitionObject : automaton.delta()) {
            Transition transition=(Transition)transitionObject;
            try {
                if (transition.label() instanceof OWLObjectPropertyExpression)
                    mirroredCopy.addTransition(new Transition(map.get(transition.end()),((OWLObjectPropertyExpression)transition.label()).getInverseProperty().getSimplified(),map.get(transition.start())));
                else
                    mirroredCopy.addTransition(new Transition(map.get(transition.end()),transition.label(),map.get(transition.start())));
            }
            catch (NoSuchStateException x) {
            }
        }
        return mirroredCopy;
    }
    protected State addNewTransition(Automaton automaton,State fromState,OWLObjectPropertyExpression objectPropertyExpression) throws NoSuchStateException {
        OWLObjectPropertyExpression propertyOfChain=objectPropertyExpression;
        State toState=automaton.addState(false,false);
        automaton.addTransition(new Transition(fromState,propertyOfChain,toState));
        return toState;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy