package uk.ac.manchester.cs.jfact.kernel; /* This file is part of the JFact DL reasoner Copyright 2011-2013 by Ignazio Palmisano, Dmitry Tsarkov, University of Manchester This library 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 2.1 of the License, or (at your option) any later version. This library 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 this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*/ import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.semanticweb.owlapi.model.IRI; import conformance.Original; import conformance.PortedFrom; /** classifiable entry */ @PortedFrom(file = "taxNamEntry.h", name = "ClassifiableEntry") public class ClassifiableEntry extends NamedEntry { private static final long serialVersionUID = 11000L; /** link to taxonomy entry for current entry */ @PortedFrom(file = "taxNamEntry.h", name = "taxVertex") protected TaxonomyVertex taxVertex = null; /** * links to 'told subsumers' (entries that are direct super-entries for * current) */ @PortedFrom(file = "taxNamEntry.h", name = "toldSubsumers") protected final Set<ClassifiableEntry> toldSubsumers = new LinkedHashSet<ClassifiableEntry>(); /** * pointer to synonym (entry which contains whole information the same as * current) */ @PortedFrom(file = "taxNamEntry.h", name = "pSynonym") protected ClassifiableEntry pSynonym = null; /** index as a vertex in the SubsumptionMap */ @PortedFrom(file = "taxNamEntry.h", name = "Index") protected int index = 0; protected ClassifiableEntry(IRI name) { super(name); } /** @return is current entry classified */ @PortedFrom(file = "taxNamEntry.h", name = "isClassified") public boolean isClassified() { return taxVertex != null; } /** * set up given entry * * @param vertex * vertex */ @PortedFrom(file = "taxNamEntry.h", name = "setTaxVertex") public void setTaxVertex(TaxonomyVertex vertex) { taxVertex = vertex; } /** @return taxonomy vertex of the entry */ @PortedFrom(file = "taxNamEntry.h", name = "getTaxVertex") public TaxonomyVertex getTaxVertex() { return taxVertex; } @Original private boolean completelyDefined; // completely defined interface /** @return a Completely Defined flag */ @Original public boolean isCompletelyDefined() { return completelyDefined; } /** * @param action * action */ @Original public void setCompletelyDefined(boolean action) { completelyDefined = action; } @Original private boolean nonClassifiable; /** @return non classifiable? */ @Original public boolean isNonClassifiable() { return nonClassifiable; } /** * @param action * action */ @Original public void setNonClassifiable(boolean action) { nonClassifiable = action; } /** @return told subsumers */ @PortedFrom(file = "taxNamEntry.h", name = "told_begin") public Collection<ClassifiableEntry> getToldSubsumers() { return toldSubsumers; } /** @return whether entry ihas any TS */ @PortedFrom(file = "taxNamEntry.h", name = "hasToldSubsumers") public boolean hasToldSubsumers() { return !toldSubsumers.isEmpty(); } /** * add told subsumer of entry (duplications possible) * * @param parent * parent */ @PortedFrom(file = "taxNamEntry.h", name = "addParent") public void addParent(ClassifiableEntry parent) { toldSubsumers.add(parent); } /** * add all parents (with duplicates) from the range to current node * * @param entries * entries */ @PortedFrom(file = "taxNamEntry.h", name = "addParents") public void addParents(Collection<ClassifiableEntry> entries) { for (ClassifiableEntry c : entries) { addParentIfNew(c); } } // index interface /** get the index value */ @Override @PortedFrom(file = "taxNamEntry.h", name = "getIndex") public int getIndex() { return index; } /** set the index value */ @Override @PortedFrom(file = "taxNamEntry.h", name = "setIndex") public void setIndex(int ind) { index = ind; } // synonym interface /** @return if current entry is a synonym */ @PortedFrom(file = "taxNamEntry.h", name = "isSynonym") public boolean isSynonym() { return pSynonym != null; } /** @return synonym of current entry */ @PortedFrom(file = "taxNamEntry.h", name = "getSynonym") public ClassifiableEntry getSynonym() { return pSynonym; } /** make sure that synonym's representative is not a synonym itself */ @PortedFrom(file = "taxNamEntry.h", name = "canonicaliseSynonym") public void canonicaliseSynonym() { assert isSynonym(); if (isSynonym()) { pSynonym = resolveSynonym(pSynonym); } } /** * add entry's synonym * * @param syn * syn */ @PortedFrom(file = "taxNamEntry.h", name = "setSynonym") public void setSynonym(ClassifiableEntry syn) { // do it only once assert pSynonym == null; // check there are no cycles Set<ClassifiableEntry> set = new HashSet<ClassifiableEntry>(); set.add(this); ClassifiableEntry runner = syn; while (runner.isSynonym() && !set.contains(runner.pSynonym)) { set.add(runner.pSynonym); runner = runner.pSynonym; } if (!set.contains(runner.pSynonym)) { // then adding this synonym would cause a loop pSynonym = syn; canonicaliseSynonym(); } } /** if two synonyms are in 'told' list, merge them */ @PortedFrom(file = "taxNamEntry.h", name = "removeSynonymsFromParents") public void removeSynonymsFromParents() { List<ClassifiableEntry> toKeep = new ArrayList<ClassifiableEntry>(); for (ClassifiableEntry c : toldSubsumers) { if (this != resolveSynonym(c)) { toKeep.add(c); } } toldSubsumers.clear(); toldSubsumers.addAll(toKeep); } /** * @param p * p * @param <T> * expression type * @return resolved synonym */ @SuppressWarnings("unchecked") @PortedFrom(file = "taxNamEntry.h", name = "resolveSynonym") public static <T extends ClassifiableEntry> T resolveSynonym(T p) { if (p == null) { return null; } if (p.isSynonym()) { return resolveSynonym((T) p.pSynonym); } return p; } /** * @param parent * parent */ @PortedFrom(file = "taxNamEntry.h", name = "addParentIfNew") public void addParentIfNew(ClassifiableEntry parent) { // resolve synonyms parent = resolveSynonym(parent); // node can not be its own parent if (parent == this) { return; } toldSubsumers.add(parent); } }