Java tutorial
/******************************************************************************* * Copyright (c) 2012 DCA-FEEC-UNICAMP * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License v3 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/lgpl.html * * Contributors: * K. Raizer, A. L. O. Paraense, R. R. Gudwin - initial API and implementation ******************************************************************************/ package br.unicamp.cst.behavior.bn; import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import java.util.List; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import br.unicamp.cst.core.entities.Codelet; import br.unicamp.cst.core.entities.MemoryObject; import br.unicamp.cst.core.exceptions.CodeletActivationBoundsException; import br.unicamp.cst.memory.WorkingStorage; /** * This competence class extends Codelet. "A competence resemble the operators of a classical planning system. A competence module i can be described by a list of preconditions and expected effects."[Maes 1989] * * @author klaus * */ public abstract class Behavior extends Codelet { //Debug variables private boolean showActivationSpread = false; // Enable this to see the activation flow in the console private boolean showCoalitionLinks = false; // Enable this to see the coalition links in the console private boolean printNoActivationCases = false;//Enable this to see if there are any problems with absent preconditions private String name = ""; //Each behavior must have a name. If not given by the user, it will be the same as its running thread's one protected ArrayList<String> actionList = new ArrayList<String>();// Actions that are to be performed by actuators and which constitute this behavior protected JSONArray jsonActionList = new JSONArray(); protected ArrayList<MemoryObject> preconList = new ArrayList<MemoryObject>(); // ci list of preconditions that must be fulfilled before the competence module can become active protected ArrayList<MemoryObject> addList = new ArrayList<MemoryObject>(); // ai expected effects of this action in terms of an add list protected ArrayList<MemoryObject> deleteList = new ArrayList<MemoryObject>(); // di expected effects of this action in terms of a delete list //TODO I'm modifying MAES original model to encompass a "soft" precondition list. Is is "soft" in the sense that it is not a must have. // a soft precondition affects activation spread in the same way a traditional precondition does, but its absense does not prevent the behavior to be executed. protected ArrayList<MemoryObject> softPreconList = new ArrayList<MemoryObject>(); // ci list of preconditions that are desirable to be fulfilled before the competence module can become active // Alpha level of activation is the codelet's own A (activation level) [Hypothesis to be investigated] protected ArrayList<Behavior> allBehaviors = new ArrayList<Behavior>();//Pointers to all behaviors in the network. Basal ganglia should support this hypothesis. protected ArrayList<Behavior> coalition = new ArrayList<Behavior>(); //A subset of all behaviors, given by consciousness. protected Hashtable<Behavior, ArrayList<MemoryObject>> predecessors = new Hashtable<Behavior, ArrayList<MemoryObject>>(); protected Hashtable<Behavior, ArrayList<MemoryObject>> successors = new Hashtable<Behavior, ArrayList<MemoryObject>>(); protected Hashtable<Behavior, ArrayList<MemoryObject>> conflicters = new Hashtable<Behavior, ArrayList<MemoryObject>>(); private ArrayList<MemoryObject> permanentGoals = new ArrayList<MemoryObject>(); private ArrayList<MemoryObject> onceOnlyGoals = new ArrayList<MemoryObject>(); private ArrayList<MemoryObject> protectedGoals = new ArrayList<MemoryObject>(); private ArrayList<MemoryObject> goals = new ArrayList<MemoryObject>(); private ArrayList<MemoryObject> worldState = new ArrayList<MemoryObject>(); private ArrayList<Object> listOfWorldBeliefStates = new ArrayList<Object>(); private ArrayList<Object> listOfPreviousWorldBeliefStates = new ArrayList<Object>(); private GlobalVariables globalVariables; //Behavior network global variables private boolean executable; //Defines if this behavior is executable or not private boolean active; //Defines if this behavior is active at the moment private boolean firstTime; // Checks if this behaviour is trying to perform actions for the first time since it got active private double maxA = 1; // maximum activation for normalization //TODO resourceList is a list of all the action buffers this behavior needs to complete its actions. private ArrayList<String> resourceList = new ArrayList<String>(); private boolean setToZeroWhenActivated = true; private double activationMA = 0; private WorkingStorage ws; public Behavior(WorkingStorage ws, GlobalVariables globalVariables) { this.ws = ws; this.globalVariables = globalVariables; //All behaviors subscribe their input list to receive news from Working Storage about WORLD_STATE, and goals memory objects. int io = 0; //Input list ws.registerCodelet(this, "WORLD_STATE", io); ws.registerCodelet(this, "ONCE_ONLY_GOAL", io); ws.registerCodelet(this, "PERMANENT_GOAL", io); ws.registerCodelet(this, "PERMANENT_GOAL", io); this.setExecutable(false); // Every competence starts as non-executable this.setActive(false); // Every competence starts as inactive try { setActivation(0); } catch (CodeletActivationBoundsException e) { e.printStackTrace(); } // Initial activation should be zero; this.setFirstTime(true); if (this.getName().equals("") || this.getName().equals(null)) { this.setName(this.getClass().getName()); //If the user did not set a name, lets use the name of the Class } Thread.currentThread().setName(this.getName());// If this behavior has a name, let's rename this thread's name } /** * Actions to be performed by the behavior net. Must be implemented by the user, or learned. */ public abstract void operation(); /** * This proc method runs the behavior network's cycle. And performs the actions described in operation() once this competence is activated. */ public void proc() { retrieveGoals(); // This should be done often because goals might change over time retrieveState(); // This should be done often because world state might change over time spreadActivation(); checkIfExecutable(); if (isActive()) { operation(); // operation this behavior should perform } } /** * * @return list of resources used by this behavior */ private ArrayList<String> getResourceList() {//TODO must develop this idea further return this.resourceList; } /** * @return the actionsSet */ public String getActionList()//TODO a simpler version of this might be interesting { // return actionList; try { JSONArray teste = new JSONArray(jsonActionList.toString()); } catch (JSONException e) { e.printStackTrace(); } return jsonActionList.toString(); } /** * retrieves the lists of world and self states from working storage through inputs */ private synchronized void retrieveState() { worldState.clear(); String moType; for (MemoryObject mo : getInputs()) { if (mo != null) { moType = mo.getName(); if (moType.equalsIgnoreCase("WORLD_STATE")) { worldState.add(mo); } } } // System.out.println("====> "+this.getName()+" worldState: "+worldState); } /** * Updates the links lists based on conscious codelets from the network * * "There is a successor link from competence module x to competence module y (x has y as successor) for every proposition p that is a member of the add list of x and also member of the precondition list of y (there can be more than one successor link between 2 competence modules)" * * "A predecessor link from module x to module y (x has y as predecessor) exists for every successor link from y to x." * * "There is a conflicter link from module x to module y (y conflicts with x) for every proposition p that is a member of the delete list of y and a member of the precondition linst of x" [Maes 1989] */ private void updateLinks()//TODO it would be best if we avoided accessing other codelet's inner states directly. How about doing all this using broadcast? { successors.clear(); predecessors.clear(); conflicters.clear(); // if(this.getName().contains("TV")){ // int a=4; // System.out.println(this.getName()); // // } ArrayList<MemoryObject> intersection = new ArrayList<MemoryObject>(); for (Behavior competence : coalition) { // if(competence.getName().contains("ROOM13")){ // int a=4; // System.out.println(competence.getName()); // // } if (impendingAccess(competence)) { try { if (competence != this) { //------ intersection = getIntersectionSet(this.getAddList(), competence.getListOfPreconditions()); if (!intersection.isEmpty()) { this.successors.put(competence, intersection); } intersection = getIntersectionSet(this.getAddList(), competence.getSoftPreconList()); if (!intersection.isEmpty()) { this.successors.put(competence, intersection); } //------ intersection = getIntersectionSet(this.getListOfPreconditions(), competence.getAddList()); if (!intersection.isEmpty()) { this.predecessors.put(competence, intersection); } intersection = getIntersectionSet(this.getSoftPreconList(), competence.getAddList()); if (!intersection.isEmpty()) { this.predecessors.put(competence, intersection); } //------ intersection = getIntersectionSet(competence.getListOfPreconditions(), this.getDeleteList()); // because we are looking for how this module messes up others preconditions, and thats why it must be inhibited by them if (!intersection.isEmpty()) { this.conflicters.put(competence, intersection); } intersection = getIntersectionSet(competence.getSoftPreconList(), this.getDeleteList()); // because we are looking for how this module messes up others preconditions, and thats why it must be inhibited by them if (!intersection.isEmpty()) { this.conflicters.put(competence, intersection); } } } finally { lock.unlock(); competence.lock.unlock(); } } } } /** * Retrieves the lists of goals from working storage */ private void retrieveGoals() { onceOnlyGoals.clear(); permanentGoals.clear(); protectedGoals.clear(); String moType; ArrayList<MemoryObject> my_inputs = new ArrayList<MemoryObject>(); my_inputs.addAll(getInputs()); for (MemoryObject mo : my_inputs) { if (mo != null) { moType = mo.getName(); if (moType.equalsIgnoreCase("ONCE_ONLY_GOAL")) { onceOnlyGoals.add(mo); } else if (moType.equalsIgnoreCase("PROTECTED_GOAL")) { protectedGoals.add(mo); } else if (moType.equalsIgnoreCase("PERMANENT_GOAL")) { permanentGoals.add(mo); } } } goals.clear(); goals.addAll(onceOnlyGoals); goals.addAll(protectedGoals); goals.addAll(permanentGoals); } public synchronized boolean changedWorldBeliefState() { ArrayList<Object> temp1 = new ArrayList<Object>(); ArrayList<Object> temp2 = new ArrayList<Object>(); temp1.addAll(listOfWorldBeliefStates); temp2.addAll(listOfPreviousWorldBeliefStates); return (!temp1.equals(temp2)); } /** * Checks if there is a current behavior proposition in working storage that is using the resources this behavior needs * @return if there is conflict of resources */ private boolean resourceConflict() {//TODO must develop this idea further boolean resourceConflict = false; ArrayList<MemoryObject> allOfType = new ArrayList<MemoryObject>(); if (ws != null) allOfType.addAll(ws.getAllOfType("BEHAVIOR_PROPOSITION")); ArrayList<String> usedResources = new ArrayList<String>(); if (allOfType != null) { for (MemoryObject bp : allOfType) { try { JSONObject jsonBp = new JSONObject(bp.getI()); //System.out.println("=======> bp.getInfo(): "+bp.getInfo()); boolean performed = jsonBp.getBoolean("PERFORMED"); if (!performed) {//otherwise it is not consuming those resources JSONArray resourceList = jsonBp.getJSONArray("RESOURCELIST"); for (int i = 0; i < resourceList.length(); i++) { usedResources.add(resourceList.getString(i)); } } } catch (JSONException e) { e.printStackTrace(); } } } // System.out.println("%%% usedResources: "+usedResources); // System.out.println("%%% getResourceList: "+getResourceList()); int sizeBefore = usedResources.size(); usedResources.removeAll(this.getResourceList()); int sizeLater = usedResources.size(); if (sizeLater != sizeBefore) { resourceConflict = true; // System.out.println("%%%%%%%%%%%%%%%%%%%%% There was a conflict here"); } return resourceConflict; } /** * A behavior module is executable at time t when all of its preconditions are observed to be true at time t. * */ private boolean checkIfExecutable() { listOfWorldBeliefStates = new ArrayList<Object>(); for (MemoryObject mo : this.getInputsOfType("WORLD_STATE")) { listOfWorldBeliefStates.add(mo.getI()); // System.out.println("###########adding world state"); } ArrayList<MemoryObject> tempPreconList = new ArrayList<MemoryObject>(); //Comparison between two MOs is performed between their infos tempPreconList.addAll(preconList); for (MemoryObject precon : preconList) { for (Object ws : listOfWorldBeliefStates) { if (precon.getI().equals(ws)) { tempPreconList.remove(precon); break; } } } if (tempPreconList.isEmpty()) { setExecutable(true); } else { setExecutable(false); } //TODO I should probably check for conflicts between behaviors here... return executable; } /** * 1-compute impact of state, goals and protected goals on the activation level of a module 2-compute the way the competence module activates and inhibits related modules through its successor links, predecessor links and conflicters 3- decay function ensures that the overall activation level remains constant */ private void spreadActivation() { if (!this.isActive()) { //If active, it should remain at zero double activation = 0; // TODO this can be optimized, I could get all this information with only one method (this would iterate only once through the coalition list double inputfromstate = inputFromState(); double inputfromgoals = inputFromGoals(); double takenawaybyprotectedgoals = takenAwayByProtectedGoals(); double spreadbw = spreadBw(); double spreadfw = spreadFw(); double takenaway = takenAway(); activation = inputfromstate + inputfromgoals - takenawaybyprotectedgoals + (spreadbw + spreadfw - takenaway); if (maxA < activation) {//calculates maximum activation added for normalization maxA = activation; } if (!this.isActive()) { // activation = activation + this.getActivation(); //TODO Without normalization activation = activation * (1 - this.getActivation()) / maxA + this.getActivation(); //With Normalization } //TODO I'm trying to migrate this decay property to BehaviorsWTA.java // decay();//TODO Decay process that scales the mean level of energy to pi // // activation=activation-globalVariables.getDecay(); //TODO Test with subtractive decay // if (globalVariables != null) activation = activation * globalVariables.getDecay(); //TODO test with multiplicative decay if (activation < 0) { activation = 0; } try { this.setActivation(activation); } catch (CodeletActivationBoundsException e) { e.printStackTrace(); } } else {//should remain at zero [Maes 1989] try { this.setActivation(0); } catch (CodeletActivationBoundsException e) { e.printStackTrace(); } } } /** * Decay function. Hypothesis: each time activation is spread from/towards a module this same module inhibits/excites the activation of all other modules making the mean activation level constant. */ private void decay() { // TODO this could be optimized double activation = 0; if (!this.coalition.isEmpty()) { for (Behavior module : this.coalition) { if (impendingAccess(module)) { try { activation = activation + module.getActivation(); activation = activation / this.coalition.size(); } finally { lock.unlock(); module.lock.unlock(); } } } } } /** * @param executable * sets this competence as being executable */ public void setExecutable(boolean executable) { this.executable = executable; } /** * @return the executable */ public boolean isExecutable() { return executable; } /** * @param adds * condition to listOfPreconditions */ public void addPreconList(MemoryObject condition) { this.preconList.add(condition); this.addInput(condition); } /** * @return deletes condition from listOfPreconditions */ public boolean delPreconList(MemoryObject condition) { this.removesInput(condition); return preconList.remove(condition); } /** * @param adds * condition to listOfPreconditions */ public void addSoftPreconList(MemoryObject condition) { this.softPreconList.add(condition); this.addInput(condition); } /** * @return deletes condition from listOfPreconditions */ public boolean delSoftPreconList(MemoryObject condition) { this.removesInput(condition); return softPreconList.remove(condition); } /** * @param adds * condition to addList */ public void addAddList(MemoryObject condition) { this.addList.add(condition); this.addOutput(condition); } /** * @return deletes condition from addList */ public boolean delAddList(MemoryObject condition) { this.removesOutput(condition); return addList.remove(condition); } /** * @param adds * condition to deleteList */ public void addDelList(MemoryObject condition) { this.addOutput(condition); this.deleteList.add(condition); } /** * @return deletes condition from deleteList */ public boolean delDelList(MemoryObject condition) { this.removesOutput(condition); return deleteList.remove(condition); } /** * @param active * the active to set */ public void setActive(boolean active) { this.active = active; listOfPreviousWorldBeliefStates = listOfWorldBeliefStates; } /** * @return the active */ public boolean isActive() { return active; } /** * * @return list of preconditions */ public ArrayList<MemoryObject> getListOfPreconditions() { return preconList; } /** * * @param listOfPreconditions * List of MemoryObjects with preconditions */ public void setListOfPreconditions(ArrayList<MemoryObject> listOfPreconditions) { this.preconList = listOfPreconditions; } /** * * @return add list */ public ArrayList<MemoryObject> getAddList() { return addList; } /** * * @param addList * sets the add list */ public void setAddList(ArrayList<MemoryObject> addList) { this.addList = addList; } /** * * @return the delete list */ public ArrayList<MemoryObject> getDeleteList() { return deleteList; } /** * * @param deleteList * sets the delete list */ public void setDeleteList(ArrayList<MemoryObject> deleteList) { this.deleteList = deleteList; } /** * @return the coalition */ public ArrayList<Behavior> getCoalition() { return coalition; } /** * @param coalition * the coalition to set */ public void setCoalition(ArrayList<Behavior> coalition) { this.coalition = coalition; updateLinks(); // Isto soh deve ser feito quando a coalizao muda if (showCoalitionLinks) { System.out.println("************* " + getName() + "'s Links ************"); System.out.println("* successors ------"); Enumeration e = this.successors.keys(); while (e.hasMoreElements()) { Behavior module = (Behavior) e.nextElement(); if (impendingAccess(module)) { try { System.out.println("Name: " + module.getName() + " |Props: " + this.successors.get(module)); } finally { lock.unlock(); module.lock.unlock(); } } } System.out.println("* predecessors ----"); e = this.predecessors.keys(); while (e.hasMoreElements()) { Behavior module = (Behavior) e.nextElement(); if (impendingAccess(module)) { try { System.out.println(module.getName() + " |Props: " + this.predecessors.get(module)); } finally { lock.unlock(); module.lock.unlock(); } } } System.out.println("* conflicters -----"); e = this.conflicters.keys(); while (e.hasMoreElements()) { Behavior module = (Behavior) e.nextElement(); if (impendingAccess(module)) { try { System.out.println(module.getName() + " |Props: " + this.conflicters.get(module)); } finally { lock.unlock(); module.lock.unlock(); } } } System.out.println("************************************************"); } } /** * @return the successors */ public Hashtable<Behavior, ArrayList<MemoryObject>> getSuccessors() { return successors; } /** * @param successors * the successors to set */ public void setSuccessors(Hashtable<Behavior, ArrayList<MemoryObject>> successors) { this.successors = successors; } /** * @return the predecessors */ public Hashtable<Behavior, ArrayList<MemoryObject>> getPredecessors() { return predecessors; } /** * @param predecessors * the predecessors to set */ public void setPredecessors(Hashtable<Behavior, ArrayList<MemoryObject>> predecessors) { this.predecessors = predecessors; } /** * @return the conflicters */ public Hashtable<Behavior, ArrayList<MemoryObject>> getConflicters() { return conflicters; } /** * @param conflicters * the conflicters to set */ public void setConflicters(Hashtable<Behavior, ArrayList<MemoryObject>> conflicters) { this.conflicters = conflicters; } /** * @param name * the name of this competence */ public void setName(String name) { this.name = name; Thread.currentThread().setName(name); } /** * @return the name of this competence */ public String getName() { return name; // return Thread.currentThread().getName(); } /** * @return the amount of activation from the state */ public double inputFromState() { double activation = 0; ArrayList<Behavior> tempCodelets = new ArrayList<Behavior>(); ArrayList<MemoryObject> THIS_softPrecon_and_ClassicPrecon = new ArrayList<MemoryObject>(); THIS_softPrecon_and_ClassicPrecon.addAll(this.getListOfPreconditions()); THIS_softPrecon_and_ClassicPrecon.addAll(this.getSoftPreconList()); tempCodelets.addAll(this.getAllBehaviors()); if (!tempCodelets.isEmpty()) { ArrayList<MemoryObject> intersection = getIntersectionSet(this.getWorldState(), THIS_softPrecon_and_ClassicPrecon); for (MemoryObject j : intersection) { double sharpM = 0; for (Behavior module : tempCodelets) { if (impendingAccess(module)) { try { ArrayList<MemoryObject> MODULE_softPrecon_and_ClassicPrecon = new ArrayList<MemoryObject>(); MODULE_softPrecon_and_ClassicPrecon.addAll(module.getListOfPreconditions()); MODULE_softPrecon_and_ClassicPrecon.addAll(module.getSoftPreconList()); if (MODULE_softPrecon_and_ClassicPrecon.contains(j)) { sharpM = sharpM + 1; } } finally { lock.unlock(); module.lock.unlock(); } } } // What if sharpM or listOfPreconditions.size == zero? // sharpM could zero because j comes from the intersection of S and c, so if no preconditions from the module is found in world state, the intersection shall be zero // synchronized(listOfPreconditions){ if ((sharpM > 0) && (THIS_softPrecon_and_ClassicPrecon.size() > 0)) { double activationfromstate = globalVariables.getPhi() * (1 / sharpM) * (1 / (double) THIS_softPrecon_and_ClassicPrecon.size()); if (showActivationSpread) { System.out.println( this.getName() + " got " + activationfromstate + " energy from the world state"); } activation = activation + activationfromstate; } else { if (printNoActivationCases) { System.out.println("No activation in the case [" + this.getName() + " getting energy from the world state]: either the number of satisfying modules is zero or there are no preconditions in this module."); } } // }//end synch } } // }//coalitionIsBusy=false; return activation; } /** * @return the allBehaviors */ public ArrayList<Behavior> getAllBehaviors() { return allBehaviors; } /** * @param allBehaviors the allBehaviors to set */ public void setAllBehaviors(ArrayList<Behavior> allBehaviors) { this.allBehaviors = allBehaviors; } /** * @return the amount of activation from goalsthis.coalition.lock(); */ public double inputFromGoals() { double activation = 0; ArrayList<Behavior> tempCodelets = new ArrayList<Behavior>(); //TODO Should we get this input from the coalition or from the full set of codelets? tempCodelets.addAll(this.getAllBehaviors()); if (!tempCodelets.isEmpty()) { ArrayList<MemoryObject> intersection = getIntersectionSet(this.getGoals(), this.getAddList()); for (MemoryObject j : intersection) { double sharpA = 0; for (Behavior module : tempCodelets) { if (impendingAccess(module)) { try { if (module.getAddList().contains(j)) { sharpA = sharpA + 1; } } finally { lock.unlock(); module.lock.unlock(); } } } // synchronized(this.addList){ if ((sharpA > 0) && (this.getAddList().size() > 0)) { double othermoduleActivation = globalVariables.getGamma() * ((1 / sharpA) * (1 / (double) this.getAddList().size())); if (showActivationSpread) { System.out.println( this.getName() + " receives " + othermoduleActivation + " energy from goal " + j); } activation = activation + othermoduleActivation; } else { if (showActivationSpread) { System.out.println("No activation from situation [" + this.getName() + " getting activation from goals]: either the number of satisfying modules is zero or there are no preconditions in this module."); } } // }//end synch } } // activation=activation*globalVariables.getGamma(); return activation; } /** * @return the amount of activation to be removed by the goals that are protected */ public double takenAwayByProtectedGoals() { double activation = 0; // synchronized(this.coalition){ if (!this.getCoalition().isEmpty()) { ArrayList<MemoryObject> intersection = getIntersectionSet(this.getProtectedGoals(), this.getDeleteList()); for (MemoryObject j : intersection) { double sharpU = 0; for (Behavior module : this.getCoalition()) { if (impendingAccess(module)) { try { if (module.getDeleteList().contains(j)) { sharpU = sharpU + 1; } } finally { lock.unlock(); module.lock.unlock(); } } } // synchronized(this.deleteList){ if ((sharpU > 0) && (this.getDeleteList().size() > 0)) { double takenEnergy = (1 / sharpU) * (1 / (double) this.getDeleteList().size()) * globalVariables.getDelta(); if (showActivationSpread) { System.out.println( this.getName() + " has " + takenEnergy + " taken away from it by protected goals."); } activation = activation + takenEnergy; } else { if (showActivationSpread) { System.out.println("No activation from situation [" + this.getName() + " having energy taken away by protected goals]: either the number of satisfying modules is zero or there are no preconditions in this module."); } } // }//end synch } } // }//end synch return activation; } /** * @return the amount of activation that is spread backwards from other modules in the direction of this module * * Note: this approach is slightly different from the one proposed at the article by [Maes 1989] since here we try to avoid meddling with another codelet's states. */ public double spreadBw() { // In this case x= other modules, y= this module double activation = 0; // synchronized(this.successors){ if (!this.getSuccessors().isEmpty()) { Enumeration e = this.getSuccessors().keys(); // iterate through Hashtable keys Enumeration while (e.hasMoreElements()) { Behavior module = (Behavior) e.nextElement(); if (impendingAccess(module)) { try { double amount = 0; if (!module.isExecutable()) {// A competence module x that is not executable spreads activation backward. ArrayList<MemoryObject> intersection = new ArrayList<MemoryObject>(); ArrayList<MemoryObject> preconPlusSoftPrecon = new ArrayList<MemoryObject>(); preconPlusSoftPrecon.addAll(module.getListOfPreconditions()); intersection.addAll(getIntersectionSet(preconPlusSoftPrecon, this.getAddList())); intersection.removeAll(worldState); for (MemoryObject item : intersection) { amount = amount + ((1.0 / this.competencesWithPropInAdd(item)) * (1.0 / (double) this.getAddList().size())); } amount = amount * module.getActivation() * (globalVariables.getPhi() / globalVariables.getGamma()); if (showActivationSpread) { System.out.println(this.getName() + " receives " + amount + " backwarded energy from " + module.getName() + " [which has A= " + module.getActivation() + " ]"); } } // -------------------------- activation = activation + amount; } finally { lock.unlock(); module.lock.unlock(); } } } } return activation; } /** * @return the amount of activation that is spread forward from other modules in the direction of this module * * Note: this approach is slightly different from the one proposed at the article by [Maes 1989] since here we try to avoid meddling with another codelet's states. */ public double spreadFw() { // In this case x= other modules, y= this module double activation = 0; // synchronized(this.predecessors){ if (!this.getPredecessors().isEmpty()) { Enumeration e = this.getPredecessors().keys(); // iterate through Hashtable keys Enumeration while (e.hasMoreElements()) { Behavior module = (Behavior) e.nextElement(); if (impendingAccess(module)) { try { double amount = 0; if (module.isExecutable()) {// An executable competence module x spreads activation forward. ArrayList<MemoryObject> intersection = new ArrayList<MemoryObject>(); ArrayList<MemoryObject> preconPlusSoftPrecon = new ArrayList<MemoryObject>(); preconPlusSoftPrecon.addAll(this.getListOfPreconditions()); preconPlusSoftPrecon.addAll(this.getSoftPreconList()); intersection.addAll(getIntersectionSet(module.getDeleteList(), preconPlusSoftPrecon)); intersection.removeAll(worldState); for (MemoryObject item : intersection) { amount = amount + ((1.0 / this.competencesWithPropInPrecon(item)) * (1.0 / (double) preconPlusSoftPrecon.size())); } amount = amount * module.getActivation() * (globalVariables.getPhi() / globalVariables.getGamma()); if (showActivationSpread) { System.out.println(this.getName() + " receives " + amount + " forwarded energy from " + module.getName() + " [which has A= " + module.getActivation() + " ]"); } } // ------------------------------------------------ activation = activation + amount; } finally { lock.unlock(); module.lock.unlock(); } } } } // }//end synch return activation; } /** * @return the amount of activation that is taken away from this module by other modules through conflict links * * Note: this approach is slightly different from the one proposed at the article by [Maes 1989] since here we try to avoid meddling with another codelet's states. Note: I am not using the "max" strategy described by maes */ public double takenAway() { // In this case x= other modules, y= this module double activation = 0; // synchronized(this.conflicters){ if (!this.getConflicters().isEmpty()) { Enumeration e = this.getConflicters().keys(); // iterate through Hashtable keys Enumeration while (e.hasMoreElements()) { Behavior module = (Behavior) e.nextElement(); if (impendingAccess(module)) { try { // --------------------------------- double amount = 0; ArrayList<MemoryObject> intersection = new ArrayList<MemoryObject>(); ArrayList<MemoryObject> preconPlusSoftPrecon = new ArrayList<MemoryObject>(); preconPlusSoftPrecon.addAll(this.getListOfPreconditions()); preconPlusSoftPrecon.addAll(this.getSoftPreconList()); intersection = getIntersectionSet(preconPlusSoftPrecon, module.getDeleteList()); intersection = getIntersectionSet(intersection, worldState); if (!((module.getActivation() < this.getActivation()) && (!intersection.isEmpty()))) { // this is the else case due to ! preconPlusSoftPrecon = new ArrayList<MemoryObject>(); preconPlusSoftPrecon.addAll(module.getListOfPreconditions()); preconPlusSoftPrecon.addAll(module.getSoftPreconList()); intersection = getIntersectionSet(this.getDeleteList(), preconPlusSoftPrecon); intersection = getIntersectionSet(intersection, worldState); for (MemoryObject item : intersection) { amount = amount + ((1.0 / this.competencesWithPropInDel(item)) * (1.0 / (double) this.getDeleteList().size())); } // amount = (b1.activation[0] * // (self.conf_energy / self.goal_energy) * // amount) amount = module.getActivation() * (globalVariables.getDelta() / globalVariables.getGamma()) * amount; ArrayList<MemoryObject> modulos = this.getConflicters().get(module); double numberOfConflicters = 0; if (modulos != null) { numberOfConflicters = (double) modulos.size(); } // TODO Eu nao deveria precisar fazer este teste! double moduleActivation = module.getActivation(); double activationFromModule = (globalVariables.getDelta() / globalVariables.getGamma()) * numberOfConflicters * moduleActivation; if (showActivationSpread) { System.out.println(this.getName() + " has " + amount + " of its energy decreased by " + module.getName() + " [which has A= " + module.getActivation() + " ]"); } } // ------------------------------------ activation = activation + amount; } finally { lock.unlock(); module.lock.unlock(); } } } } return activation; } /** * * @param A * double value to be compared * @param B * @return the highest value */ private double max(double A, double B) { if (A > B) { return A; } else { return B; } } /** * Returns a list of PROPOSITION MOs constituting the intersection between A and B. * For this method to work, at least one of the lists must be of propositions * * @param list * list A * @param B * list B * @return the list with the intersection between A and B lists * @throws Exception */ public ArrayList<MemoryObject> getIntersectionSet(ArrayList<MemoryObject> A, ArrayList<MemoryObject> B) {//TODO Should this comparison be performed as pattern matching? ArrayList<MemoryObject> currentList = new ArrayList<MemoryObject>(); ArrayList<MemoryObject> intersection = new ArrayList<MemoryObject>(); if ((A.isEmpty() || B.isEmpty()) || (A == null || B == null)) { return intersection; } // System.out.println(B); // System.out.println(B.get(0)); //Gives preference to returning PROPOSITIONs if (A.get(0).getName().equalsIgnoreCase("PROPOSITION")) { currentList.addAll(B); intersection.addAll(A); } else if ((B.get(0).getName().equalsIgnoreCase("PROPOSITION"))) { currentList.addAll(A); intersection.addAll(B); } else { // return null; //Should throw an exception? currentList.addAll(A); intersection.addAll(B); } for (int i = intersection.size() - 1; i > -1; --i) { MemoryObject mo = intersection.get(i); if (!removeByInfo(currentList, mo.getI())) removeByInfo(intersection, mo.getI()); } return intersection; } public boolean removeByInfo(ArrayList<MemoryObject> moList, Object target) { boolean removed = false; MemoryObject mustRemove = null; for (MemoryObject mo : moList) { if (mo.getI().equals(target)) { mustRemove = mo; break; } } if (mustRemove != null) { moList.remove(mustRemove); removed = true; } return removed; } /** * @return the worldState */ public ArrayList<MemoryObject> getWorldState() { return worldState; } /** * @param worldState * the worldState to set */ public void setWorldState(ArrayList<MemoryObject> worldState) { this.worldState = worldState; } /** * @return the protectedGoals */ public ArrayList<MemoryObject> getProtectedGoals() { return protectedGoals; } /** * @param protectedGoals * the protectedGoals to set */ public void setProtectedGoals(ArrayList<MemoryObject> protectedGoals) { this.protectedGoals = protectedGoals; } /** * @return the permanentGoals */ public ArrayList<MemoryObject> getPermanentGoals() { return permanentGoals; } /** * @param permanentGoals * the permanentGoals to set */ public void setPermanentGoals(ArrayList<MemoryObject> permanentGoals) { this.permanentGoals = permanentGoals; } /** * @return the onceOnlyGoals */ public ArrayList<MemoryObject> getOnceOnlyGoals() { return onceOnlyGoals; } /** * @param onceOnlyGoals * the onceOnlyGoals to set */ public void setOnceOnlyGoals(ArrayList<MemoryObject> onceOnlyGoals) { this.onceOnlyGoals = onceOnlyGoals; } /** * @return the goals */ public ArrayList<MemoryObject> getGoals() { return goals; } /** * @param goals * the goals to set */ public void setGoals(ArrayList<MemoryObject> goals) { this.goals = goals; } /** * @return the globalVariables */ public GlobalVariables getGlobalVariables() { return globalVariables; } /** * @param globalVariables * the globalVariables to set */ public void setGlobalVariables(GlobalVariables globalVariables) { this.globalVariables = globalVariables; } /** * @return the firstTime */ public boolean isFirstTime() { return firstTime; } /** * @param firstTime * the firstTime to set */ public void setFirstTime(boolean firstTime) { this.firstTime = firstTime; } /** * @param actionsSet * the actionsSet to set * @return */ public void setActionList(ArrayList<String> actionsSet) { this.actionList = actionsSet; } /** * @param action * the action to be added to actionSet */ public void addAction(String action) { this.actionList.add(action); String pNumber; String[] actionDecomposition = action.split(" "); JSONObject jsonAction = new JSONObject(); try { if (!this.resourceList.contains(actionDecomposition[0])) { this.resourceList.add(actionDecomposition[0]); //Stores this resource in this behavior's resource list } jsonAction.put("RESOURCE", actionDecomposition[0]); jsonAction.put("ACTION", actionDecomposition[1]); for (int i = 2; i < actionDecomposition.length; i++) { pNumber = "P" + String.valueOf(i - 1); jsonAction.put(pNumber, actionDecomposition[i]); } } catch (JSONException e) { e.printStackTrace(); } this.jsonActionList.put(jsonAction); // System.out.println("---JSON ACTION: "+jsonAction); } /** * Clears this behavior's action list */ public void clearActionList() { this.jsonActionList = new JSONArray(); this.actionList.clear(); } /** * Returns the number of competences in coalition with the given proposition in their precondition lists */ private double competencesWithPropInPrecon(MemoryObject proposition) { double compWithProp = 0; for (Behavior comp : this.getCoalition()) { if (impendingAccess(comp)) { try { if (comp.getListOfPreconditions().contains(proposition) || comp.getSoftPreconList().contains(proposition)) { compWithProp = compWithProp + 1; } } finally { lock.unlock(); comp.lock.unlock(); } } } return compWithProp; } /** * Returns the list of competences from coalition with the given proposition in their add lists */ private double competencesWithPropInAdd(MemoryObject proposition) { double compWithProp = 0; for (Behavior comp : this.getCoalition()) { if (impendingAccess(comp)) { try { if (comp.getAddList().contains(proposition)) { compWithProp = compWithProp + 1; } } finally { lock.unlock(); comp.lock.unlock(); } } } return compWithProp; } /** * Returns the list of competences from coalition with the given proposition in its del lists */ private double competencesWithPropInDel(MemoryObject proposition) { double compWithProp = 0; for (Behavior comp : this.getCoalition()) { if (impendingAccess(comp)) { try { if (comp.getDeleteList().contains(proposition)) { compWithProp = compWithProp + 1; } } finally { lock.unlock(); comp.lock.unlock(); } } } return compWithProp; } /** * Sets the list of actions constituting this behavior * * @param actions * list of actions */ private void addAllActions(ArrayList<String> actions) { this.actionList = actions; } /** * Returns the list of actions constituting this behavior * * @return list of actions */ private List<String> getAllActions() { return this.actionList; } public void setBehaviors(ArrayList<Behavior> competences) { this.allBehaviors = competences; } /** * @return the setToZeroWhenActivated */ public boolean isSetToZeroWhenActivated() { return setToZeroWhenActivated; } /** * @param setToZeroWhenActivated the setToZeroWhenActivated to set */ public void setSetToZeroWhenActivated(boolean setToZeroWhenActivated) { this.setToZeroWhenActivated = setToZeroWhenActivated; } /** * Returns the moving average of the last n activations. * n must be previously defined, otherwise it will return the current activation (n=1) * @return */ public synchronized double getActivationMA() { return activationMA; } /** * @return the softPreconList */ public ArrayList<MemoryObject> getSoftPreconList() { return softPreconList; } /** * @param softPreconList the softPreconList to set */ public void setSoftPreconList(ArrayList<MemoryObject> softPreconList) { this.softPreconList = softPreconList; } }