/****************************************************************************** * * Copyright 2014 Paphus Solutions Inc. * * Licensed under the Eclipse Public License, Version 1.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ package org.botlibre.knowledge; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.botlibre.Bot; import org.botlibre.api.knowledge.Memory; import org.botlibre.api.knowledge.MemoryEventListener; import org.botlibre.api.knowledge.Network; import org.botlibre.api.knowledge.Vertex; /** * Defines a set of networks that make up a knowledge base. * Defines long term, short term and flash networks. * Basic implementation to allow subclasses to avoid defining some of the basic stuff, * Note this basic implementation is not persistent. */ public class BasicMemory implements Memory { /** Back reference to Bot instance. **/ protected Bot bot; protected List<Vertex> activeMemory; protected Network shortTermMemory; protected Network longTermMemory; protected List<MemoryEventListener> listeners; protected Map<String, String> properties; public BasicMemory() { this.activeMemory = new ArrayList<Vertex>(); this.listeners = new ArrayList<MemoryEventListener>(); this.properties = new HashMap<String, String>(); initMemory(); } public void initMemory() { this.longTermMemory = new BasicNetwork(); this.longTermMemory.setBot(getBot()); this.shortTermMemory = new BasicNetwork(this.longTermMemory); this.shortTermMemory.setBot(getBot()); } /** * Return the current connected database name. */ public String getMemoryName() { return "Basic"; } /** * Return the property setting. */ public String getProperty(String property) { return this.properties.get(property); } /** * Save the property setting. */ public String setProperty(String property, String value) { return this.properties.put(property, value); } /** * Remove the property setting. */ public String removeProperty(String property) { return this.properties.remove(property); } public Map<String, String> getProperties() { return properties; } public void setProperties(Map<String, String> properties) { this.properties = properties; } /** * Return Bot. */ public Bot getBot() { return bot; } /** * Set Bot. */ public void setBot(Bot bot) { this.bot = bot; if (this.shortTermMemory != null) { this.shortTermMemory.setBot(bot); } if (this.longTermMemory != null) { this.longTermMemory.setBot(bot); } } /** * Initialize any configurable settings from the properties. */ public void initialize(Map<String, Object> properties) { return; } /** * Load any properties and init. */ public void awake() { } public void loadProperties(String propertySet) { } public void clearProperties(String propertySet) { } /** * Active memory represents the last sensory state. */ public List<Vertex> getActiveMemory() { return activeMemory; } /** * Add the sensory data to the active memory. * Register the vertex in the short-term memory and return the registered version. */ public synchronized Vertex addActiveMemory(Vertex vertex) { Vertex activeVertex = getShortTermMemory().createVertex(vertex); getActiveMemory().add(activeVertex); for (MemoryEventListener listener : getListeners()) { listener.addActiveMemory(vertex); } notifyAll(); return activeVertex; } /** * Represents a non-committed transactional memory. * Helps to define a learn scope and local context. */ public Network getShortTermMemory() { return shortTermMemory; } /** * Return an isolated transactional memory. * Can be used by senses or sub-conscious thought for concurrent processing. */ public Network newMemory() { BasicNetwork memory = new BasicNetwork(getLongTermMemory()); memory.setBot(getBot()); return memory; } /** * Represents the persisted memory (or cache there of). */ public Network getLongTermMemory() { return longTermMemory; } public void setActiveMemory(List<Vertex> activeMemory) { this.activeMemory = activeMemory; } public void setShortTermMemory(Network shortTermMemory) { this.shortTermMemory = shortTermMemory; } public void setLongTermMemory(Network longTermMemory) { this.longTermMemory = longTermMemory; if (getShortTermMemory().getParent() != longTermMemory) { getShortTermMemory().setParent(longTermMemory); } } /** * Merge the short term memory into the long term and clears the short term. * This is similar to a transactional commit. * The changes should also be persisted, as the long term should always just be a cache of the storage. * This implementation does not support persistence. */ public void save() { getBot().log(this, "Saving", Bot.FINE, getShortTermMemory()); getLongTermMemory().merge(getShortTermMemory()); getShortTermMemory().resume(); } /** * This implementation does not support persistence. */ public void restore() { getBot().log(this, "Restoring", Bot.FINE, this); } /** * This implementation does not support persistence. */ public void fastRestore(String database, boolean isSchema) { getBot().log(this, "Restoring", Bot.FINE, this, database); } /** * This implementation does not support persistence. */ public void restore(String database, boolean isSchema) { getBot().log(this, "Restoring", Bot.FINE, this, database); } /** * Create a memory database. */ public void createMemory(String database) { } /** * Create a memory database. */ public void createMemory(String database, boolean isSchema) { } /** * Create a memory database. */ public void createMemoryFromTemplate(String database, String template) { createMemoryFromTemplate(database, false, template, false); } /** * Create a memory database. */ public void createMemoryFromTemplate(String database, boolean templateIsSchema, String template, boolean isSchema) { } /** * Destroy the database. */ public void destroyMemory(String database) { destroyMemory(database, false); } /** * Destroy the database. */ public void destroyMemory(String database, boolean isSchema) { } /** * Delete all content from the database. */ public void deleteMemory() { this.longTermMemory = new BasicNetwork(); this.longTermMemory.setBot(getBot()); this.shortTermMemory = new BasicNetwork(this.longTermMemory); this.shortTermMemory.setBot(getBot()); } /** * Allow import of another memory location. */ public void importMemory(String location) { } /** * Allow switching to another memory location. */ public void switchMemory(String location) { } /** * Allow switching to another memory location. */ public void switchMemory(String location, boolean isSchema) { } /** * Shutdown the memory. */ public synchronized void shutdown() { try { save(); } catch (Exception exception) { getBot().log(this, exception); } } /** * Reset state when instance is pooled. */ public void pool() { } /** * Reset the short term and active memories. * Revert to the long term state. */ public void abort() { getBot().log(this, "Aborting", Bot.FINE, getShortTermMemory()); this.activeMemory = new LinkedList<Vertex>(); this.shortTermMemory = new BasicNetwork(); this.shortTermMemory.setBot(getBot()); } public String toString() { return getClass().getSimpleName() + "(active(" + this.activeMemory.size() //+ "), short(" + this.shortTermMemory.size() + "), long(" + this.longTermMemory.size() + "))"; } public List<MemoryEventListener> getListeners() { return listeners; } protected void setListeners(List<MemoryEventListener> listeners) { this.listeners = listeners; } /** * Add the memory listener. * It will be notified of any new active memory. */ public void addListener(MemoryEventListener listener) { getListeners().add(listener); } public void removeListener(MemoryEventListener listener) { getListeners().remove(listener); } public int cacheSize() { return 0; } public void freeMemory() { } }