org.semanticweb.elk.reasoner.saturation.properties.SaturatedPropertyChain Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of elk-reasoner Show documentation
Show all versions of elk-reasoner Show documentation
The core ELK Reasoner package
/*
* #%L
* elk-reasoner
*
* $Id$
* $HeadURL$
* %%
* Copyright (C) 2011 Department of Computer Science, University of Oxford
* %%
* 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.
* #L%
*/
package org.semanticweb.elk.reasoner.saturation.properties;
import java.io.IOException;
import java.io.Writer;
import java.util.Collections;
import java.util.Set;
import org.semanticweb.elk.reasoner.indexing.model.IndexedClassExpression;
import org.semanticweb.elk.reasoner.indexing.model.IndexedComplexPropertyChain;
import org.semanticweb.elk.reasoner.indexing.model.IndexedObjectProperty;
import org.semanticweb.elk.reasoner.indexing.model.IndexedPropertyChain;
import org.semanticweb.elk.util.collections.AbstractHashMultimap;
import org.semanticweb.elk.util.collections.Multimap;
import org.semanticweb.elk.util.collections.Operations;
/**
*
* This object is used for fast retrieval of property inclusions and
* compositions which are needed during saturation of class expressions.
*
* @author Frantisek Simancik
* @author "Yevgeny Kazakov"
*
*/
public class SaturatedPropertyChain {
/**
* the {@code IndexedPropertyChain} for which this saturation is computed
*/
final IndexedPropertyChain root;
/**
* the {@code IndexedObjectProperty}s which are subsumed by {@link #root}
*/
Set derivedSubProperties;
/**
* the {@code IndexedPropertyChain}s which are subsumed by {@link #root}
*/
Set derivedSubProperyChains;
/**
* {@code true} if {@link #derivedSubProperties} and
* {@link #derivedSubProperyChains} are not {@code null} and fully computed
*/
volatile boolean derivedSubPropertiesComputed = false;
/**
* the {@code IndexedClassExpression}s that are ranges of the
* {@code IndexedObjectProperty}s that subsume {@link #root}
*/
Set derivedRanges;
/**
* {@code true} if {@link #derivedRanges} is not {@code null} and fully
* computed
*/
volatile boolean derivedRangesComputed = false;
/**
* a multimap T -> {S} such that both S and ObjectPropertyChain(S, T) imply
* {@link #root}
*/
Multimap leftSubComposableSubPropertiesByRightProperties;
/**
* {@code true} if {@link #leftSubComposableSubPropertiesByRightProperties}
* is not {@code null} and was fully computed
*/
volatile boolean leftSubComposableSubPropertiesByRightPropertiesComputed = false;
/**
* A {@link Multimap} from R to S such that ObjectPropertyChain(R, root) is
* a subrole of S
*/
AbstractHashMultimap nonRedundantCompositionsByLeftSubProperty;
/**
* A {@link Multimap} from R to S such that ObjectPropertyChain(R, root) is
* a subrole of S, which is considered to be redundant
*/
AbstractHashMultimap redundantCompositionsByLeftSubProperty;
/**
* A {@link Multimap} from R to S such that ObjectPropertyChain(root, R) is
* a subrole of S
*/
AbstractHashMultimap nonRedundantCompositionsByRightSubProperty;
/**
* A {@link Multimap} from R to S such that ObjectPropertyChain(root, R) is
* a subrole of S, which is considered to be redundant
*/
AbstractHashMultimap redundantCompositionsByRightSubProperty;
public SaturatedPropertyChain(IndexedPropertyChain ipc) {
this.root = ipc;
}
/**
* Clear all derived information for this {@link SaturatedPropertyChain}
*/
public void clear() {
derivedSubProperties = null;
derivedSubProperyChains = null;
derivedSubPropertiesComputed = false;
derivedRanges = null;
derivedRangesComputed = false;
leftSubComposableSubPropertiesByRightProperties = null;
leftSubComposableSubPropertiesByRightPropertiesComputed = false;
nonRedundantCompositionsByLeftSubProperty = null;
redundantCompositionsByLeftSubProperty = null;
nonRedundantCompositionsByRightSubProperty = null;
redundantCompositionsByRightSubProperty = null;
}
/**
* @return {@code true} if there is no derived information in this
* {@link SaturatedPropertyChain}, that is, its state is the same as
* after applying {@link #clear()}
*/
public boolean isClear() {
return derivedSubProperties == null && derivedSubProperyChains == null
&& leftSubComposableSubPropertiesByRightProperties == null
&& nonRedundantCompositionsByLeftSubProperty == null
&& redundantCompositionsByLeftSubProperty == null
&& nonRedundantCompositionsByRightSubProperty == null
&& redundantCompositionsByRightSubProperty == null;
}
/**
* @return All sub-{@link IndexedObjectProperty} of root including root, if
* it is an {@link IndexedObjectProperty} itself.
*/
public Set getSubProperties() {
if (derivedSubProperties != null)
return derivedSubProperties;
// else
if (root instanceof IndexedObjectProperty)
return Collections
. singleton((IndexedObjectProperty) root);
// else
return Collections.emptySet();
}
/**
* @return All sub-{@link IndexedPropertyChain} of root including root
* itself.
*/
public Set getSubPropertyChains() {
return derivedSubProperyChains == null ? Collections
. singleton(root)
: derivedSubProperyChains;
}
/**
* @return All ranges of super-{@link IndexedObjectProperty} of root.
*/
public Set getRanges() {
if (derivedRanges == null)
return Collections.emptySet();
// else
return derivedRanges;
}
/**
* @return A {@link Multimap} from R to S such that ObjectPropertyChain(R,
* root) is a subrole of S, non-redundant ones
*/
public Multimap getNonRedundantCompositionsByLeftSubProperty() {
return nonRedundantCompositionsByLeftSubProperty == null ? Operations
. emptyMultimap()
: nonRedundantCompositionsByLeftSubProperty;
}
/**
* @return A {@link Multimap} from R to S such that ObjectPropertyChain(R,
* root) is a subrole of S, redundant ones
*/
public Multimap getRedundantCompositionsByLeftSubProperty() {
return redundantCompositionsByLeftSubProperty == null ? Operations
. emptyMultimap()
: redundantCompositionsByLeftSubProperty;
}
/**
* @return A {@link Multimap} from R to S such that
* ObjectPropertyChain(root, R) is a subrole of S, non-redundant ones
*/
public Multimap getNonRedundantCompositionsByRightSubProperty() {
return nonRedundantCompositionsByRightSubProperty == null ? Operations
. emptyMultimap()
: nonRedundantCompositionsByRightSubProperty;
}
/**
* @return A {@link Multimap} from R to S such that
* ObjectPropertyChain(root, R) is a subrole of S, including the redundant ones
*/
public Multimap getRedundantCompositionsByRightSubProperty() {
return redundantCompositionsByRightSubProperty == null ? Operations
. emptyMultimap()
: redundantCompositionsByRightSubProperty;
}
/* Functions that modify the saturation */
/**
* Prints differences with other {@link SaturatedPropertyChain}
*
* @param other
* the {@link SaturatedPropertyChain} with which to compare this
* {@link SaturatedPropertyChain}
* @param writer
* the {@link Writer} using which the differences are written
* @throws IOException
* if I/O error happens
*/
public void dumpDiff(SaturatedPropertyChain other, Writer writer)
throws IOException {
// comparing roots
if (this.root != other.root)
writer.append("this root: " + root + "; other root: " + other.root
+ "\n");
// comparing derived sub-properties
Operations.dumpDiff(this.getSubPropertyChains(),
other.getSubPropertyChains(), writer, root
+ ": this sub-property not in other: ");
Operations.dumpDiff(other.getSubPropertyChains(),
this.getSubPropertyChains(), writer, root
+ ": other sub-property not in this: ");
// comparing derived compositions
Operations.dumpDiff(this.getNonRedundantCompositionsByLeftSubProperty(),
other.getNonRedundantCompositionsByLeftSubProperty(), writer, root
+ ": this non-redundant left composition not in other: ");
Operations.dumpDiff(this.getRedundantCompositionsByLeftSubProperty(),
other.getRedundantCompositionsByLeftSubProperty(), writer, root
+ ": this redundant left composition not in other: ");
Operations.dumpDiff(other.getNonRedundantCompositionsByLeftSubProperty(),
this.getNonRedundantCompositionsByLeftSubProperty(), writer, root
+ ": other non-redundant left composition not in this: ");
Operations.dumpDiff(other.getRedundantCompositionsByLeftSubProperty(),
this.getRedundantCompositionsByLeftSubProperty(), writer, root
+ ": other redundant left composition not in this: ");
Operations.dumpDiff(this.getNonRedundantCompositionsByRightSubProperty(),
other.getNonRedundantCompositionsByRightSubProperty(), writer, root
+ ": this non-redundant right composition not in other: ");
Operations.dumpDiff(this.getRedundantCompositionsByRightSubProperty(),
other.getRedundantCompositionsByRightSubProperty(), writer, root
+ ": this redundant right composition not in other: ");
Operations.dumpDiff(other.getNonRedundantCompositionsByRightSubProperty(),
this.getNonRedundantCompositionsByRightSubProperty(), writer, root
+ ": other non-redundant right composition not in this: ");
Operations.dumpDiff(other.getRedundantCompositionsByRightSubProperty(),
this.getRedundantCompositionsByRightSubProperty(), writer, root
+ ": other redundant right composition not in this: ");
}
}