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

org.semanticweb.elk.reasoner.saturation.properties.SaturatedPropertyChain Maven / Gradle / Ivy

There is a newer version: 0.29.0
Show newest version
/*
 * #%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: ");
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy