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.io.Serializable; import java.util.ArrayList; import java.util.BitSet; import java.util.List; import uk.ac.manchester.cs.jfact.dep.DepSet; import uk.ac.manchester.cs.jfact.helpers.ArrayIntMap; import uk.ac.manchester.cs.jfact.helpers.Helper; import conformance.Original; import conformance.PortedFrom; /** List of concepts with dependencies */ @PortedFrom(file = "CWDArray.h", name = "CWDArray") public class CWDArray implements Serializable { private static final long serialVersionUID = 11000L; @Original private static final double distribution = 0.025; /** array of concepts together with dep-sets */ @PortedFrom(file = "CWDArray.h", name = "Base") private final List<ConceptWDep> base = new ArrayList<ConceptWDep>(); @Original private BitSet cache; @Original private final ArrayIntMap indexes = new ArrayIntMap(); @Original private boolean createCache = false; @Original private static final int cacheLimit = 1; @Original private int size = 0; /** init/clear label */ @PortedFrom(file = "CWDArray.h", name = "init") public void init() { base.clear(); cache = null; indexes.clear(); createCache = false; size = 0; } /** @return list of concepts */ @PortedFrom(file = "CWDArray.h", name = "begin") public List<ConceptWDep> getBase() { return base; } /** @return contained concept map */ @Original public ArrayIntMap getContainedConcepts() { return indexes; } /** * adds concept P to a label - to be called only from CGLabel * * @param p * p */ @Original protected void private_add(ConceptWDep p) { base.add(p); size++; if (cache != null) { cache.set(asPositive(p.getConcept())); } indexes.put(p.getConcept(), size - 1); int span = Math.max(asPositive(indexes.keySet(0)), indexes.keySet(indexes.size() - 1)); // create a cache only if the size is higher than a preset minimum and // there is at least an element in 20; caches with very dispersed // elements eat up too much memory createCache = size > cacheLimit && (double) size / (span + 1) > distribution; } /** * @param bp * bp * @return true if label contains BP (ignoring dep-set) */ @PortedFrom(file = "CWDArray.h", name = "contains") public boolean contains(int bp) { if (cache == null && createCache) { initCache(); } if (cache != null) { return cache.get(asPositive(bp)); } else { return indexes.containsKey(bp); } } @Original private void initCache() { cache = new BitSet(); for (int i = 0; i < indexes.size(); i++) { cache.set(asPositive(indexes.keySet(i))); } } @Original private int asPositive(int p) { return p >= 0 ? 2 * p : 1 - 2 * p; } /** * @param bp * bp * @return index of given bp */ @PortedFrom(file = "CWDArray.h", name = "index") public int index(int bp) { // check that the index actually exist: quicker if (cache != null && !cache.get(asPositive(bp))) { return -1; } return indexes.get(bp); } /** * @param bp * bp * @return depset for given bp */ @PortedFrom(file = "CWDArray.h", name = "get") public DepSet get(int bp) { // check that the index actually exist: quicker if (cache != null && !cache.get(asPositive(bp))) { return null; } int i = indexes.get(bp); if (i < 0) { return null; } return base.get(i).getDep(); } /** * @param bp * bp * @return concept with given bp */ @Original public ConceptWDep getConceptWithBP(int bp) { // check that the index actually exist: quicker if (cache != null && !cache.get(asPositive(bp))) { return null; } int i = indexes.get(bp); if (i < 0) { return null; } return base.get(i); } /** @return size of list */ @PortedFrom(file = "CWDArray.h", name = "size") public int size() { return size; } /** * @param label * label * @return true if this list is lesser or equal label */ @PortedFrom(file = "CWDArray.h", name = "<=") public boolean lesserequal(CWDArray label) { // use the cache on the label if there is one if (label.cache != null) { for (int i = 0; i < indexes.size(); i++) { if (!label.cache.get(asPositive(indexes.keySet(i)))) { return false; } } return true; } // checks the keys are in both maps return label.indexes.containsAll(indexes); } @Override public int hashCode() { return indexes.hashCode(); } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (this == obj) { return true; } if (obj instanceof CWDArray) { CWDArray obj2 = (CWDArray) obj; return indexes.equals(obj2.indexes); } return false; } /** * save label using given SS * * @return save level */ @PortedFrom(file = "CWDArray.h", name = "save") public int save() { return size; } /** * @param index * index * @param dep * dep * @return restorer for saved dep set */ @PortedFrom(file = "CWDArray.h", name = "updateDepSet") public Restorer updateDepSet(int index, DepSet dep) { if (dep.isEmpty()) { throw new IllegalArgumentException(); } Restorer ret = new UnMerge(this, base.get(index), index); base.get(index).addDep(dep); return ret; } /** * @param dep * dep * @return restorer for saved dep set */ @PortedFrom(file = "CWDArray.h", name = "updateDepSet") public List<Restorer> updateDepSet(DepSet dep) { if (dep.isEmpty()) { throw new IllegalArgumentException(); } List<Restorer> toReturn = new ArrayList<Restorer>(size); for (int i = 0; i < size; i++) { Restorer ret = new UnMerge(this, base.get(i), i); base.get(i).addDep(dep); toReturn.add(ret); } return toReturn; } /** * @param ss * ss * @param level * level */ @PortedFrom(file = "CWDArray.h", name = "restore") public void restore(int ss, int level) { for (int i = ss; i < size; i++) { int concept = base.get(i).getConcept(); indexes.remove(concept); if (cache != null) { cache.clear(asPositive(concept)); } } Helper.resize(base, ss); size = ss; } @Override public String toString() { StringBuilder o = new StringBuilder(); o.append(" ["); for (int i = 0; i < size; i++) { if (i != 0) { o.append(", "); } o.append(base.get(i)); } o.append(']'); return o.toString(); } }