diff --git a/README.md b/README.md
index 206046d0..f1474d82 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.4.1'
+ implementation 'com.github.CST-Group:cst:1.4.2'
}
```
@@ -53,7 +53,7 @@ Sometimes, the version number (tag) in this README gets out of date, as maintain
com.github.CST-Group
cst
- 1.4.1
+ 1.4.2
```
diff --git a/build.gradle b/build.gradle
index c0c25090..caa262cf 100644
--- a/build.gradle
+++ b/build.gradle
@@ -17,7 +17,7 @@ java {
}
-version = '1.4.0'
+version = '1.4.2'
repositories {
mavenCentral()
diff --git a/src/main/java/br/unicamp/cst/core/entities/MemoryContainer.java b/src/main/java/br/unicamp/cst/core/entities/MemoryContainer.java
index 7379405e..b97b81fd 100755
--- a/src/main/java/br/unicamp/cst/core/entities/MemoryContainer.java
+++ b/src/main/java/br/unicamp/cst/core/entities/MemoryContainer.java
@@ -46,7 +46,7 @@ public class MemoryContainer implements Memory {
*/
private String name;
- public enum Policy {MAX, MIN, RANDOM_FLAT, RANDOM_PROPORTIONAL, ITERATE};
+ public enum Policy {MAX, MIN, RANDOM_FLAT, RANDOM_FLAT_STABLE, RANDOM_PROPORTIONAL, RANDOM_PROPORTIONAL_STABLE, ITERATE};
/**
* Policy used for selecting a MemoryObject at the MemoryContainer
@@ -56,6 +56,7 @@ public enum Policy {MAX, MIN, RANDOM_FLAT, RANDOM_PROPORTIONAL, ITERATE};
private volatile Memory last;
private volatile int lasti=0;
private transient Random rand = new Random();
+ private transient int randchoice = -1;
/**
* Creates a MemoryContainer.
@@ -142,8 +143,8 @@ else if (memoryEval == maxEval) {
}
}
if (allmax.size() > 1) {
- int i = rand.nextInt(allmax.size());
- last = allmax.get(i);
+ if (randchoice < 0) randchoice = rand.nextInt(allmax.size());
+ last = allmax.get(randchoice);
return(last.getI());
}
else {
@@ -176,8 +177,8 @@ else if (memoryEval == minEval) {
}
}
if (allmin.size() > 1) {
- int i = rand.nextInt(allmin.size());
- last = allmin.get(i);
+ if (randchoice < 0) randchoice = rand.nextInt(allmin.size());
+ last = allmin.get(randchoice);
return(last.getI());
}
else {
@@ -201,8 +202,21 @@ private synchronized Object getIRandomFlat() {
/**
* Gets the info of a random memory from within the MemoryContainer.
+ * In this case, the choice will only change after a change in the container
*
- * @return the info of a random memory within the MemoryContainer
+ * @return the info of a random memory within the MemoryContainer (stable version)
+ */
+ private synchronized Object getIRandomFlatStable() {
+
+ if (randchoice < 0) randchoice = rand.nextInt(memories.size());
+ last = memories.get(randchoice);
+ return(last.getI());
+ }
+
+ /**
+ * Gets the info of a random memory from within the MemoryContainer using eval as a weight.
+ *
+ * @return the info of a random memory within the MemoryContainer using eval as a weight
*/
private synchronized Object getIRandomProportional() {
@@ -232,9 +246,42 @@ private synchronized Object getIRandomProportional() {
}
/**
- * Gets the info of a random memory from within the MemoryContainer.
+ * Gets the info of a random memory from within the MemoryContainer using eval as a weight.
*
- * @return the info of a random memory within the MemoryContainer
+ * @return the info of a random memory within the MemoryContainer using eval as a weight
+ */
+ private synchronized Object getIRandomProportionalStable() {
+
+ if (memories.size() == 0) return null;
+ double indexfrom[] = new double[memories.size()];
+ double indexto[] = new double[memories.size()];
+ int i = 0;
+ for (Memory memory : memories) {
+ if (i == 0)
+ indexfrom[i] = 0;
+ else
+ indexfrom[i] = indexto[i-1];
+ double interval = memory.getEvaluation();
+ indexto[i] = indexfrom[i] + interval;
+ i++;
+ }
+ double llast = indexto[i-1];
+ double wheel = rand.nextDouble();
+ if (llast*wheel == 0) return(getIRandomFlatStable());
+ for (int j=0;j<=memories.size();j++)
+ if (indexfrom[j] < wheel*llast && wheel*llast < indexto[j]) {
+ if (randchoice < 0) randchoice = j;
+ last = memories.get(randchoice);
+ return(last.getI());
+ }
+ last = memories.get(0);
+ return(last.getI());
+ }
+
+ /**
+ * Gets the info of a memory from within the MemoryContainer in an iterative way.
+ *
+ * @return the info of a memory within the MemoryContainer in an iterative way
*/
private synchronized Object getIIterate() {
if (memories.size() > 0 && lasti < memories.size()) {
@@ -253,7 +300,9 @@ private synchronized Object getIIterate() {
* Policy.MAX
* Policy.MIN
* Policy.RANDOM_FLAT
+ * Policy.RANDOM_FLAT_STABLE
* Policy.RANDOM_PROPORTIONAL
+ * Policy.RANDOM_PROPORTIONAL_STABLE
* Policy.ITERATE
*
* @return the info of the memory according to the specified MemoryContainer policy
@@ -264,7 +313,9 @@ public synchronized Object getI() {
case MAX: return getIMax();
case MIN: return getIMin();
case RANDOM_FLAT: return getIRandomFlat();
+ case RANDOM_FLAT_STABLE: return getIRandomFlatStable();
case RANDOM_PROPORTIONAL: return getIRandomProportional();
+ case RANDOM_PROPORTIONAL_STABLE: return getIRandomProportionalStable();
case ITERATE: return getIIterate();
default: return getIMax();
}
@@ -390,7 +441,8 @@ public synchronized int setI(Object info) {
*/
public synchronized int setI(Object info, Double evaluation) {
- MemoryObject mo = new MemoryObject();
+ randchoice = -1;
+ MemoryObject mo = new MemoryObject();
mo.setI(info);
if (evaluation != -1.0)
mo.setEvaluation(evaluation);
@@ -408,6 +460,7 @@ public synchronized int setI(Object info, Double evaluation) {
* @param index the index of the memory inside the container.
*/
public synchronized void setI(Object info, int index) {
+ randchoice = -1;
if (memories != null && memories.size() > index) {
Memory memory = memories.get(index);
if (memory != null) {
@@ -430,6 +483,7 @@ public synchronized void setI(Object info, int index) {
* @param evaluation the evaluation to be set.
*/
public synchronized void setI(Object info, Double evaluation, int index) {
+ randchoice = -1;
if (memories != null && memories.size() > index) {
Memory memory = memories.get(index);
if (memory != null) {
@@ -454,6 +508,7 @@ public synchronized void setI(Object info, Double evaluation, int index) {
* @return the index of the memory
*/
public synchronized int setI(Object info, double evaluation, String type) {
+ randchoice = -1;
int index = -1;
if (memories != null) {
boolean set = false;
@@ -529,6 +584,7 @@ public synchronized String getName() {
*/
@Override
public synchronized void setEvaluation(Double eval) {
+ randchoice = -1;
if (last != null && last instanceof Memory) {
last.setEvaluation(eval);
}
@@ -542,6 +598,7 @@ public synchronized void setEvaluation(Double eval) {
* @param index the index of the memory inside this container.
*/
public synchronized void setEvaluation(Double eval, int index) {
+ randchoice = -1;
if (memories != null && memories.size() > index) {
Memory memory = memories.get(index);
if (memory != null) {
@@ -561,6 +618,7 @@ public synchronized void setEvaluation(Double eval, int index) {
* @return the index of the added memory
*/
public synchronized int add(Memory memory) {
+ randchoice = -1;
int index = -1;
if (memory != null) {
memories.add(memory);
@@ -707,6 +765,7 @@ public synchronized void removeMemoryObserver(MemoryObserver memoryObserver) {
* @param pol the new Policy to be used
*/
public void setPolicy(Policy pol) {
+ randchoice = -1;
policy = pol;
}
diff --git a/src/main/java/br/unicamp/cst/core/entities/Mind.java b/src/main/java/br/unicamp/cst/core/entities/Mind.java
index 0fc3f6b7..c2099bbc 100755
--- a/src/main/java/br/unicamp/cst/core/entities/Mind.java
+++ b/src/main/java/br/unicamp/cst/core/entities/Mind.java
@@ -14,6 +14,8 @@
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
/**
* This class represents the Mind of the agent, wrapping all the CST's core
@@ -75,7 +77,7 @@ public synchronized void createCodeletGroup(String groupName) {
*
*/
public synchronized void createMemoryGroup(String groupName) {
- ArrayList group = new ArrayList();
+ ArrayList group = new ArrayList();
memoryGroups.put(groupName,group);
}
@@ -276,7 +278,8 @@ public Codelet insertCodelet(Codelet co, String groupName) {
*/
public void registerCodelet(Codelet co, String groupName) {
ArrayList groupList = codeletGroups.get(groupName);
- if (groupList != null) groupList.add(co);
+ if (groupList != null) groupList.add(co);
+ else Logger.getAnonymousLogger().log(Level.INFO,"The Codelet Group {0} still does not have been created ... create it first with createCodeletGroup",groupName);
}
/**
@@ -287,7 +290,8 @@ public void registerCodelet(Codelet co, String groupName) {
*/
public void registerMemory(Memory m, String groupName) {
ArrayList groupList = memoryGroups.get(groupName);
- if (groupList != null) groupList.add(m);
+ if (groupList != null) groupList.add(m);
+ else Logger.getAnonymousLogger().log(Level.INFO,"The Memory Group {0} still does not have been created ... create it first with createMemoryGroup",groupName);
}
diff --git a/src/main/java/br/unicamp/cst/representation/idea/Idea.java b/src/main/java/br/unicamp/cst/representation/idea/Idea.java
index 35066f14..e52cd8a9 100644
--- a/src/main/java/br/unicamp/cst/representation/idea/Idea.java
+++ b/src/main/java/br/unicamp/cst/representation/idea/Idea.java
@@ -11,11 +11,17 @@
package br.unicamp.cst.representation.idea;
import br.unicamp.cst.support.ToString;
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.ToNumberPolicy;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
+import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
@@ -26,8 +32,7 @@
import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import org.slf4j.LoggerFactory;
/**
@@ -44,6 +49,7 @@ public class Idea implements Category,Habit {
private String category;
private int scope=1; // 0: possibility, 1: existence, 2: law
private transient IdeaComparator ideaComparator = new IdeaComparator();
+ private static transient Logger logger = (Logger) LoggerFactory.getLogger(Idea.class);
// This list is used while building a toStringFull()
/**
* The repo hashmap is a list of known Ideas used by the createIdea factory method to
@@ -495,12 +501,76 @@ public int getType() {
return type;
}
+ private void correctCategoryAndScope() {
+ switch(type) {
+ case 0:setCategory("AbstractObject");
+ setScope(1);
+ break;
+ case 1:setCategory("Property");
+ setScope(1);
+ break;
+ case 2://2 - Link or Reference to another Idea
+ setCategory("Link");
+ break;
+ case 3:setCategory("QualityDimension");
+ setScope(1);
+ break;
+ case 4:setCategory("Episode");
+ setScope(1);
+ break;
+ case 5://5 - Composite
+ setCategory("Composite");
+ break;
+ case 6://6 - Aggregate
+ setCategory("Aggregate");
+ break;
+ case 7:// 7 - Configuration
+ setCategory("Configuration");
+ break;
+ case 8:setCategory("TimeStep");
+ break;
+ case 9:setCategory("Property");
+ setScope(2);
+ break;
+ case 10:setCategory("AbstractObject");
+ setScope(2);
+ break;
+ case 11:setCategory("Episode");
+ setScope(2);
+ break;
+ case 12:setCategory("Property");
+ setScope(0);
+ break;
+ case 13:setCategory("AbstractObject");
+ setScope(0);
+ break;
+ case 14:setCategory("Episode");
+ setScope(0);
+ break;
+ case 15:setCategory("Action");
+ setScope(0);
+ break;
+ case 16:setCategory("Action");
+ setScope(1);
+ break;
+ case 17:setCategory("Action");
+ setScope(2);
+ break;
+ case 18:setCategory("Goal");
+ setScope(1);
+ break;
+ default:break;
+
+ }
+ }
+
/**
* This method is used to set a new type for the Idea
* @param type the new type assigned to the Idea
*/
public void setType(int type) {
this.type = type;
+ correctCategoryAndScope();
}
/**
@@ -596,7 +666,7 @@ public boolean isLong() {
* @return a boolean indicating if the value of the current Idea is a number.
*/
public boolean isNumber() {
- if (isFloat() || isDouble() || isLong() || isInteger()) return(true);
+ if (isFloat() || isDouble() || isLong() || isInteger() || value instanceof Short || value instanceof Byte) return(true);
return(false);
}
@@ -816,7 +886,7 @@ else if (classname.equals(CBOOLEAN)) {
javaObject = type.getDeclaredConstructor().newInstance();
type.cast(javaObject);
} catch (Exception e) {
- Logger.getAnonymousLogger().log(Level.INFO, "The class name {0} is not on the Java Library Path !", classname);
+ logger.info("The class name {0} is not on the Java Library Path !", classname);
}
return (javaObject);
}
@@ -1220,6 +1290,7 @@ else if (obj instanceof Idea) {
Idea ao = (Idea) obj;
child.add(ao);
this.add(child);
+ //this.add((Idea)obj);
listtoavoidloops.add(obj); // should I include obj or child here ?
return;
}
@@ -1236,17 +1307,19 @@ else if (obj instanceof Idea) {
int modifiers = field.getModifiers();
if (Modifier.isStatic(modifiers)) fo = field.get(null);
else fo = field.get(obj);
+ //System.out.println("Field "+fname+" with value "+fo+" is accessible");
}
else { // if it is inaccessible, check if it is a bean, before giving up
fo = checkIfObjectHasSetGet(obj, fname);
if (fo != null && fo.equals("<>")) {
+ // This is the case the field is inaccessible and DOES NOT have a get Method
String mod = fname+":";
if (Modifier.isStatic(field.getModifiers())) mod+=" STATIC";
if (Modifier.isProtected(field.getModifiers())) mod+=" PROTECTED";
if (Modifier.isPrivate(field.getModifiers())) mod+=" PRIVATE";
if (Modifier.isTransient(field.getModifiers())) mod+=" TRANSIENT";
if (Modifier.isVolatile(field.getModifiers())) mod+=" VOLATILE";
- Logger.getAnonymousLogger().log(Level.INFO,mod);
+ //Logger.getAnonymousLogger().log(Level.INFO,"The field "+getFullName()+"."+ToString.getSimpleName(fullname)+"."+mod+" is inaccessible while being proceessed by addObject and does not hava a get method ! It will not be included in the Idea");
}
}
if (fo != null && fo.equals("<>")) {
@@ -1254,14 +1327,16 @@ else if (obj instanceof Idea) {
}
else if (!already_exists(fo)) {
ao.addObject(fo,fname,false);
+ //System.out.println("Inserting a new idea with name "+fname+" with value "+fo);
}
else { // this is the case when a recursive object is detected ... inserting a link
String ideaname = getFullName()+"."+ToString.getSimpleName(fullname)+"."+fname;
+ //System.out.println("Im inserting a link "+fname+" here: "+ideaname);
Idea fi = createIdea(ideaname,"",2);
ao.add(fi);
}
} catch (Exception e) {
- Logger.getAnonymousLogger().log(Level.INFO,"I got a {0} Exception in field {1} in class Idea: {2}",new Object[]{e.getClass().getName(),fname,e.getMessage()+"-->"+e.getLocalizedMessage()});
+ logger.info("I got a {0} Exception in field {1} in class Idea: {2}",new Object[]{e.getClass().getName(),fname,e.getMessage()+"-->"+e.getLocalizedMessage()});
}
}
this.add(ao);
@@ -1312,7 +1387,9 @@ public double membership(Idea idea) {
* @return true if this idea is a Category or false otherwise
*/
public boolean isCategory() {
- if (getValue() instanceof Category) return(true);
+ Object val = getValue();
+ if (val instanceof Idea) return(((Idea) value).isCategory());
+ else if (getValue() instanceof Category) return(true);
else return(false);
}
@@ -1322,6 +1399,8 @@ public boolean isCategory() {
* @return true if this idea is a Habit or false otherwise
*/
public boolean isHabit() {
+ Object val = getValue();
+ if (val instanceof Idea) return(((Idea) value).isHabit());
if (getValue() instanceof Habit) return(true);
else return(false);
}
@@ -1334,5 +1413,116 @@ public boolean isLeaf() {
return this.l.isEmpty();
}
+ public String toJSON() {
+ Gson gson;
+ //gson = new GsonBuilder().registerTypeAdapter(Idea.class, new InterfaceAdapter())
+ // .setPrettyPrinting().create();
+ //gson = new Gson();
+ gson = new GsonBuilder().setPrettyPrinting().setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE).create();
+ String out = "";
+ try {
+ out = gson.toJson(this);
+ } catch(Error e) {
+ logger.info("It was not possible to generate a version of the idea {0}",this.getFullName());
+ }
+ return(out);
+ }
+
+ public static Idea fromJSON(String idea_json) {
+ Gson gson;
+ //gson = new GsonBuilder().registerTypeAdapter(Idea.class, new InterfaceAdapter())
+ // .setPrettyPrinting().create();
+ //gson = new Gson();
+ gson = new GsonBuilder().setPrettyPrinting().setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE).create();
+ Idea i = null;
+ try {
+ i = gson.fromJson(idea_json, Idea.class);
+ } catch(Error e) {
+ logger.info("It was not possible to generate an idea from the given String ... creating a null Idea");
+ }
+ return(i);
+ }
+
+ public boolean equals(Idea other) {
+ if (this != null && other == null) return(false);
+ boolean out = true;
+ out &= this.getFullName().equals(other.getFullName());
+ if (this.getValue() == null && other.getValue() != null ||
+ this.getValue() != null && other.getValue() == null) {
+ System.out.println("Values are different ..."+this.getName()+": "+this.getValue()+" ("+this.getValue().getClass().getCanonicalName()+") "+other.getName()+": "+other.getValue()+" ("+other.getValue().getClass().getCanonicalName()+")");
+ return(false);
+ }
+ else if (this.getValue() == null && other.getValue() == null) {
+ // do nothing
+ }
+ else {
+ boolean valuediff;
+ if (this.isNumber() && other.isNumber()) {
+ //System.out.println("OK, "+this.getName()+" and "+other.getName()+" are both numbers");
+ BigDecimal t = new BigDecimal(0);
+ if (this.getValue() instanceof Integer) t = new BigDecimal((Integer)this.getValue());
+ else if (this.getValue() instanceof Long) t = new BigDecimal((Long)this.getValue());
+ else if (this.getValue() instanceof Short) t = new BigDecimal((Short)this.getValue());
+ else if (this.getValue() instanceof Byte) t = new BigDecimal((Byte)this.getValue());
+ else if (this.getValue() instanceof Float) t = new BigDecimal((Float)this.getValue());
+ else if (this.getValue() instanceof Double) t = new BigDecimal((Double)this.getValue());
+ BigDecimal o = new BigDecimal(0);
+ if (other.getValue() instanceof Integer) o = new BigDecimal((Integer)other.getValue());
+ else if (other.getValue() instanceof Long) o = new BigDecimal((Long)other.getValue());
+ else if (other.getValue() instanceof Short) o = new BigDecimal((Short)other.getValue());
+ else if (other.getValue() instanceof Byte) o = new BigDecimal((Byte)other.getValue());
+ else if (other.getValue() instanceof Float) o = new BigDecimal((Float)other.getValue());
+ else if (other.getValue() instanceof Double) o = new BigDecimal((Double)other.getValue());
+ //valuediff = t.compareTo(o) == 0;
+ valuediff = t.floatValue() == o.floatValue();
+ if (valuediff == false) {
+ System.out.println("t."+this.getFullName()+": "+t+" o."+other.getFullName()+": "+o);
+ }
+
+ }
+ else {
+ valuediff = this.getValue().equals(other.getValue());
+ if (valuediff == false) System.out.println("Hmmm, "+this.getName()+" and "+other.getName()+" are not both numbers");
+ }
+ if (valuediff == false) System.out.println("Values are different ..."+this.getName()+": "+this.getValue()+" ("+this.getValue().getClass().getCanonicalName()+") "+other.getName()+": "+other.getValue()+" ("+other.getValue().getClass().getCanonicalName()+")");
+ out &= valuediff;
+ if (out == false) return(out);
+ }
+ long lt = this.getType();
+ long lo = other.getType();
+ out &= lt == lo;
+ if (out == false) {
+ System.out.println("Types are different ..."+this.getName()+": "+lt+" "+other.getName()+": "+lo);
+ return(out);
+ }
+ if (this.getCategory() == null && other.getCategory() != null ||
+ this.getCategory() != null && other.getCategory() == null) {
+ System.out.println("Categories are different ..."+this.getName()+": "+this.getCategory()+" "+other.getName()+": "+other.getCategory());
+ return(false);
+ }
+ else if (this.getCategory() == null && other.getCategory() == null) {
+ // do nothing
+ }
+ else {
+ out &= this.getCategory().equals(other.getCategory());
+ if (out == false) System.out.println("Categories are different ..."+this.getName()+": "+this.getCategory()+" "+other.getName()+": "+other.getCategory());
+ }
+ out &= this.getScope() == other.getScope();
+ if (this.getL().size() == other.getL().size()) {
+ for (int i=0;i 0) assertEquals(oldi,i);
+ }
+ int i2;
+ int k=0;
+ do {
+ // Changing I will trigger a different choice, though !
+ memoryContainer.setI(1,m1);
+ memoryContainer.setI(2,m2);
+ memoryContainer.setI(3,m3);
+ i2 = (int) memoryContainer.getI();
+ k++;
+ } while (i2 == i && k < 100);
+ assertTrue(k != 100);
+ }
+
+ @Test
+ public void testMinPolicyWithSameEval() {
+ MemoryContainer memoryContainer = new MemoryContainer("MIN");
+ memoryContainer.setPolicy(Policy.MIN);
+ int m1 = memoryContainer.setI(1, 0.2D);
+ int m2 = memoryContainer.setI(2, 0.2D);
+ int m3 = memoryContainer.setI(3, 0.2D);
+ int i = -1;
+ int oldi = 0;
+ for (int j=0;j<10;j++) {
+ oldi = i;
+ // Despite the choice is random, if no chance in I happens, it stays the same
+ i = (int) memoryContainer.getI();
+ if (j > 0) assertEquals(oldi,i);
+ }
+ int i2;
+ int k=0;
+ do {
+ // Changing I will trigger a different choice, though !
+ memoryContainer.setI(1,m1);
+ memoryContainer.setI(2,m2);
+ memoryContainer.setI(3,m3);
+ i2 = (int) memoryContainer.getI();
+ k++;
+ } while (i2 == i && k < 100);
+ assertTrue(k != 100);
+ }
+
@Test
public void testMaxUniquePolicy() {
MemoryContainer memoryContainer = new MemoryContainer("MAX");
@@ -355,6 +411,39 @@ public void testRandomProportionalPolicy() {
assertEquals(count[2]>0,true);
}
+ @Test
+ public void testRandomProportionalStablePolicy() {
+ MemoryContainer memoryContainer = new MemoryContainer("RANDOMPROPORTIONALSTABLE");
+ memoryContainer.setPolicy(Policy.RANDOM_PROPORTIONAL_STABLE);
+ int n = memoryContainer.setI(1, 0.2D); // 14%
+ memoryContainer.setI(2, 0.4D); // 28%
+ memoryContainer.setI(3, 0.8D); // 57%
+ int count[] = new int[3];
+ int first = 0;
+ for (int i=0;i<1000;i++) {
+ int j = (int) memoryContainer.getI();
+ if (i==0) first = j-1;
+ count[j-1]++;
+ }
+ //System.out.println("[0]: "+count[0]+" [1]: "+count[1]+" [2]: "+count[2]+" first:"+first);
+ for (int i=0;i<3;i++) {
+ if (i == first) assertEquals(count[i]>0,true);
+ else assertEquals(count[i]>0,false);
+ }
+ count[0] = 0;
+ count[1] = 0;
+ count[2] = 0;
+ for (int i=0;i<1000;i++) {
+ memoryContainer.setI(1,0.2D,n);
+ int j = (int) memoryContainer.getI();
+ count[j-1]++;
+ }
+ //System.out.println("[0]: "+count[0]+" [1]: "+count[1]+" [2]: "+count[2]);
+ assertEquals(count[0]0,true);
}
+ @Test
+ public void testRandomFlatStable() {
+ MemoryContainer memoryContainer = new MemoryContainer("RANDOMFLATSTABLE");
+ memoryContainer.setPolicy(Policy.RANDOM_FLAT_STABLE);
+ int n1 = memoryContainer.setI(1, 0.2D); // 14%
+ memoryContainer.setI(2, 0.4D); // 28%
+ memoryContainer.setI(3, 0.8D); // 57%
+ int count[] = new int[3];
+ int first=0;
+ for (int i=0;i<1000;i++) {
+ int j = (int) memoryContainer.getI();
+ if (i==0) first = j-1;
+ count[j-1]++;
+ }
+ for (int i=0;i<3;i++) {
+ if (i == first) assertEquals(count[i]>0,true);
+ else assertEquals(count[i]>0,false);
+ }
+ count[0] = 0;
+ count[1] = 0;
+ count[2] = 0;
+ for (int i=0;i<1000;i++) {
+ memoryContainer.setI(1, 0.2D, n1);
+ int j = (int) memoryContainer.getI();
+ if (i==0) first = j-1;
+ count[j-1]++;
+ }
+ assertEquals(count[0]>0,true);
+ assertEquals(count[1]>0,true);
+ assertEquals(count[2]>0,true);
+ }
+
@Test
public void testIteratePolicy() {
MemoryContainer memoryContainer = new MemoryContainer("ITERATE");
diff --git a/src/test/java/br/unicamp/cst/representation/idea/TestCategory.java b/src/test/java/br/unicamp/cst/representation/idea/TestCategory.java
index 2dcca3d2..87940365 100644
--- a/src/test/java/br/unicamp/cst/representation/idea/TestCategory.java
+++ b/src/test/java/br/unicamp/cst/representation/idea/TestCategory.java
@@ -10,8 +10,6 @@
***********************************************************************************************/
package br.unicamp.cst.representation.idea;
-import java.util.Arrays;
-import java.util.List;
import java.util.Random;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
diff --git a/src/test/java/br/unicamp/cst/representation/idea/TestIdea.java b/src/test/java/br/unicamp/cst/representation/idea/TestIdea.java
index 2ed30614..f7aa6132 100644
--- a/src/test/java/br/unicamp/cst/representation/idea/TestIdea.java
+++ b/src/test/java/br/unicamp/cst/representation/idea/TestIdea.java
@@ -23,11 +23,20 @@
import br.unicamp.cst.core.profiler.TestComplexMemoryObjectInfo;
import br.unicamp.cst.support.TimeStamp;
import br.unicamp.cst.support.ToString;
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.read.ListAppender;
import java.util.HashMap;
import java.util.Locale;
+
+import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import org.junit.jupiter.api.Test;
+import org.slf4j.LoggerFactory;
public class TestIdea {
@@ -474,8 +483,15 @@ public void cloneTest() {
static int maxid = 0; // To be used in TestAutoReference
+ public void printChildren(Idea id) {
+ System.out.println("Children of "+id.getFullName());
+ for (Idea i : id.getL()) {
+ System.out.println(i.getFullName()+" ");
+ }
+ }
+
private class TestAutoReference {
- int id;
+ public int id;
public TestAutoReference parent;
public ArrayList children = new ArrayList<>();
public TestAutoReference() {
@@ -502,16 +518,206 @@ public String toString() {
ar.add(ar2);
ar2.add(ar4);
ar.add(ar3);
- Idea i1 = Idea.createIdea("autoref",ar,1);
+ Idea i1 = Idea.createIdea("root",ar,1);
+ // Converting the complex ar object into Idea using addObject
i1.addObject(ar, "autoref");
- i1.addObject(ar, "autoref",false);
- i1.addObject(ar, "autoref2",false);
- Idea i2 = i1.get("autoref");
- i2.addObject(ar, "autoref",false);
- i1.addObject(i2, "autoref",false);
- System.out.println(i1.toStringFull());
- Idea i3 = i1.get("autoref.autoref");
- System.out.println(i3.toStringFull());
+ assertEquals(i1.get("autoref.id").getValue(),ar.id);
+ assertEquals(i1.get("autoref.children.children[0].id").getValue(),ar2.id);
+ assertEquals(i1.get("autoref.children.children[1].id").getValue(),ar3.id);
+ assertEquals(i1.get("autoref.children.children[0].children.children[0].id").getValue(),ar4.id);
+ // Creating a second level of reference to the same object
+ i1.get("autoref").addObject(ar, "autoref");
+ // This test checks if the original idea is different from the inner reference
+ assertNotEquals(i1.get("autoref.id"),i1.get("autoref.autoref.id"));
+ assertEquals(i1.get("autoref.id").getValue(),i1.get("autoref.autoref.id").getValue());
+ // Creating a second level of autoreference
+ i1.addObject(ar, "autoref2");
+ assertNotEquals(i1.get("autoref.id"),i1.get("autoref2.id"));
+ assertEquals(i1.get("autoref.id").getValue(),i1.get("autoref2.id").getValue());
+ Idea i3 = Idea.createIdea("autoref",null,1);
+ i3.add(i3);
+ Idea i4 = i3.get("autoref.autoref.autoref.autoref");
+ assertEquals(i4,i3);
+ System.out.println("i3:\n"+i3.toStringFull(true));
+ }
+
+ @Test public void testMistakenIsCategoryAndIsHabit() {
+ Idea iorig = new Idea();
+ assertEquals(iorig.isCategory(),false);
+ assertEquals(iorig.isHabit(),false);
+ Idea i1 = Idea.createIdea("notcategory",iorig,1);
+ assertEquals(i1.isCategory(),false);
+ assertEquals(i1.isHabit(),false);
+ Category cat = new Category() {
+ @Override
+ public double membership(Idea idea) {
+ //Check if belongs to category return membershipDegree;
+ return(1.0);
+ }
+ @Override
+ public Idea getInstance(Idea constraints) {
+ Idea id = new Idea("idea");
+ return(id);
+ }
+ };
+ iorig.setValue(cat);
+ assertEquals(i1.isCategory(),true);
+ assertEquals(i1.isHabit(),false);
+ Habit hab = new Habit() {
+ @Override
+ public Idea exec(Idea idea) {
+ Idea nid = new Idea("idea");
+ return(nid);
+ }
+ };
+ iorig.setValue(hab);
+ assertEquals(i1.isCategory(),false);
+ assertEquals(i1.isHabit(),true);
+ }
+
+ /* 0 - AbstractObject (Existent)
+ * 1 - Property (Existent)
+ * 2 - Link or Reference to another Idea
+ * 3 - QualityDimension
+ * 4 - Episode (Existent)
+ * 5 - Composite
+ * 6 - Aggregate
+ * 7 - Configuration
+ * 8 - TimeStep
+ * 9 - Property (Law)
+ * 10 - AbstractObject (Law)
+ * 11 - Episode (Law)
+ * 12 - Property (Possibility)
+ * 13 - AbstractObject (Possibility)
+ * 14 - Episode (Possibility)
+ * 15 - ActionPossibility
+ * 16 - Action
+ * 17 - ActionCategory
+ * 18 - Goal */
+
+ @Test public void testCorrectCategoryAndScope() {
+ for (int i=0;i<19;i++) {
+ Idea id = new Idea();
+ id.setType(i);
+ switch(i) {
+ case 0:assertEquals(id.getCategory(),"AbstractObject");
+ assertEquals(id.getScope(),1);
+ break;
+ case 1:assertEquals(id.getCategory(),"Property");
+ assertEquals(id.getScope(),1);
+ break;
+ case 2:assertEquals(id.getCategory(),"Link");
+ break;
+ case 3:assertEquals(id.getCategory(),"QualityDimension");
+ break;
+ case 4:assertEquals(id.getCategory(),"Episode");
+ assertEquals(id.getScope(),1);
+ break;
+ case 5:assertEquals(id.getCategory(),"Composite");
+ break;
+ case 6:assertEquals(id.getCategory(),"Aggregate");
+ break;
+ case 7:assertEquals(id.getCategory(),"Configuration");
+ break;
+ case 8:assertEquals(id.getCategory(),"TimeStep");
+ break;
+ case 9:assertEquals(id.getCategory(),"Property");
+ assertEquals(id.getScope(),2);
+ break;
+ case 10:assertEquals(id.getCategory(),"AbstractObject");
+ assertEquals(id.getScope(),2);
+ break;
+ case 11:assertEquals(id.getCategory(),"Episode");
+ assertEquals(id.getScope(),2);
+ break;
+ case 12:assertEquals(id.getCategory(),"Property");
+ assertEquals(id.getScope(),0);
+ break;
+ case 13:assertEquals(id.getCategory(),"AbstractObject");
+ assertEquals(id.getScope(),0);
+ break;
+ case 14:assertEquals(id.getCategory(),"Episode");
+ assertEquals(id.getScope(),0);
+ break;
+ case 15:assertEquals(id.getCategory(),"Action");
+ assertEquals(id.getScope(),0);
+ break;
+ case 16:assertEquals(id.getCategory(),"Action");
+ assertEquals(id.getScope(),1);
+ break;
+ case 17:assertEquals(id.getCategory(),"Action");
+ assertEquals(id.getScope(),2);
+ break;
+ case 18:assertEquals(id.getCategory(),"Goal");
+ break;
+ }
+ }
+ }
+
+ public class MemoryAppender extends ListAppender {
+ public void reset() {
+ this.list.clear();
+ }
+
+ public boolean contains(String string, Level level) {
+ return this.list.stream()
+ .anyMatch(event -> event.toString().contains(string)
+ && event.getLevel().equals(level));
+ }
+
+ public int countEventsForLogger(String loggerName) {
+ return (int) this.list.stream()
+ .filter(event -> event.getLoggerName().contains(loggerName))
+ .count();
+ }
+
+ public List search(String string) {
+ return this.list.stream()
+ .filter(event -> event.toString().contains(string))
+ .collect(Collectors.toList());
+ }
+
+ public List search(String string, Level level) {
+ return this.list.stream()
+ .filter(event -> event.toString().contains(string)
+ && event.getLevel().equals(level))
+ .collect(Collectors.toList());
+ }
+
+ public int getSize() {
+ return this.list.size();
+ }
+
+ public List getLoggedEvents() {
+ return Collections.unmodifiableList(this.list);
+ }
+}
+
+ @Test public void testToJSON() {
+ MemoryAppender memoryAppender = new MemoryAppender();
+ Logger logger = (Logger) LoggerFactory.getLogger(Idea.class);
+ memoryAppender.setContext((LoggerContext) LoggerFactory.getILoggerFactory());
+ logger.setLevel(Level.DEBUG);
+ logger.addAppender(memoryAppender);
+ memoryAppender.start();
+ Idea ii = Idea.createIdea("teste", 12, 1);
+ ii.add(Idea.createIdea("tt2",null,5));
+ String idea_json = ii.toJSON();
+ Idea ii2 = Idea.fromJSON(idea_json);
+ assertTrue(ii.equals(ii2));
+ TestComplexMemoryObjectInfo ttt = new TestComplexMemoryObjectInfo();
+ initialize(ttt);
+ Idea i = Idea.createIdea("root",null,1);
+ i.addObject(ttt,"cmoi");
+ String ij = i.toJSON();
+ Idea i2 = Idea.fromJSON(ij);
+ assertTrue(i.equals(i2));
+ ii = Idea.createIdea("feedback", l, 1);
+ ii.add(ii);
+ ij = ii.toJSON();
+ System.out.println(ij);
+
}
+
}
\ No newline at end of file