diff --git a/README.md b/README.md
index cd02ac83..d7fb7338 100755
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ Note: This library is still under development, and some concepts or features mig
```
dependencies {
...
- implementation 'com.github.CST-Group:cst:1.5.0'
+ implementation 'com.github.CST-Group:cst:1.6.0'
}
```
@@ -53,7 +53,7 @@ Sometimes, the version number (tag) in this README gets out of date, as maintain
com.github.CST-Group
cst
- 1.5.0
+ 1.6.0
```
diff --git a/build.gradle b/build.gradle
index 87b497e5..d44fedc9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -17,7 +17,7 @@ java {
}
-version = '1.5.0'
+version = '1.6.0'
repositories {
mavenCentral()
@@ -177,4 +177,4 @@ testlogger {
// set to false to hide failed standard out and error streams
showFailedStandardStreams true
-}
\ No newline at end of file
+}
diff --git a/src/main/java/br/unicamp/cst/core/entities/Codelet.java b/src/main/java/br/unicamp/cst/core/entities/Codelet.java
index a29418aa..57060076 100755
--- a/src/main/java/br/unicamp/cst/core/entities/Codelet.java
+++ b/src/main/java/br/unicamp/cst/core/entities/Codelet.java
@@ -803,6 +803,21 @@ public synchronized void setIsMemoryObserver(boolean isMemoryObserver) {
this.isMemoryObserver = isMemoryObserver;
}
+ /**
+ * Check if this Codelet is in publish-subscribe mode.
+ *
+ */
+ public synchronized boolean isPublishSubscribe() {
+ return isMemoryObserver;
+ }
+
+
+ /**
+ * Sets and unsets publish-subscribe mode.
+ *
+ * @param enable
+ * sets publish-subscribe mode on true or false
+ */
@SuppressWarnings("empty-statement")
public synchronized void setPublishSubscribe(boolean enable) {
if (enable) {
diff --git a/src/main/java/br/unicamp/cst/representation/idea/HabitExecutionerCodelet.java b/src/main/java/br/unicamp/cst/representation/idea/HabitExecutionerCodelet.java
index 8d7b0046..eaa3a794 100644
--- a/src/main/java/br/unicamp/cst/representation/idea/HabitExecutionerCodelet.java
+++ b/src/main/java/br/unicamp/cst/representation/idea/HabitExecutionerCodelet.java
@@ -12,37 +12,67 @@
import br.unicamp.cst.core.entities.Codelet;
import br.unicamp.cst.core.entities.Memory;
+import br.unicamp.cst.core.entities.MemoryContainer;
+
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
- *
+ * This codelet executes a habit found in its input memories.
+ *
+ * It looks for a habit in a memory whose name is the
+ * same as the name of the codelet plus "Habits".
+ *
+ * It also looks for ideas in the other input memories and adds them
+ * to a root idea, which is passed as a parameter to the habit execution.
+ *
+ * If there is another habit in the input memories without the "Habits"
+ * suffix, it is added to the root idea as well, but not executed.
+ *
+ * The habit returns a root idea, which may contain several ideas inside it.
+ * The codelet looks for ideas inside the root idea whose names match (case insensitive)
+ * the names of its output memories, and sets those ideas to the respective memories.
+ *
+ * If the output memory is a MemoryContainer, it sets the MemoryObjects inside it
+ * with the name of the Habit being executed by the HabitExecutionerCodelet itslef.
+ *
* @author rgudwin
*/
public class HabitExecutionerCodelet extends Codelet {
-
Habit h;
Idea root;
+ String habitName;
+
+ public HabitExecutionerCodelet() {
+ this.name = "Default";
+ }
+
+ public HabitExecutionerCodelet(String name) {
+ this.name = name;
+ }
@Override
public void accessMemoryObjects() {
- root = new Idea("root");
+ root = new Idea("root", "");
for (Memory m : this.inputs) {
Object o = m.getI();
if (o instanceof Idea) {
Idea id = (Idea)o;
Object value = id.getValue();
- if (value instanceof Habit) {
+ if (m.getName().equalsIgnoreCase(this.getName()+"Habits") && value instanceof Habit) {
h = (Habit) value;
+ habitName = id.getName();
}
else {
root.add((Idea)o);
}
}
}
- if (root.isLeaf()) {
- Logger.getAnonymousLogger().log(Level.INFO, "I was not able to find any valid Idea at inputs");
+ if (root.isLeaf() && this.inputs.size() > 1) {
+ Logger.getAnonymousLogger().log(Level.FINE, "I was not able to find any valid Idea at inputs");
}
if (h == null) {
Logger.getAnonymousLogger().log(Level.INFO, "I found no habit to execute");
@@ -56,10 +86,71 @@ public void calculateActivation() {
@Override
public void proc() {
- if (h != null) {
- Idea ois = h.exec(root);
- for (Memory m : outputs)
- m.setI(ois);
+ if (h == null) return;
+
+ Idea outputRoot = h.exec(root);
+ if (outputRoot == null) return;
+
+ try{this.setActivation(getActivationValue(outputRoot));}catch(Exception e){};
+
+ setTimeStepValue(outputRoot);
+
+ setPublishSubscribeValue(outputRoot);
+
+ setIdeasToOutputMemories(outputRoot);
+ }
+
+ private double getActivationValue(Idea idea) {
+ double act = 0.0d;
+ Idea actIdea = idea.get("activation");
+ if (actIdea != null && actIdea.getValue() instanceof Double) {
+ act = (double) actIdea.getValue();
+ }
+ return act;
+ }
+
+ private void setTimeStepValue(Idea idea) {
+ Idea timeStepIdea = idea.get("timeStep");
+ if (timeStepIdea != null && timeStepIdea.getValue() instanceof Long) {
+ long timeStep = (long) timeStepIdea.getValue();
+ try{this.setTimeStep(timeStep);}catch(Exception e){};
+ }
+ }
+
+ private void setPublishSubscribeValue(Idea idea) {
+ Idea publishSubscribeIdea = idea.get("publishSubscribe");
+ if (publishSubscribeIdea != null && publishSubscribeIdea.getValue() instanceof Boolean) {
+ boolean publishSubscribe = (boolean) publishSubscribeIdea.getValue();
+ try{this.setPublishSubscribe(publishSubscribe);}catch(Exception e){};
+ }
+ }
+
+ /**
+ * Gets the ideas from the outputRoot and sets them to the output memories
+ * that match by name (case insensitive).
+ *
+ * If the memory is a MemoryContainer, it sets the MemoryObjects inside it
+ * with the name of the Habit being executed by the HabitExecutionerCodelet itslef.
+ * It does so to differentiate between different Habits writing to the same MemoryContainer.
+ *
+ * @param outputRoot
+ * the root idea that comes from the habit execution
+ */
+ private void setIdeasToOutputMemories(Idea outputRoot) {
+ Map outputsMap = new HashMap<>();
+ for (Memory mem : this.outputs) outputsMap.put(mem.getName().toLowerCase(), mem);
+
+ for (Idea outputIdea : outputRoot.getL()) {
+ Memory m = outputsMap.get(outputIdea.getName().toLowerCase());
+ if (m == null) continue; // Skip to the next idea if no match is found
+
+ if (m instanceof MemoryContainer) {
+ MemoryContainer mc = (MemoryContainer) m;
+ mc.setI(outputIdea, getActivationValue(outputIdea), habitName);
+ }
+ else {
+ m.setI(outputIdea);
+ }
}
}
-}
+}
\ No newline at end of file
diff --git a/src/test/java/br/unicamp/cst/representation/idea/HabitExecutionerCodeletTest.java b/src/test/java/br/unicamp/cst/representation/idea/HabitExecutionerCodeletTest.java
index 9ed6d5f7..c0e3e10d 100644
--- a/src/test/java/br/unicamp/cst/representation/idea/HabitExecutionerCodeletTest.java
+++ b/src/test/java/br/unicamp/cst/representation/idea/HabitExecutionerCodeletTest.java
@@ -3,30 +3,54 @@
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
package br.unicamp.cst.representation.idea;
-import br.unicamp.cst.core.entities.MemoryContainer;
-import br.unicamp.cst.core.entities.MemoryObject;
-import br.unicamp.cst.core.entities.Mind;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.fail;
+
+import java.util.Random;
+
import org.junit.jupiter.api.Test;
+import br.unicamp.cst.core.entities.MemoryContainer;
+import br.unicamp.cst.core.entities.MemoryObject;
+import br.unicamp.cst.core.entities.Mind;
+
/**
*
* @author rgudwin
*/
public class HabitExecutionerCodeletTest {
-
+ double act;
+ long timeStep;
+ boolean publishSubscribe;
+ int exec_counter;
+ int proc_counter;
+
+ Habit summer;
+ Habit decrementer;
+ Habit actSetter;
+ Habit timeStepSetter;
+ Habit publishSubscribeSetter;
+ Habit outputSetter;
+ Habit notExecuted;
+ Habit nullIdeaSetter;
+ Habit emptyIdeaSetter;
+
Mind m;
MemoryContainer mc;
MemoryObject moi;
MemoryObject moo;
+
+ Idea global_idea;
- public HabitExecutionerCodeletTest() {
+ private void setUp() {
+ MockHabits mh = new MockHabits();
+ summer = mh.summer;
+ decrementer = mh.decrementer;
+
m = new Mind();
- mc = m.createMemoryContainer("HabitsMemory");
+
+ mc = m.createMemoryContainer("testHabits");
Idea sh = new Idea("Summer");
sh.setValue(summer);
sh.setScope(2);
@@ -37,7 +61,7 @@ public HabitExecutionerCodeletTest() {
mc.setI(dh);
moi = m.createMemoryObject("InputIdeasMemory");
moo = m.createMemoryObject("OutputIdeasMemory");
- HabitExecutionerCodelet hec = new HabitExecutionerCodelet();
+ HabitExecutionerCodelet hec = new HabitExecutionerCodelet("test");
hec.addInput(mc);
hec.addInput(moi);
hec.addOutput(moo);
@@ -45,42 +69,7 @@ public HabitExecutionerCodeletTest() {
m.insertCodelet(hec);
m.start();
}
-
- Habit summer = new Habit() {
- @Override
- public Idea exec(Idea idea) {
- Idea adder = idea.get("value.add");
- int valuetoadd=0;
- if (adder != null && adder.getValue() instanceof Integer) {
- valuetoadd = (int) adder.getValue();
- }
- if (idea.get("value").getValue() instanceof Integer) {
- int number = (int) idea.get("value").getValue();
- Idea modifiedIdea = new Idea("incremented",number+valuetoadd);
- return(modifiedIdea);
- }
- System.out.println("Something wrong happened");
- return(null);
- }
- };
- Habit decrementer = new Habit() {
- @Override
- public Idea exec(Idea idea) {
- Idea adder = idea.get("value.add");
- int valuetodec=0;
- if (adder != null && adder.getValue() instanceof Integer) {
- valuetodec = (int) adder.getValue();
- }
- if (idea.get("value").getValue() instanceof Integer) {
- int number = (int) idea.get("value").getValue();
- Idea modifiedIdea = new Idea("decremented",number-valuetodec);
- return(modifiedIdea);
- }
- System.out.println("Something wrong happened");
- return(null);
- }
- };
-
+
private void doTest() {
Object oo;
Random r = new Random();
@@ -127,7 +116,7 @@ private void doTest() {
@Test
public void testHabitExecutionerCodeletMAX() {
- HabitExecutionerCodeletTest test = new HabitExecutionerCodeletTest();
+ setUp();
mc.setPolicy(MemoryContainer.Policy.MAX);
System.out.println("\nTesting the MAX Policy - Sums for < 50 Decs for > 50");
doTest();
@@ -135,7 +124,7 @@ public void testHabitExecutionerCodeletMAX() {
@Test
public void testHabitExecutionerCodeletMIN() {
- HabitExecutionerCodeletTest test = new HabitExecutionerCodeletTest();
+ setUp();
mc.setPolicy(MemoryContainer.Policy.MIN);
System.out.println("\nTesting the MIN Policy - Sums for > 50 Decs for < 50");
doTest();
@@ -143,7 +132,7 @@ public void testHabitExecutionerCodeletMIN() {
@Test
public void testHabitExecutionerCodeletIterate() {
- HabitExecutionerCodeletTest test = new HabitExecutionerCodeletTest();
+ setUp();
mc.setPolicy(MemoryContainer.Policy.ITERATE);
System.out.println("\nTesting the ITERATE Policy - Iterate Sums and Decs");
doTest();
@@ -151,10 +140,620 @@ public void testHabitExecutionerCodeletIterate() {
@Test
public void testHabitExecutionerCodeletRandom() {
- HabitExecutionerCodeletTest test = new HabitExecutionerCodeletTest();
+ setUp();
mc.setPolicy(MemoryContainer.Policy.RANDOM_FLAT);
System.out.println("\nTesting the RANDOM_FLAT Policy - Sums and Decs at Random");
doTest();
}
-
-}
+
+ @Test
+ public void testName() {
+ System.out.println("\nTesting Name Setting and Default Name");
+ HabitExecutionerCodelet hec = new HabitExecutionerCodelet();
+ assertEquals("Default", hec.getName());
+ hec = new HabitExecutionerCodelet("MyName");
+ assertEquals("MyName", hec.getName(), "Name should be MyName");
+ }
+
+ @Test
+ public void testActivation() {
+ System.out.println("\nTesting Activation Setting through Habits");
+
+ Random r = new Random();
+ for (int k=0;k<100;k++) {
+ act = r.nextDouble();
+ MockHabits mh = new MockHabits();
+ actSetter = mh.actSetter;
+ HabitExecutionerCodelet hec = new HabitExecutionerCodelet("Name");
+ hec.h = actSetter;
+ hec.proc();
+
+ assertEquals(act, hec.getActivation(), "Activation should be " + act);
+ }
+ }
+
+ @Test
+ public void testTimeStep() {
+ System.out.println("\nTesting TimeStep Setting through Habits");
+
+ Random r = new Random();
+ for (int k=0;k<100;k++) {
+ timeStep = r.nextInt(1000);
+ MockHabits mh = new MockHabits();
+ timeStepSetter = mh.timeStepSetter;
+ HabitExecutionerCodelet hec = new HabitExecutionerCodelet("Name");
+ hec.h = timeStepSetter;
+ hec.proc();
+
+ assertEquals(timeStep, hec.getTimeStep(), "TimeStep should be " + timeStep);
+ }
+
+ }
+
+ @Test
+ public void testPublishSubscribe() {
+ System.out.println("\nTesting PublishSubscribe Setting through Habits");
+
+ MockHabits mh = new MockHabits();
+ publishSubscribeSetter = mh.publishSubscribeSetter;
+ HabitExecutionerCodelet hec = new HabitExecutionerCodelet("Name");
+ hec.h = publishSubscribeSetter;
+
+ publishSubscribe = true;
+ hec.proc();
+ assertEquals(true, hec.isPublishSubscribe(), "PublishSubscribe should be true");
+
+ publishSubscribe = false;
+ hec.proc();
+ assertEquals(false, hec.isPublishSubscribe(), "PublishSubscribe should be false");
+ }
+
+ @Test
+ public void testNoOutputMemory() {
+ System.out.println("\nTesting the case where there is no output memory");
+
+ exec_counter = 0;
+
+ MockHabits mh = new MockHabits();
+ outputSetter = mh.outputSetter;
+ m = new Mind();
+ mc = m.createMemoryContainer("testHabits");
+ Idea osh = new Idea("OutputSetter");
+ osh.setValue(outputSetter);
+ osh.setScope(2);
+ mc.setI(osh);
+ HabitExecutionerCodelet hec = new HabitExecutionerCodelet("test");
+ hec.addInput(mc);
+ m.insertCodelet(hec);
+ m.start();
+ try {
+ while(exec_counter < 5) { System.out.print("."); Thread.sleep(1); }
+ } catch (Exception e) {
+ fail("An error occurred: " + e.getMessage());
+ }
+ assertEquals(5, exec_counter, "The habit should have been executed 5 times without errors");
+ }
+
+ @Test
+ public void testNoHabitMemoryContainer() {
+ System.out.println("\nTesting the case where there is no habit memory container");
+
+ proc_counter = 0;
+
+ m = new Mind();
+ moi = m.createMemoryObject("InputIdeasMemory");
+ moo = m.createMemoryObject("OutputIdeasMemory");
+ HabitExecutionerCodelet hec = new HabitExecutionerCodelet("test") {
+ @Override
+ public void proc() {
+ proc_counter++;
+ super.proc();
+ }
+ };
+ hec.addInput(moi);
+ hec.addOutput(moo);
+
+ m.insertCodelet(hec);
+ m.start();
+
+ try {
+ while(proc_counter < 5) { System.out.print("."); Thread.sleep(1); }
+ } catch (Exception e) {
+ fail("An error occurred: " + e.getMessage());
+ }
+ assertNull(hec.h, "The habit should be null");
+ }
+
+ @Test
+ public void testNoHabit() {
+ System.out.println("\nTesting the case where there is a habit memory container but no habit inside it");
+
+ proc_counter = 0;
+
+ m = new Mind();
+ mc = m.createMemoryContainer("testHabits");
+ moi = m.createMemoryObject("InputIdeasMemory");
+ moo = m.createMemoryObject("OutputIdeasMemory");
+ HabitExecutionerCodelet hec = new HabitExecutionerCodelet("test") {
+ @Override
+ public void proc() {
+ proc_counter++;
+ super.proc();
+ }
+ };
+ hec.addInput(mc);
+ hec.addInput(moi);
+ hec.addOutput(moo);
+
+ m.insertCodelet(hec);
+ m.start();
+
+ try {
+ while(proc_counter < 5) { System.out.print("."); Thread.sleep(1); }
+ } catch (Exception e) {
+ fail("An error occurred: " + e.getMessage());
+ }
+ assertNull(hec.h, "The habit should be null");
+ }
+
+ @Test
+ public void testHabitsContainerNameMatching() {
+ System.out.println("\nTesting the case where there is one Habit Memory Container with correct name");
+
+ String[] matchingNames = {"testHabits", "TESTHABITS", "TestHabits", "tEsThAbItS"};
+
+ for (String name : matchingNames) {
+ exec_counter = 0;
+
+ MockHabits mh = new MockHabits();
+ outputSetter = mh.outputSetter;
+ m = new Mind();
+ mc = m.createMemoryContainer(name);
+ Idea osh = new Idea("OutputSetter");
+ osh.setValue(outputSetter);
+ osh.setScope(2);
+ mc.setI(osh);
+ moi = m.createMemoryObject("InputIdeasMemory");
+ moo = m.createMemoryObject("OutputIdeasMemory");
+ HabitExecutionerCodelet hec = new HabitExecutionerCodelet("test");
+ hec.addInput(mc);
+ hec.addInput(moi);
+ hec.addOutput(moo);
+
+ m.insertCodelet(hec);
+ m.start();
+
+ try {
+ while(exec_counter < 5) { System.out.print("."); Thread.sleep(1); }
+ } catch (Exception e) {
+ fail("An error occurred: " + e.getMessage());
+ }
+ assertEquals(outputSetter, hec.h, "Habit should be the same as the one set in the container with name: " + name);
+ }
+ }
+
+ @Test
+ public void testHabitsContainerNameNotMatching() {
+ System.out.println("\nTesting the case where there is one Habit Memory Container with incorrect name");
+
+ String[] nonMatchingNames = {"someOtherName", "habitsTest", "test_habits", "testhabit"};
+
+ // Test non-matching names (should not find habit)
+ for (String name : nonMatchingNames) {
+ System.out.println("\nTesting with container name: " + name);
+
+ proc_counter = 0;
+ MockHabits mh = new MockHabits();
+ outputSetter = mh.outputSetter;
+ m = new Mind();
+ mc = m.createMemoryContainer(name);
+ Idea osh = new Idea("OutputSetter");
+ osh.setValue(outputSetter);
+ osh.setScope(2);
+ mc.setI(osh);
+ moi = m.createMemoryObject("InputIdeasMemory");
+ moo = m.createMemoryObject("OutputIdeasMemory");
+ HabitExecutionerCodelet hec = new HabitExecutionerCodelet("test") {
+ @Override
+ public void proc() {
+ proc_counter++;
+ super.proc();
+ }
+ };
+ hec.addInput(mc);
+ hec.addInput(moi);
+ hec.addOutput(moo);
+
+ m.insertCodelet(hec);
+ m.start();
+
+ try {
+ while(proc_counter < 5) { System.out.print("."); Thread.sleep(1); }
+ } catch (Exception e) {
+ fail("An error occurred: " + e.getMessage());
+ }
+ assertNull(hec.h, "Habit should be null for container name: " + name);
+ }
+ }
+
+ // Test case for when there is one Habit Memory Container with correct name and one without
+ // In this case, the codelet should find the habit in the container with the correct name
+ // and add the other habit to the root idea, but not execute it
+ @Test
+ public void testDoubleHabitContainers() {
+ System.out.println("\nTesting the case where there are two habit memory containers, one with the correct name and one without");
+
+ proc_counter = 0;
+ m = new Mind();
+
+ MockHabits mh = new MockHabits();
+ outputSetter = mh.outputSetter;
+ mc = m.createMemoryContainer("testHabits");
+ Idea osh = new Idea("OutputSetter");
+ osh.setValue(outputSetter);
+ osh.setScope(2);
+ mc.setI(osh);
+
+ notExecuted = mh.notExecuted;
+ MemoryContainer mc2 = m.createMemoryContainer("someOtherName");
+ Idea neh = new Idea("NotExecuted");
+ neh.setValue(notExecuted);
+ neh.setScope(2);
+ mc2.setI(neh);
+
+ moi = m.createMemoryObject("InputIdeasMemory");
+ moo = m.createMemoryObject("OutputIdeasMemory");
+ HabitExecutionerCodelet hec = new HabitExecutionerCodelet("test") {
+ @Override
+ public void proc() {
+ proc_counter++;
+ super.proc();
+ }
+ };
+ hec.addInput(mc);
+ hec.addInput(mc2);
+ hec.addInput(moi);
+ hec.addOutput(moo);
+
+ m.insertCodelet(hec);
+ m.start();
+
+ try {
+ while(proc_counter < 5) { System.out.print("."); Thread.sleep(1); }
+ } catch (Exception e) {
+ fail("An error occurred: " + e.getMessage());
+ }
+
+ // Should find the habit in the container with the correct name
+ assertEquals(outputSetter, hec.h, "Habit should not be null for container with correct name");
+
+ Idea habit_input = global_idea.get("NotExecuted");
+ // The other habit should be added to the root idea, but not executed
+ assertEquals(habit_input, neh, "The habit in the container with incorrect name should be added to the root idea");
+ }
+
+ @Test
+ public void testNullIdea() {
+ System.out.println("\nTesting the case where the habit returns a null idea");
+
+ exec_counter = 0;
+
+ MockHabits mh = new MockHabits();
+ nullIdeaSetter = mh.nullIdeaSetter;
+ m = new Mind();
+ mc = m.createMemoryContainer("testHabits");
+ Idea nish = new Idea("NullIdeaSetter");
+ nish.setValue(nullIdeaSetter);
+ nish.setScope(2);
+ mc.setI(nish);
+ moi = m.createMemoryObject("InputIdeasMemory");
+ moo = m.createMemoryObject("OutputIdeasMemory");
+ HabitExecutionerCodelet hec = new HabitExecutionerCodelet("test");
+ hec.addInput(mc);
+ hec.addInput(moi);
+ hec.addOutput(moo);
+
+ m.insertCodelet(hec);
+ m.start();
+
+ try {
+ while(exec_counter < 5) { System.out.print("."); Thread.sleep(1); }
+ } catch (Exception e) {
+ fail("An error occurred: " + e.getMessage());
+ }
+ assertEquals(5, exec_counter, "The habit should have been executed 5 times without errors");
+ }
+
+ @Test
+ public void testEmptyIdea() {
+ System.out.println("\nTesting the case where the habit returns an empty idea");
+
+ exec_counter = 0;
+
+ MockHabits mh = new MockHabits();
+ emptyIdeaSetter = mh.emptyIdeaSetter;
+ m = new Mind();
+ mc = m.createMemoryContainer("testHabits");
+ Idea eish = new Idea("EmptyIdeaSetter");
+ eish.setValue(emptyIdeaSetter);
+ eish.setScope(2);
+ mc.setI(eish);
+ moi = m.createMemoryObject("InputIdeasMemory");
+ moo = m.createMemoryObject("OutputIdeasMemory");
+ HabitExecutionerCodelet hec = new HabitExecutionerCodelet("test");
+ hec.addInput(mc);
+ hec.addInput(moi);
+ hec.addOutput(moo);
+
+ m.insertCodelet(hec);
+ m.start();
+
+ try {
+ while(exec_counter < 5) { System.out.print("."); Thread.sleep(1); }
+ } catch (Exception e) {
+ fail("An error occurred: " + e.getMessage());
+ }
+ assertEquals(5, exec_counter, "The habit should have been executed 5 times without errors");
+ }
+
+ @Test
+ public void testSettingIdeaMemoryObject() {
+ System.out.println("\nTesting the case where the habit sets an idea to an output memory object");
+
+ exec_counter = 0;
+
+ MockHabits mh = new MockHabits();
+ outputSetter = mh.outputSetter;
+ m = new Mind();
+ mc = m.createMemoryContainer("testHabits");
+ Idea osh = new Idea("OutputSetter");
+ osh.setValue(outputSetter);
+ osh.setScope(2);
+ mc.setI(osh);
+ moi = m.createMemoryObject("InputIdeasMemory");
+ moo = m.createMemoryObject("OutputIdeasMemory");
+ HabitExecutionerCodelet hec = new HabitExecutionerCodelet("test");
+ hec.addInput(mc);
+ hec.addInput(moi);
+ hec.addOutput(moo);
+
+ m.insertCodelet(hec);
+ m.start();
+
+ try {
+ while(exec_counter < 5) { System.out.print("."); Thread.sleep(1); }
+ } catch (Exception e) {
+ fail("An error occurred: " + e.getMessage());
+ }
+ assertEquals(5, exec_counter, "The habit should have been executed 5 times without errors");
+
+ Object oo = moo.getI();
+ if (oo != null) {
+ Idea ooi = (Idea) oo;
+ int val = (int) ooi.getValue();
+ assertEquals(13, val, "The value set in the output memory object should be 13");
+ }
+ else fail("The output memory object is null");
+ }
+
+ @Test
+ public void testSettingIdeaMemoryContainer() {
+ System.out.println("\nTesting the case where the habit sets an idea to an output memory container");
+
+ exec_counter = 0;
+
+ MockHabits mh = new MockHabits();
+ outputSetter = mh.outputSetter;
+ m = new Mind();
+ mc = m.createMemoryContainer("testHabits");
+ Idea osh = new Idea("OutputSetter");
+ osh.setValue(outputSetter);
+ osh.setScope(2);
+ mc.setI(osh);
+ moi = m.createMemoryObject("InputIdeasMemory");
+ MemoryContainer moc = m.createMemoryContainer("OutputIdeasMemory");
+ HabitExecutionerCodelet hec = new HabitExecutionerCodelet("test");
+ hec.addInput(mc);
+ hec.addInput(moi);
+ hec.addOutput(moc);
+
+ m.insertCodelet(hec);
+ m.start();
+
+ try {
+ while(exec_counter < 5) { System.out.print("."); Thread.sleep(1); }
+ } catch (Exception e) {
+ fail("An error occurred: " + e.getMessage());
+ }
+ assertEquals(5, exec_counter, "The habit should have been executed 5 times without errors");
+
+ Object oo = moc.getLastI();
+ if (oo != null) {
+ Idea ooi = (Idea) oo;
+ int val = (int) ooi.getValue();
+ assertEquals(13, val, "The value set in the output memory container should be 13");
+ }
+ else fail("The output memory container is empty");
+ }
+
+ @Test
+ public void testSettingTwoIdeasTwoMemories() {
+ System.out.println("\nTesting the case where the habit sets two ideas to two output memories");
+
+ exec_counter = 0;
+
+ MockHabits mh = new MockHabits();
+ outputSetter = mh.outputSetter;
+ m = new Mind();
+ mc = m.createMemoryContainer("testHabits");
+ Idea osh = new Idea("OutputSetter");
+ osh.setValue(outputSetter);
+ osh.setScope(2);
+ mc.setI(osh);
+ moi = m.createMemoryObject("InputIdeasMemory");
+ MemoryContainer moc = m.createMemoryContainer("OutputIdeasMemory");
+ moo = m.createMemoryObject("anotherIdea");
+ HabitExecutionerCodelet hec = new HabitExecutionerCodelet("test");
+ hec.addInput(mc);
+ hec.addInput(moi);
+ hec.addOutput(moc);
+ hec.addOutput(moo);
+
+ m.insertCodelet(hec);
+ m.start();
+
+ try {
+ while(exec_counter < 5) { System.out.print("."); Thread.sleep(1); }
+ } catch (Exception e) {
+ fail("An error occurred: " + e.getMessage());
+ }
+ assertEquals(5, exec_counter, "The habit should have been executed 5 times without errors");
+
+ Object oo = moc.getLastI();
+ if (oo != null) {
+ Idea ooi = (Idea) oo;
+ int val = (int) ooi.getValue();
+ assertEquals(13, val, "The value set in the first output memory container should be 13");
+ }
+ else fail("The first output memory container is empty");
+
+ oo = moo.getI();
+ if (oo != null) {
+ Idea ooi = (Idea) oo;
+ String val = (String) ooi.getValue();
+ assertEquals("abc", val, "The value set in the second output memory object should be 'abc'");
+ }
+ else fail("The second output memory object is null");
+ }
+
+ class MockHabits {
+ public MockHabits() {
+ }
+
+ Habit summer = new Habit() {
+ @Override
+ public Idea exec(Idea idea) {
+ exec_counter++;
+
+ Idea root = new Idea("root", "");
+ Idea adder = idea.get("value.add");
+ int valuetoadd=0;
+ if (adder != null && adder.getValue() instanceof Integer) {
+ valuetoadd = (int) adder.getValue();
+ }
+ if (idea.get("value").getValue() instanceof Integer) {
+ int number = (int) idea.get("value").getValue();
+ Idea modifiedIdea = new Idea("OutputIdeasMemory",number+valuetoadd);
+ root.add(modifiedIdea);
+ return root;
+ }
+ System.out.println("Something wrong happened");
+ return(null);
+ }
+ };
+
+ Habit decrementer = new Habit() {
+ @Override
+ public Idea exec(Idea idea) {
+ exec_counter++;
+
+ Idea root = new Idea("root", "");
+ Idea adder = idea.get("value.add");
+ int valuetodec=0;
+ if (adder != null && adder.getValue() instanceof Integer) {
+ valuetodec = (int) adder.getValue();
+ }
+ if (idea.get("value").getValue() instanceof Integer) {
+ int number = (int) idea.get("value").getValue();
+ Idea modifiedIdea = new Idea("OutputIdeasMemory",number-valuetodec);
+ root.add(modifiedIdea);
+ return root;
+ }
+ System.out.println("Something wrong happened");
+ return(null);
+ }
+ };
+
+ Habit actSetter = new Habit() {
+ @Override
+ public Idea exec(Idea idea) {
+ exec_counter++;
+
+ Idea root = new Idea("root", "");
+ root.add(new Idea("activation", act));
+ root.add(new Idea("someIdea", 123));
+ root.add(new Idea("anotherIdea", "abc"));
+ return root;
+ }
+ };
+
+ Habit timeStepSetter = new Habit() {
+ @Override
+ public Idea exec(Idea idea) {
+ exec_counter++;
+
+ Idea root = new Idea("root", "");
+ root.add(new Idea("timeStep", timeStep));
+ root.add(new Idea("someIdea", 123));
+ root.add(new Idea("anotherIdea", "abc"));
+ return root;
+ }
+ };
+
+ Habit publishSubscribeSetter = new Habit() {
+ @Override
+ public Idea exec(Idea idea) {
+ exec_counter++;
+
+ Idea root = new Idea("root", "");
+ root.add(new Idea("publishSubscribe", publishSubscribe));
+ root.add(new Idea("someIdea", 123));
+ root.add(new Idea("anotherIdea", "abc"));
+ return root;
+ }
+ };
+
+ Habit outputSetter = new Habit() {
+ @Override
+ public Idea exec(Idea idea) {
+ exec_counter++;
+ global_idea = idea;
+
+ Idea root = new Idea("root", "");
+ root.add(new Idea("someIdea", 123));
+ root.add(new Idea("anotherIdea", "abc"));
+ root.add(new Idea("OutputIdeasMemory", 13));
+ return root;
+ }
+ };
+
+ Habit notExecuted = new Habit() {
+ @Override
+ public Idea exec(Idea idea) {
+ exec_counter++;
+
+ Idea root = new Idea("root", "");
+ root.add(new Idea("OutputIdeasMemory", 9999));
+ return root;
+ }
+ };
+
+ Habit nullIdeaSetter = new Habit() {
+ @Override
+ public Idea exec(Idea idea) {
+ exec_counter++;
+
+ return null;
+ }
+ };
+
+ Habit emptyIdeaSetter = new Habit() {
+ @Override
+ public Idea exec(Idea idea) {
+ exec_counter++;
+
+ return new Idea("root", "");
+ }
+ };
+ }
+}
\ No newline at end of file