/** * 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.utils.similarity; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.jactr.core.chunk.IChunk; import org.jactr.core.chunk.ISymbolicChunk; import org.jactr.core.chunk.five.ISubsymbolicChunk5; import org.jactr.core.slot.ISlot; /** * The DefaultSimilarityHandler handles basic similarity computations and * permits the attaching of custom handlers * * @author harrison * @created April 18, 2003 */ public class DefaultSimilarityHandler implements SimilarityHandler { /** * Description of the Field */ protected List<SimilarityHandler> _handlers; /** * Constructor for the DefaultSimilarityHandler object */ public DefaultSimilarityHandler() { _handlers = new ArrayList<SimilarityHandler>(); addHandler(this); } /** * Adds a feature to the Handler attribute of the DefaultSimilarityHandler * object * * @param sm * The feature to be added to the Handler attribute */ public void addHandler(SimilarityHandler sm) { _handlers.add(0, sm); } /** * Description of the Method * * @param sm * Description of the Parameter */ public void removeHandler(SimilarityHandler sm) { _handlers.remove(sm); } /** * Gets the similarity attribute of the DefaultSimilarityHandler object * * @param one * Description of the Parameter * @param two * Description of the Parameter * @param maxDiff * Description of the Parameter * @param maxSim * Description of the Parameter * @return The similarity value */ public double getSimilarity(Object one, Object two, double maxDiff, double maxSim) { for (SimilarityHandler sm : _handlers) if (sm.handles(one, two)) { // if the handler can do it, delegate double sim = sm.computeSimilarity(one, two, maxDiff, maxSim); return sim; } // otherwise return maxDiff return maxDiff; } /** * can this handler compute a similarity for these two chunks * * @param one * Description of the Parameter * @param two * Description of the Parameter * @return true if it can compute the sim */ public boolean handles(Object one, Object two) { return true; } /** * compute the similarty between one and two scaled to fit maxDiff and maxSim * * @param one * Description of the Parameter * @param two * Description of the Parameter * @param maxDiff * Description of the Parameter * @param maxSim * Description of the Parameter * @return maxSim if they are equal maxDiff if not */ public double computeSimilarity(Object one, Object two, double maxDiff, double maxSim) { if (!(one instanceof IChunk) && !(two instanceof IChunk)) { return maxDiff; } /* * both chunks must have ISubsymbolicChunk5 */ IChunk c1 = (IChunk) one; IChunk c2 = (IChunk) two; if (!(c1.getSubsymbolicChunk() instanceof ISubsymbolicChunk5) || !(c2.getSubsymbolicChunk() instanceof ISubsymbolicChunk5)) return maxDiff; double lastSim = ((ISubsymbolicChunk5) c1.getSubsymbolicChunk()) .getSimilarity(c2); if (!Double.isNaN(lastSim)) { return lastSim; } Collection<? extends ISlot> oneSlots = ((IChunk) one).getSymbolicChunk() .getSlots(); ISlot tmpSlot = null; ISymbolicChunk twoSC = ((IChunk) two).getSymbolicChunk(); double sim = maxSim; for (ISlot slot : oneSlots) { if ((tmpSlot = twoSC.getSlot(slot.getName())) != null) { if (!tmpSlot.equalValues(slot)) { sim = maxDiff; break; } } else { sim = maxDiff; } } setSimilarity((IChunk) one, (IChunk) two, sim); // the only way we get this far is if all is good.. return sim; } /** * Sets the similarity attribute of the DefaultSimilarityHandler class * * @param one * The new similarity value * @param two * The new similarity value * @param sim * The new similarity value */ public void setSimilarity(IChunk one, IChunk two, double sim) { Double similarity = new Double(sim); if (one.getSubsymbolicChunk() instanceof ISubsymbolicChunk5) ((ISubsymbolicChunk5) one.getSubsymbolicChunk()).setSimilarity(two, similarity); if (two.getSubsymbolicChunk() instanceof ISubsymbolicChunk5) ((ISubsymbolicChunk5) two.getSubsymbolicChunk()).setSimilarity(one, similarity); } }