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

org.semanticweb.elk.reasoner.indexing.hierarchy.IndexedObjectUnionOf Maven / Gradle / Ivy

There is a newer version: 0.4.3
Show newest version
package org.semanticweb.elk.reasoner.indexing.hierarchy;

/*
 * #%L
 * ELK Reasoner
 * $Id:$
 * $HeadURL:$
 * %%
 * Copyright (C) 2011 - 2013 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%
 */

import java.util.List;
import java.util.Set;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.semanticweb.elk.owl.interfaces.ElkObjectUnionOf;
import org.semanticweb.elk.reasoner.indexing.visitors.IndexedClassExpressionVisitor;
import org.semanticweb.elk.reasoner.indexing.visitors.IndexedObjectUnionOfVisitor;
import org.semanticweb.elk.reasoner.saturation.BasicSaturationStateWriter;
import org.semanticweb.elk.reasoner.saturation.conclusions.NegativeSubsumer;
import org.semanticweb.elk.reasoner.saturation.context.Context;
import org.semanticweb.elk.reasoner.saturation.rules.ChainableRule;
import org.semanticweb.elk.reasoner.saturation.rules.DecompositionRuleApplicationVisitor;
import org.semanticweb.elk.reasoner.saturation.rules.RuleApplicationVisitor;
import org.semanticweb.elk.util.collections.ArrayHashSet;
import org.semanticweb.elk.util.collections.chains.Chain;
import org.semanticweb.elk.util.collections.chains.Matcher;
import org.semanticweb.elk.util.collections.chains.ModifiableLinkImpl;
import org.semanticweb.elk.util.collections.chains.ReferenceFactory;
import org.semanticweb.elk.util.collections.chains.SimpleTypeBasedMatcher;
import org.semanticweb.elk.util.logging.ElkMessage;

/**
 * Represents all occurrences of an {@link ElkObjectUnionOf} in an ontology.
 * 
 * @author "Yevgeny Kazakov"
 */
public class IndexedObjectUnionOf extends IndexedClassExpression {

	protected static final Logger LOGGER_ = Logger
			.getLogger(IndexedObjectUnionOf.class);

	private final Set disjuncts_;

	IndexedObjectUnionOf(List disjuncts) {
		this.disjuncts_ = new ArrayHashSet(2);
		for (IndexedClassExpression disjunct : disjuncts) {
			disjuncts_.add(disjunct);
		}
	}

	public Set getDisjuncts() {
		return disjuncts_;
	}

	public  O accept(IndexedObjectUnionOfVisitor visitor) {
		return visitor.visit(this);
	}

	@Override
	public  O accept(IndexedClassExpressionVisitor visitor) {
		return accept((IndexedObjectUnionOfVisitor) visitor);
	}

	@Override
	void updateOccurrenceNumbers(ModifiableOntologyIndex index, int increment,
			int positiveIncrement, int negativeIncrement) {

		if (negativeOccurrenceNo == 0 && negativeIncrement > 0) {
			// first negative occurrence of this expression
			for (IndexedClassExpression disjunct : disjuncts_)
				index.add(disjunct, new ThisCompositionRule(this));
		}

		if (positiveOccurrenceNo == 0 && positiveIncrement > 0) {
			// first positive occurrence of this expression
			if (LOGGER_.isEnabledFor(Level.WARN))
				LOGGER_.warn(new ElkMessage(
						"ELK does not support positive occurrences of ObjectUnionOf. Reasoning might be incomplete!",
						"reasoner.indexing.IndexedObjectUnionOf"));
		}

		positiveOccurrenceNo += positiveIncrement;
		negativeOccurrenceNo += negativeIncrement;

		checkOccurrenceNumbers();

		if (negativeOccurrenceNo == 0 && negativeIncrement < 0) {
			// no negative occurrences of this expression left
			for (IndexedClassExpression disjunct : disjuncts_)
				index.remove(disjunct, new ThisCompositionRule(this));
		}
	}

	@Override
	public void accept(DecompositionRuleApplicationVisitor visitor,
			Context context) {
		// disjunctions are not decomposed
	}

	@Override
	public String toStringStructural() {
		return "ObjectUnionOf(" + disjuncts_ + ')';
	}

	/**
	 * 
	 */
	public static class ThisCompositionRule extends
			ModifiableLinkImpl> implements
			ChainableRule {

		private static final String NAME = "ObjectUnionOf Introduction";

		/**
		 * All disjunctions containing the disjunct for which this rule is
		 * registered
		 */
		private final Set disjunctions_;

		private ThisCompositionRule(ChainableRule tail) {
			super(tail);
			disjunctions_ = new ArrayHashSet();

		}

		ThisCompositionRule(IndexedClassExpression disjunction) {
			this((ChainableRule) null);
			this.disjunctions_.add(disjunction);
		}

		@Override
		public String getName() {
			return NAME;
		}

		@Override
		public void accept(RuleApplicationVisitor visitor,
				BasicSaturationStateWriter writer, Context context) {
			visitor.visit(this, writer, context);
		}

		// TODO: hide this method
		public Set getDisjunctions() {
			return disjunctions_;
		}

		@Override
		public void apply(BasicSaturationStateWriter writer, Context context) {
			if (LOGGER_.isTraceEnabled()) {
				LOGGER_.trace("Applying " + NAME + " to " + context);
			}
			for (IndexedClassExpression disjunction : disjunctions_)
				writer.produce(context, new NegativeSubsumer(disjunction));
		}

		@Override
		public boolean addTo(Chain> ruleChain) {
			ThisCompositionRule rule = ruleChain.getCreate(MATCHER_, FACTORY_);
			return rule.disjunctions_.addAll(this.disjunctions_);
		}

		@Override
		public boolean removeFrom(Chain> ruleChain) {
			ThisCompositionRule rule = ruleChain.find(MATCHER_);
			boolean changed = false;
			if (rule != null) {
				changed = rule.disjunctions_.removeAll(this.disjunctions_);
				if (rule.isEmpty())
					ruleChain.remove(MATCHER_);
			}
			return changed;
		}

		/**
		 * @return {@code true} if this rule never does anything
		 */
		private boolean isEmpty() {
			return disjunctions_.isEmpty();
		}

		private static final Matcher, ThisCompositionRule> MATCHER_ = new SimpleTypeBasedMatcher, ThisCompositionRule>(
				ThisCompositionRule.class);

		private static final ReferenceFactory, ThisCompositionRule> FACTORY_ = new ReferenceFactory, ThisCompositionRule>() {
			@Override
			public ThisCompositionRule create(ChainableRule tail) {
				return new ThisCompositionRule(tail);
			}
		};

	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy