Java tutorial
/** * Copyright (C) 2001-3, Anthony Harrison anh23@pitt.edu 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.chunk.five; import java.lang.ref.SoftReference; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jactr.core.chunk.IChunk; import org.jactr.core.chunk.ISymbolicChunk; import org.jactr.core.chunk.basic.AbstractChunk; import org.jactr.core.chunk.event.ChunkEvent; import org.jactr.core.chunk.four.DefaultSubsymbolicChunk4; import org.jactr.core.event.ParameterEvent; import org.jactr.core.model.IModel; import org.jactr.core.module.declarative.five.IDeclarativeModule5; import org.jactr.core.production.condition.ChunkPattern; import org.jactr.core.production.request.ChunkTypeRequest; import org.jactr.core.runtime.ACTRRuntime; import org.jactr.core.slot.IConditionalSlot; import org.jactr.core.utils.parameter.ACTRParameterHandler; import org.jactr.core.utils.parameter.CollectionParameterHandler; import org.jactr.core.utils.parameter.ParameterHandler; import org.jactr.core.utils.parameter.SimilarityParameterHandler; /** * default implementation of ISubsymbolicChunk * * @author harrison * @created December 4, 2002 * @see org.jactr.core.chunk.ISubsymbolicChunk */ public class DefaultSubsymbolicChunk5 extends DefaultSubsymbolicChunk4 implements ISubsymbolicChunk5 { /** * Description of the Field * * @since */ public final static String SIMILARITY_ACTIVATION = "SimilarityActivation"; private static transient Log LOGGER = LogFactory.getLog(DefaultSubsymbolicChunk5.class.getName()); protected double _similarityActivation; protected Map<IChunk, Double> _similarityMap; /** * last pattern used to calculate similarity activation */ protected transient SoftReference<ChunkTypeRequest> _lastPattern = new SoftReference<ChunkTypeRequest>(null); public DefaultSubsymbolicChunk5(AbstractChunk parentChunk) { super(parentChunk); _similarityMap = new HashMap<IChunk, Double>(); setSimilarity(parentChunk, 1); } /** * Sets the Parameter attribute of the DefaultSubsymbolicChunk5 object * * @param key * The new Parameter value * @param value * The new Parameter value * @since */ @Override public void setParameter(String key, String value) { if (SIMILARITY_ACTIVATION.equalsIgnoreCase(key)) setSimilarityActivation(ParameterHandler.numberInstance().coerce(value).doubleValue()); else if (SIMILARITIES.equalsIgnoreCase(key)) { ACTRParameterHandler actrph = new ACTRParameterHandler(getParentChunk().getModel()); SimilarityParameterHandler sph = new SimilarityParameterHandler(actrph); CollectionParameterHandler<Object[]> aph = new CollectionParameterHandler<Object[]>(sph); for (Object[] similarity : aph.coerce(value)) setSimilarity((IChunk) similarity[0], (Double) similarity[1]); } } /** * Sets the Similarity attribute of the DefaultSubsymbolicChunk5 object * * @param c * The new Similarity value * @param value * The new Similarity value * @since */ public void setSimilarity(IChunk c, double value) { if (c == null) return; double oldValue = getSimilarity(c); if (oldValue == value) return; try { writeLock().lock(); _similarityMap.put(c, value); } finally { writeLock().unlock(); } if (_parentChunk.hasListeners()) _parentChunk.dispatch(new ChunkEvent(_parentChunk, c, oldValue, value)); } /** * Sets the SimilarityActivation attribute of the DefaultSubsymbolicChunk5 * object * * @param act * The new SimilarityActivation value * @since */ public void setSimilarityActivation(double act) { double oldSim = getSimilarityActivation(); try { writeLock().lock(); _similarityActivation = act; } finally { writeLock().unlock(); } if (_parentChunk.hasParameterListeners()) _parentChunk.dispatch( new ParameterEvent(this, ACTRRuntime.getRuntime().getClock(_parentChunk.getModel()).getTime(), SIMILARITY_ACTIVATION, oldSim, _similarityActivation)); } /** * this uses a JIT get parameter.. why? to set them in their respective * methods could grind the system to a halt since many of these values would * change many times during a model run. * * @param key * Description of Parameter * @return The Parameter value * @since */ @Override public String getParameter(String key) { if (SIMILARITIES.equalsIgnoreCase(key)) { ACTRParameterHandler actrph = new ACTRParameterHandler(getParentChunk().getModel()); SimilarityParameterHandler sph = new SimilarityParameterHandler(actrph); CollectionParameterHandler<Object[]> aph = new CollectionParameterHandler<Object[]>(sph); return aph.toString(getSimilarities(null)); } else if (SIMILARITY_ACTIVATION.equalsIgnoreCase(key)) return ParameterHandler.numberInstance().toString(getSimilarityActivation()); return super.getParameter(key); } /** * Gets the PossibleParameters attribute of the DefaultSubsymbolicChunk5 * object * * @return The PossibleParameters value * @since */ @Override public Collection<String> getPossibleParameters() { Collection<String> rtn = super.getPossibleParameters(); rtn.add(SIMILARITIES); rtn.add(SIMILARITY_ACTIVATION); return rtn; } /** * Gets the Similarity attribute of the DefaultSubsymbolicChunk5 object * * @param c * Description of Parameter * @return The Similarity value * @since */ public double getSimilarity(IChunk c) { if (c == null) return Double.NaN; try { readLock().lock(); Double rtn = _similarityMap.get(c); if (rtn == null) return Double.NaN; return rtn.doubleValue(); } finally { readLock().unlock(); } } /** * Gets the Similarities attribute of the DefaultSubsymbolicChunk5 object * * @return The Similarities value * @since */ public Collection<Object[]> getSimilarities(Collection<Object[]> container) { if (container == null) container = new ArrayList<Object[]>(); try { readLock().lock(); for (Map.Entry<IChunk, Double> entry : _similarityMap.entrySet()) container.add(new Object[] { entry.getKey(), entry.getValue() }); return container; } finally { readLock().unlock(); } } /** * Gets the SimilarityActivation attribute of the DefaultSubsymbolicChunk5 * object * * @return The SimilarityActivation value * @since */ public double getSimilarityActivation() { try { readLock().lock(); return _similarityActivation; } finally { readLock().unlock(); } } /* * @bug is source activation added to total activation?? No : the self * referential associative link will handle that for us */ /** * Gets the Activation attribute of the DefaultSubsymbolicChunk5 object * * @param p * Description of Parameter * @return The Activation value * @since */ public double getActivation(ChunkTypeRequest p) { // calculate the usual values.. refreshActivationValues(); boolean newPattern = p != _lastPattern.get(); if (newPattern) { setSimilarityActivation(computeSimilarityActivation(p)); _lastPattern = new SoftReference<ChunkTypeRequest>(p); } return getActivation() + getSimilarityActivation(); } /** * Description of the Method * * @since */ @Override public void dispose() { super.dispose(); try { writeLock().lock(); _lastPattern = null; _similarityMap.clear(); _similarityMap = null; } finally { writeLock().unlock(); } } /** * Description of the Method * * @param p * Description of Parameter * @since */ protected double computeSimilarityActivation(ChunkTypeRequest p) { if (p == null) return 0; IModel parentModel = _parentChunk.getModel(); IDeclarativeModule5 idm = (IDeclarativeModule5) parentModel.getModule(IDeclarativeModule5.class); if (idm == null) { if (LOGGER.isWarnEnabled()) LOGGER.warn("parent model does not support similarities"); return 0; } ISymbolicChunk sc = _parentChunk.getSymbolicChunk(); double maxSim = idm.getMaximumSimilarity(); double mmp = idm.getMismatchPenalty(); double simAct = 0; for (IConditionalSlot s : p.getConditionalSlots()) { String slotName = s.getName(); try { Object chunkSlotValue = sc.getSlot(slotName).getValue(); // System.out.println("Checking "+slotName+" "+s.getSlotValue()+" ?= // "+chunkSlotValue); double sim = 0; if (!s.matchesCondition(chunkSlotValue)) sim = idm.getSimilarity(s.getValue(), chunkSlotValue); else sim = maxSim; // System.out.println(_parentChunk+" sim :"+sim); simAct += (sim * mmp); } catch (Exception e) { simAct += idm.getMaximumDifference() * mmp; } } // System.out.println("S :"+_similarityActivation); if (LOGGER.isDebugEnabled()) LOGGER.debug("SimilarityActivation " + simAct); // System.out.println(_parentChunk+" S:"+_similarityActivation); return simAct; } }