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