![JAR search and dependency download from the Maven repository](/logo.png)
org.semanticweb.owlapi.util.OWLObjectPropertyManager Maven / Gradle / Ivy
The newest version!
/*
* 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.util;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import org.semanticweb.owlapi.model.AxiomType;
import org.semanticweb.owlapi.model.OWLEquivalentObjectPropertiesAxiom;
import org.semanticweb.owlapi.model.OWLInverseObjectPropertiesAxiom;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.model.OWLSubObjectPropertyOfAxiom;
import org.semanticweb.owlapi.model.OWLSubPropertyChainOfAxiom;
import org.semanticweb.owlapi.model.OWLSymmetricObjectPropertyAxiom;
import org.semanticweb.owlapi.model.OWLTransitiveObjectPropertyAxiom;
/**
* Author: Matthew Horridge
* The University Of Manchester
* Bio-Health Informatics Group
* Date: 25-Feb-2008
*/
public class OWLObjectPropertyManager {
static final class SetSizeComparator implements
Comparator>, Serializable {
private static final long serialVersionUID = 30406L;
@Override
public int compare(Set o1, Set o2) {
return o1.size() - o2.size();
}
}
private final OWLOntologyManager man;
private OWLOntology ontology;
private final Set properties = new HashSet();
private final Map> hierarchy;
private final Map> reflexiveTransitiveClosure;
private final Set compositeProperties;
private final Set nonSimpleProperties;
private final Map> partialOrdering;
private boolean compositeDirty;
private boolean hierarchyDirty;
private boolean reflexiveTransitiveClosureDirty;
private boolean simpleDirty;
private boolean partialOrderingDirty;
/**
* @param manager the ontology manager to use
* @param ont the ontology to use
*/
public OWLObjectPropertyManager(OWLOntologyManager manager, OWLOntology ont) {
man = manager;
hierarchy = new HashMap>();
reflexiveTransitiveClosure = new HashMap>();
compositeProperties = new HashSet();
nonSimpleProperties = new HashSet();
partialOrdering = new HashMap>();
setOntology(ont);
}
private void reset() {
compositeDirty = true;
hierarchyDirty = true;
reflexiveTransitiveClosureDirty = true;
simpleDirty = true;
partialOrderingDirty = true;
}
/**
* clear the object and its resources
*/
public void dispose() {
}
private void setOntology(OWLOntology ontology) {
this.ontology = ontology;
for(OWLOntology ont : man.getImportsClosure(ontology)) {
for(OWLObjectProperty prop : ont.getObjectPropertiesInSignature()) {
properties.add(prop);
properties.add(prop.getInverseProperty());
}
}
reset();
}
protected Set getOntologies() {
return man.getImportsClosure(ontology);
}
/**
* An object property expression PE is composite in Ax if Ax contains an axiom of the form
* SubObjectPropertyOf(SubObjectPropertyChain(PE1 ... PEn) PE) with n > 1, or
* SubObjectPropertyOf(SubObjectPropertyChain(PE1 ... PEn) INV(PE)) with n > 1, or
* TransitiveObjectProperty(PE), or
* TransitiveObjectProperty(INV(PE)).
*
* @param expression The object property expression to be tested
* @return true
if the object property is composite (according to the above definition)
* or false
if the object property is not composite.
*/
public boolean isComposite(OWLObjectPropertyExpression expression) {
return getCompositeProperties().contains(expression.getSimplified());
}
/**
* @return the property expressions
*/
public Set getCompositeProperties() {
if (compositeDirty) {
compositeProperties.clear();
compositeProperties.add(man.getOWLDataFactory().getOWLTopObjectProperty());
compositeProperties.add(man.getOWLDataFactory().getOWLBottomObjectProperty());
// We only depend on:
// 1) Property chain axioms
// 2) Transitive property axioms
for (OWLOntology ont : getOntologies()) {
for (OWLTransitiveObjectPropertyAxiom ax : ont.getAxioms(AxiomType.TRANSITIVE_OBJECT_PROPERTY)) {
markComposite(ax.getProperty());
for (OWLObjectPropertyExpression namedInv : ax.getProperty().getInverses(ontology)) {
markComposite(namedInv);
}
}
for (OWLSubPropertyChainOfAxiom ax : ont.getAxioms(AxiomType.SUB_PROPERTY_CHAIN_OF)) {
markComposite(ax.getSuperProperty());
for (OWLObjectPropertyExpression namedInv : ax.getSuperProperty().getInverses(ontology)) {
markComposite(namedInv);
}
}
}
compositeDirty = false;
}
return compositeProperties;
}
private void markComposite(OWLObjectPropertyExpression prop) {
compositeProperties.add(prop.getSimplified());
compositeProperties.add(prop.getInverseProperty().getSimplified());
}
/** The object property hierarchy relation -> is the smallest relation on
* object property expressions for which the following conditions hold (A ->
* B means that -> holds for A and B): if Ax contains an axiom
* SubObjectPropertyOf(PE1 PE2), then PE1 -> PE2 holds; and if Ax contains
* an axiom EquivalentObjectProperties(PE1 PE2), then PE1 -> PE2 and PE2 ->
* PE1 hold; and if Ax contains an axiom InverseObjectProperties(PE1 PE2),
* then PE1 -> INV(PE2) and INV(PE2) -> PE1 hold; and if Ax contains an
* axiom SymmetricObjectProperty(PE), then PE -> INV(PE) holds; and if PE1
* -> PE2 holds, then INV(PE1) -> INV(PE2) holds as well.
*
* @return A Map that maps sub properties to sets of super properties. */
public Map> getPropertyHierarchy() {
if (hierarchyDirty) {
Map> map = new HashMap>();
// Examine: SubObjectPropertyOf
// EquivalentObjectProperties
// InverseObjectProperties
// SymmetricObjectProperty
for (OWLOntology ont : getOntologies()) {
for (OWLSubObjectPropertyOfAxiom ax : ont.getAxioms(AxiomType.SUB_OBJECT_PROPERTY)) {
getKeyValue(ax.getSubProperty().getSimplified(), map).add(ax.getSuperProperty().getSimplified());
getKeyValue(ax.getSubProperty().getInverseProperty().getSimplified(),
map).add(ax.getSuperProperty().getInverseProperty().getSimplified());
}
for (OWLEquivalentObjectPropertiesAxiom ax : ont.getAxioms(AxiomType.EQUIVALENT_OBJECT_PROPERTIES)) {
// Do pairwise
for (OWLObjectPropertyExpression propA : ax.getProperties()) {
for (OWLObjectPropertyExpression propB : ax.getProperties()) {
if (!propA.equals(propB)) {
getKeyValue(propA.getSimplified(), map).add(propB.getSimplified());
getKeyValue(propB.getSimplified(), map).add(propA.getSimplified());
getKeyValue(propA.getInverseProperty().getSimplified(),
map).add(propB.getInverseProperty().getSimplified());
getKeyValue(propB.getInverseProperty().getSimplified(),
map).add(propA.getInverseProperty().getSimplified());
}
}
}
}
for (OWLInverseObjectPropertiesAxiom ax : ont.getAxioms(AxiomType.INVERSE_OBJECT_PROPERTIES)) {
getKeyValue(ax.getFirstProperty().getSimplified(),
map).add(ax.getSecondProperty().getInverseProperty().getSimplified());
getKeyValue(ax.getSecondProperty().getInverseProperty().getSimplified(), map).add(ax.getFirstProperty().getSimplified());
getKeyValue(ax.getFirstProperty().getInverseProperty().getSimplified(),
map).add(ax.getSecondProperty().getSimplified());
getKeyValue(ax.getSecondProperty().getSimplified(), map).add(ax.getFirstProperty().getInverseProperty().getSimplified());
}
for (OWLSymmetricObjectPropertyAxiom ax : ont.getAxioms(AxiomType.SYMMETRIC_OBJECT_PROPERTY)) {
getKeyValue(ax.getProperty().getSimplified(),
map).add(ax.getProperty().getInverseProperty().getSimplified());
getKeyValue(ax.getProperty().getInverseProperty().getSimplified(),
map).add(ax.getProperty().getSimplified());
}
}
hierarchy.clear();
hierarchy.putAll(map);
hierarchyDirty = false;
}
return hierarchy;
}
/**
* @return transitive reflexive closure
*/
public Map> getHierarchyReflexiveTransitiveClosure() {
if (reflexiveTransitiveClosureDirty) {
// Produce a map of the transitive reflexive closure of this
Map> rtcMap = new HashMap>();
Map> propertyHierarchy = getPropertyHierarchy();
for (OWLObjectPropertyExpression prop : getReferencedProperties()) {
Set processed = new HashSet();
Set rtc = new HashSet();
getReflexiveTransitiveClosure(prop, propertyHierarchy, rtc, processed);
rtcMap.put(prop, rtc);
}
reflexiveTransitiveClosure.clear();
reflexiveTransitiveClosure.putAll(rtcMap);
reflexiveTransitiveClosureDirty = false;
}
return reflexiveTransitiveClosure;
}
/**
* Tests to see if one property is a sub property of another property in the reflexive transitive
* closure of the property hierarchy
*
* @param sub The sub property
* @param sup The super property
* @return true
if sub is the sub-property of sup, otherwise false
*/
public boolean isSubPropertyOf(OWLObjectPropertyExpression sub, OWLObjectPropertyExpression sup) {
Set supers = getHierarchyReflexiveTransitiveClosure().get(sub);
if (supers == null) {
return false;
} else {
return supers.contains(sup);
}
}
/** The relation ->* is the reflexive-transitive closure of ->. An object
* property expression PE is simple in Ax if, for each object property
* expression PE' such that PE' ->* PE holds, PE' is not composite.
*
* @param expression
* The expression to be tested.
* @return true
if the object property expression is simple,
* otherwise false. */
public boolean isNonSimple(OWLObjectPropertyExpression expression) {
return getNonSimpleProperties().contains(expression.getSimplified());
}
/**
* @return non simple properties
*/
public Set getNonSimpleProperties() {
if (simpleDirty) {
nonSimpleProperties.clear();
Set props = getReferencedProperties();
Map> reflexiveTransitiveClosureMap = getHierarchyReflexiveTransitiveClosure();
for (OWLObjectPropertyExpression prop : getReferencedProperties()) {
if (isComposite(prop)) {
// Supers are not simple
Set rtc = reflexiveTransitiveClosureMap.get(prop);
props.removeAll(rtc);
nonSimpleProperties.add(prop);
nonSimpleProperties.addAll(rtc);
}
}
for (OWLObjectPropertyExpression prop : new ArrayList(nonSimpleProperties)) {
nonSimpleProperties.add(prop.getInverseProperty().getSimplified());
}
simpleDirty = false;
}
return nonSimpleProperties;
}
/**
* @return partial ordering
*/
public Map> getPropertyPartialOrdering() {
if (partialOrderingDirty) {
partialOrdering.clear();
Map> map = new HashMap>(getPropertyHierarchy());
for (OWLOntology ont : getOntologies()) {
for (OWLSubPropertyChainOfAxiom ax : ont.getAxioms(AxiomType.SUB_PROPERTY_CHAIN_OF)) {
for (OWLObjectPropertyExpression prop : ax.getPropertyChain()) {
Set sups = map.get(prop.getSimplified());
if (sups == null) {
sups = new HashSet();
map.put(prop, sups);
}
sups.add(ax.getSuperProperty().getSimplified());
Set supsInv = map.get(prop.getInverseProperty().getSimplified());
if (supsInv == null) {
supsInv = new HashSet();
map.put(prop.getInverseProperty().getSimplified(), supsInv);
}
supsInv.add(ax.getSuperProperty().getInverseProperty().getSimplified());
}
}
}
Map> ordering = new HashMap>();
for (OWLObjectPropertyExpression prop : getReferencedProperties()) {
Set processed = new HashSet();
Set rtc = new HashSet();
getReflexiveTransitiveClosure(prop, map, rtc, processed);
ordering.put(prop, rtc);
}
partialOrdering.putAll(ordering);
partialOrderingDirty = false;
}
return partialOrdering;
}
/**
* @param propA first property
* @param propB second property
* @return true if first property comes first in the default ordering
*/
public boolean isLessThan(OWLObjectPropertyExpression propA, OWLObjectPropertyExpression propB) {
Set props = getPropertyPartialOrdering().get(propA.getSimplified());
if (props == null) {
return false;
} else {
return props.contains(propB.getSimplified());
}
}
private Set getReferencedProperties() {
Set props = new HashSet();
for (OWLOntology ont : getOntologies()) {
for (OWLObjectPropertyExpression prop : ont.getObjectPropertiesInSignature()) {
props.add(prop.getSimplified());
}
}
return props;
}
/**
* @param ontologies ontologies to search
* @return sets of equivalent properties
*/
public static Collection> getEquivalentObjectProperties(Set ontologies) {
Set> result = new HashSet>();
Set processed = new HashSet();
Set properties = new HashSet();
for (OWLOntology ont : ontologies) {
properties.addAll(ont.getObjectPropertiesInSignature());
}
for (OWLObjectPropertyExpression prop : properties) {
if (processed.contains(prop)) {
continue;
}
tarjan(ontologies,
prop,
0,
new Stack(),
new HashMap(),
new HashMap(),
result,
processed,
new HashSet());
}
// Get maximal
List> equivs = new ArrayList>(result);
Collections.sort(equivs, new SetSizeComparator());
for (int i = 0; i < equivs.size(); i++) {
Set first = equivs.get(i);
for (int j = i; j < equivs.size(); j++) {
Set second = equivs.get(j);
if (second.size() > first.size() && second.containsAll(first)) {
equivs.remove(i);
break;
}
}
}
return equivs;
}
/**
* @return sets of equivalent properties
*/
public Collection> getEquivalentObjectProperties() {
return getEquivalentObjectProperties(getOntologies());
}
/**
* @param ontologies The ontologies
* @param prop the property
* @param index index
* @param stack stack
* @param indexMap index map
* @param lowlinkMap low link map
* @param result result
* @param processed processed
* @param stackProps stack entities
*/
@SuppressWarnings("boxing")
public static void tarjan(Set ontologies, OWLObjectPropertyExpression prop, int index,
Stack stack,
Map indexMap,
Map lowlinkMap,
Set> result,
Set processed,
Set stackProps) {
processed.add(prop);
indexMap.put(prop, index);
lowlinkMap.put(prop, index);
index = index + 1;
stack.push(prop);
stackProps.add(prop);
for (OWLOntology ont : ontologies) {
for (OWLSubObjectPropertyOfAxiom ax : ont.getObjectSubPropertyAxiomsForSubProperty(prop)) {
if (ax.getSubProperty().equals(prop)) {
OWLObjectPropertyExpression supProp = ax.getSuperProperty();
if (!indexMap.containsKey(supProp)) {
tarjan(ontologies, supProp, index, stack, indexMap, lowlinkMap, result, processed, stackProps);
lowlinkMap.put(prop, Math.min(lowlinkMap.get(prop), lowlinkMap.get(supProp)));
} else if (stackProps.contains(supProp)) {
lowlinkMap.put(prop, Math.min(lowlinkMap.get(prop), indexMap.get(supProp)));
}
}
}
}
if (lowlinkMap.get(prop).equals(indexMap.get(prop))) {
Set scc = new HashSet();
OWLObjectPropertyExpression propPrime;
while (true) {
propPrime = stack.pop();
stackProps.remove(propPrime);
scc.add(propPrime);
if (propPrime.equals(prop)) {
break;
}
}
if (scc.size() > 1) {
result.add(scc);
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Util methods
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private static void getReflexiveTransitiveClosure(OWLObjectPropertyExpression prop,
Map> map,
Set rtc,
Set processed) {
if (processed.contains(prop)) {
return;
}
rtc.add(prop);
processed.add(prop);
Set supers = map.get(prop);
if (supers == null) {
return;
}
for (OWLObjectPropertyExpression sup : supers) {
getReflexiveTransitiveClosure(sup, map, rtc, processed);
}
}
private static Set getKeyValue(OWLObjectPropertyExpression key,
Map> map) {
Set vals = map.get(key);
if (vals == null) {
vals = new HashSet(4);
map.put(key, vals);
}
return vals;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy