package org.jactr.modules.pm.common.symbol; /* * default logging */ import java.util.Collection; import java.util.Map; import java.util.TreeMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.commonreality.modalities.aural.DefaultAuralPropertyHandler; import org.commonreality.modalities.aural.IAuralPropertyHandler; import org.commonreality.modalities.visual.DefaultVisualPropertyHandler; import org.commonreality.modalities.visual.IVisualPropertyHandler; import org.commonreality.object.IAfferentObject; import org.jactr.core.chunk.ChunkActivationComparator; import org.jactr.core.chunk.IChunk; import org.jactr.core.chunktype.IChunkType; import org.jactr.core.module.declarative.IDeclarativeModule; import org.jactr.core.module.declarative.search.filter.AcceptAllFilter; import org.jactr.core.production.request.ChunkTypeRequest; import org.jactr.core.slot.DefaultConditionalSlot; import org.jactr.core.slot.IConditionalSlot; import org.jactr.core.slot.IMutableSlot; import org.jactr.modules.pm.IPerceptualModule; public class DefaultChunkSymbolGrounder implements ISymbolGrounder { /** * Logger definition */ static private final transient Log LOGGER = LogFactory .getLog(DefaultChunkSymbolGrounder.class); static private final String PERCEPTUAL_SYMBOL_CHUNKTYPE = "perceptual-symbol"; static private final String TOKEN_SLOT = "token"; private IVisualPropertyHandler _visualPropertyHandler = new DefaultVisualPropertyHandler(); private IAuralPropertyHandler _auralPropertyHandler = new DefaultAuralPropertyHandler(); private Map<String, IChunk> _tokenToConcept = new TreeMap<String, IChunk>(); private IChunkType _symbolChunkType; private ChunkActivationComparator _activationSorter = new ChunkActivationComparator(); public Object getSymbolForPercept(IAfferentObject percept, IPerceptualModule perceivingModule, IDeclarativeModule declarativeModule) { return getSymbolForString(getToken(percept), declarativeModule); } public Object getSymbolForString(String symbolString, IDeclarativeModule declarativeModule) { IChunk conceptSymbol = getConcept(symbolString); /* * try to find it in DM */ if (conceptSymbol == null) try { conceptSymbol = findConcept(symbolString, declarativeModule); if (conceptSymbol != null) addConcept(symbolString, conceptSymbol); } catch (Exception e) { LOGGER.error(String .format("Failed to search DM for existing grounded symbol %s", symbolString), e); } if (conceptSymbol == null) try { conceptSymbol = createConcept(symbolString, declarativeModule); conceptSymbol = encodeConcept(conceptSymbol, declarativeModule); addConcept(symbolString, conceptSymbol); } catch (Exception e) { LOGGER .error( String .format( "Failed to create and encode grounded symbol %s. Returning string symbol instead.", symbolString), e); return symbolString; } return conceptSymbol; } private IChunk getConcept(String symbolName) { IChunk symbol = _tokenToConcept.get(symbolName); return symbol; } private void addConcept(String symbolName, IChunk symbolChunk) { _tokenToConcept.put(symbolName, symbolChunk); } private IChunk findConcept(String symbol, IDeclarativeModule declarativeModule) throws Exception { ChunkTypeRequest request = new ChunkTypeRequest( getSymbolChunkType(declarativeModule)); request.addSlot(new DefaultConditionalSlot(TOKEN_SLOT, IConditionalSlot.EQUALS, symbol)); Collection<IChunk> candidates = declarativeModule.findExactMatches(request, _activationSorter, new AcceptAllFilter()).get(); if (candidates.size() == 0) { if (LOGGER.isDebugEnabled()) LOGGER.debug(String.format("Found no existing symbols with token=%s", symbol)); return null; } else { if (LOGGER.isDebugEnabled()) LOGGER.debug(String.format("Found %d existing symbols with token=%s", candidates.size(), symbol)); return candidates.iterator().next(); } } private IChunk createConcept(String symbol, IDeclarativeModule declarativeModule) throws Exception { IChunk symbolChunk = declarativeModule.createChunk( getSymbolChunkType(declarativeModule), symbol).get(); ((IMutableSlot) symbolChunk.getSymbolicChunk().getSlot(TOKEN_SLOT)) .setValue(symbol); return symbolChunk; } private IChunk encodeConcept(IChunk symbolConcept, IDeclarativeModule declarativeModule) throws Exception { symbolConcept = declarativeModule.addChunk(symbolConcept).get(); return symbolConcept; } private IChunkType getSymbolChunkType(IDeclarativeModule declarativeModule) throws Exception { if (_symbolChunkType == null) _symbolChunkType = declarativeModule.getChunkType( PERCEPTUAL_SYMBOL_CHUNKTYPE).get(); return _symbolChunkType; } private String getToken(IAfferentObject percept) { String symbol = null; if (_visualPropertyHandler.hasModality(percept)) { if (_visualPropertyHandler.hasProperty(IVisualPropertyHandler.TEXT, percept)) symbol = _visualPropertyHandler.getText(percept); else if (_visualPropertyHandler.hasProperty(IVisualPropertyHandler.TOKEN, percept)) symbol = _visualPropertyHandler.getToken(percept); } else if (_auralPropertyHandler.hasModality(percept)) if (_auralPropertyHandler.hasProperty(IAuralPropertyHandler.TOKEN, percept)) symbol = _auralPropertyHandler.getToken(percept); /* * catch all */ if (symbol == null) { symbol = percept.getIdentifier().getName(); if (symbol == null) symbol = percept.getIdentifier().toString(); } return symbol; // toLower cases problems since jactr is case respecting } }