/* * Created on Oct 12, 2006 Copyright (C) 2001-6, Anthony Harrison anh23@pitt.edu * (jactr.org) 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., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA */ package org.jactr.core.module.retrieval.six; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.Future; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jactr.core.buffer.IActivationBuffer; import org.jactr.core.chunk.ChunkActivationComparator; import org.jactr.core.chunk.IChunk; import org.jactr.core.event.ACTREventDispatcher; import org.jactr.core.module.AbstractModule; import org.jactr.core.module.declarative.IDeclarativeModule; import org.jactr.core.module.declarative.four.IDeclarativeModule4; import org.jactr.core.module.retrieval.IRetrievalModule; import org.jactr.core.module.retrieval.buffer.DefaultRetrievalBuffer6; import org.jactr.core.module.retrieval.event.IRetrievalModuleListener; import org.jactr.core.module.retrieval.event.RetrievalModuleEvent; import org.jactr.core.module.retrieval.four.IRetrievalModule4; import org.jactr.core.module.retrieval.time.DefaultRetrievalTimeEquation; import org.jactr.core.module.retrieval.time.IRetrievalTimeEquation; import org.jactr.core.production.request.ChunkTypeRequest; import org.jactr.core.utils.parameter.IParameterized; import org.jactr.core.utils.parameter.ParameterHandler; public class DefaultRetrievalModule6 extends AbstractModule implements IRetrievalModule4, IParameterized { /** * logger definition */ static private final Log LOGGER = LogFactory .getLog(DefaultRetrievalModule6.class); static public final String INDEXED_RETRIEVALS_ENABLED_PARAM = "EnableIndexedRetrievals"; private double _retrievalThreshold = Double.NEGATIVE_INFINITY; private double _latencyFactor = 1; private double _latencyExponent = 1; private boolean _indexedRetrievalsEnabled = false; private ACTREventDispatcher<IRetrievalModule, IRetrievalModuleListener> _eventDispatcher; private DefaultRetrievalBuffer6 _retrievalBuffer; private IRetrievalTimeEquation _retrievalTimeEquation; static final protected ChunkActivationComparator _activationSorter = new ChunkActivationComparator(); public DefaultRetrievalModule6() { super("retrieval"); _eventDispatcher = new ACTREventDispatcher<IRetrievalModule, IRetrievalModuleListener>(); _retrievalTimeEquation = new DefaultRetrievalTimeEquation(this); } @Override public void dispose() { super.dispose(); _eventDispatcher.clear(); _retrievalBuffer.dispose(); _retrievalTimeEquation = null; } protected @Override Collection<IActivationBuffer> createBuffers() { _retrievalBuffer = new DefaultRetrievalBuffer6(IActivationBuffer.RETRIEVAL, this); return Collections.singleton((IActivationBuffer) _retrievalBuffer); } public boolean isIndexedRetrievalEnabled() { return _indexedRetrievalsEnabled; } public void setIndexedRetrievalEnabled(boolean enabled) { _indexedRetrievalsEnabled = enabled; } public double getRetrievalThreshold() { return _retrievalThreshold; } private boolean isPartialMatchingEnabled(IDeclarativeModule dm) { if(dm instanceof IDeclarativeModule4) return ((IDeclarativeModule4)dm).isPartialMatchingEnabled(); return false; } protected IChunk retrieveChunkInternal(IDeclarativeModule dm, ChunkTypeRequest pattern) throws ExecutionException, InterruptedException { Future<Collection<IChunk>> fromDM = null; fireInitiated(pattern); if (isPartialMatchingEnabled(dm)) fromDM = dm.findPartialMatches(pattern, _activationSorter, getRetrievalThreshold(), true); else fromDM = dm.findExactMatches(pattern, _activationSorter, getRetrievalThreshold(), true); Collection<IChunk> results = fromDM.get(); IChunk retrievalResult = dm.getErrorChunk(); if (results.size() != 0) retrievalResult = results.iterator().next(); fireCompleted(pattern, retrievalResult); return retrievalResult; } public Future<IChunk> retrieveChunk(final ChunkTypeRequest chunkPattern) { return delayedFuture(new Callable<IChunk>() { public IChunk call() throws Exception { return retrieveChunkInternal(getModel().getDeclarativeModule(), chunkPattern); } }, getExecutor()); } public void setRetrievalThreshold(double threshold) { _retrievalThreshold = threshold; } protected void fireInitiated(ChunkTypeRequest pattern) { _eventDispatcher.fire(new RetrievalModuleEvent(this, pattern)); } protected void fireCompleted(ChunkTypeRequest pattern, IChunk chunk) { _eventDispatcher.fire(new RetrievalModuleEvent(this, pattern, chunk)); } public void addListener(IRetrievalModuleListener listener, Executor executor) { _eventDispatcher.addListener(listener, executor); } public void removeListener(IRetrievalModuleListener listener) { _eventDispatcher.removeListener(listener); } @Override public void initialize() { } public IRetrievalTimeEquation getRetrievalTimeEquation() { return _retrievalTimeEquation; } public double getLatencyExponent() { return _latencyExponent; } public double getLatencyFactor() { return _latencyFactor; } public void setLatencyExponent(double exp) { _latencyExponent = exp; } public void setLatencyFactor(double fact) { _latencyFactor = fact; } /** * @see org.jactr.core.utils.parameter.IParameterized#getParameter(java.lang.String) */ public String getParameter(String key) { if (RETRIEVAL_THRESHOLD.equalsIgnoreCase(key)) return "" + getRetrievalThreshold(); if (LATENCY_EXPONENT.equalsIgnoreCase(key)) return "" + getLatencyExponent(); if (LATENCY_FACTOR.equalsIgnoreCase(key)) return "" + getLatencyFactor(); if (INDEXED_RETRIEVALS_ENABLED_PARAM.equalsIgnoreCase(key)) return "" + isIndexedRetrievalEnabled(); return null; } /** * @see org.jactr.core.utils.parameter.IParameterized#getPossibleParameters() */ public Collection<String> getPossibleParameters() { ArrayList<String> rtn = new ArrayList<String>(); rtn.add(RETRIEVAL_THRESHOLD); rtn.add(LATENCY_EXPONENT); rtn.add(LATENCY_FACTOR); rtn.add(INDEXED_RETRIEVALS_ENABLED_PARAM); return rtn; } /** * @see org.jactr.core.utils.parameter.IParameterized#getSetableParameters() */ public Collection<String> getSetableParameters() { return getPossibleParameters(); } /** * @see org.jactr.core.utils.parameter.IParameterized#setParameter(java.lang.String, * java.lang.String) */ public void setParameter(String key, String value) { if (RETRIEVAL_THRESHOLD.equalsIgnoreCase(key)) setRetrievalThreshold(ParameterHandler.numberInstance().coerce(value) .doubleValue()); else if (LATENCY_EXPONENT.equalsIgnoreCase(key)) setLatencyExponent(ParameterHandler.numberInstance().coerce(value) .doubleValue()); else if (LATENCY_FACTOR.equalsIgnoreCase(key)) setLatencyFactor(ParameterHandler.numberInstance().coerce(value) .doubleValue()); else if (INDEXED_RETRIEVALS_ENABLED_PARAM.equalsIgnoreCase(key)) setIndexedRetrievalEnabled(ParameterHandler.booleanInstance().coerce( value).booleanValue()); else if (LOGGER.isWarnEnabled()) LOGGER.warn("No clue how to set " + key + " to " + value); } public void reset() { _retrievalBuffer.clear(); } }