diff --git a/src/examples/descriptionSet/attributeSet.txt b/src/examples/descriptionSet/attributeSet.txt new file mode 100644 index 000000000..458d435ee --- /dev/null +++ b/src/examples/descriptionSet/attributeSet.txt @@ -0,0 +1,6 @@ +DescriptionSetContext attribute +Observations: 1 2 3 4 +1: a b +2: b +3: c b d +4: a b c \ No newline at end of file diff --git a/src/examples/descriptionSet/interval.txt b/src/examples/descriptionSet/interval.txt new file mode 100644 index 000000000..d5b23a31a --- /dev/null +++ b/src/examples/descriptionSet/interval.txt @@ -0,0 +1,5 @@ +DescriptionSetContext interval +Observations: 1 2 3 +1: [2,11] +2: [5,16] +3: [10,20] \ No newline at end of file diff --git a/src/examples/descriptionSet/interval2.txt b/src/examples/descriptionSet/interval2.txt new file mode 100644 index 000000000..49f940de8 --- /dev/null +++ b/src/examples/descriptionSet/interval2.txt @@ -0,0 +1,5 @@ +DescriptionSetContext interval +Observations: 1 2 3 +1: [2,11] +2: [5,16] +3: [12,20] \ No newline at end of file diff --git a/src/main/java/org/thegalactic/descriptionset/AttributeDescription.java b/src/main/java/org/thegalactic/descriptionset/AttributeDescription.java new file mode 100644 index 000000000..2140d4d96 --- /dev/null +++ b/src/main/java/org/thegalactic/descriptionset/AttributeDescription.java @@ -0,0 +1,135 @@ +package org.thegalactic.descriptionset; + +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * This class implements descriptions of binary attribute sets. + * + * A set of binary attributes is a description of type DescritionType.attributeSet. + * The description's value is a sorted set of String, representing the binary attributes. + * + * The attributes in the set are ordered based on the lexicographic order on the attributes' name. + * (default compareTo of String) + * + * @author Jessie Carbonnel + * + */ +public class AttributeDescription extends Description> { + + /* + * ------------ CONSTRUCTORS ------------------ + */ + + /** + * Constructs a new AttributeDescription with the value v. + * + * @param v the value of the new AttributeDescription. + */ + public AttributeDescription(SortedSet v) { + super(DescriptionType.attributeSet, v); + } + + /** + * Constructs a new AttributeDescription without specifying a value. + */ + public AttributeDescription() { + super(DescriptionType.attributeSet, new TreeSet()); + } + + /* + * ------------- INHERITED METHODS ------------ + */ + + @Override + /** + * Binary attribute sets form a poset. + * The order is based on lexicographic order of attribute sets. + * An attribute description always contains a set of attributes, + * but it may be empty. + * + * @param d an AttributeDescription. + * @return a negative integer, zero, or a positive integer as this AttributeDescription + * is less than, equal to, or greater than the specified one. + */ + public int compareTo(Description> d) { + + // handling the case of descriptions representing bottom concept's intent + if (this.getValue().contains("*")) { + return -1; + } else if (d.getValue().contains("*")) { + return 1; + } else { + // if the two sets have the same elements, then returns 0 + if (this.getValue().containsAll(d.getValue()) && d.getValue().containsAll(this.getValue())) { + return 0; + } else if (this.getValue().size() == d.getValue().size()) { + + // if the two sets are not equal but have the same size + + SortedSet set1 = new TreeSet(); + set1.addAll(this.getValue()); + + SortedSet set2 = new TreeSet(); + set2.addAll(d.getValue()); + + // for each attribute of the specified AttributeDescription + while (set2.size() < 0) { + + // we compare the first attributes of the two sets + int res = set1.first().compareTo(set2.first()); + + // if the two attributes are equals, repeat on the two following attributes + if (res == 0) { + set1 = set1.headSet(set1.first()); + set2 = set2.headSet(set2.first()); + } else { + // else returns the results + return res; + } + } + return 0; + } else if (this.getValue().size() < d.getValue().size()) { + // if the current set is smaller than the specified one, then returns -1 + return -1; + } else { + // if the current set is larger, then return 1 + return 1; + } + } + } + + @Override + /** + * Takes a binary attributes set represented by a String + * and initialises the AttributeDescription's value accordingly. + * + * @param s the description in String format + */ + public void initFromDescriptionSetContext(String s) { + this.setValue(new TreeSet()); + + for (String att : s.split(" ")) { + this.getValue().add(att); + } + } + + @Override + /** + * Compares the two AttributeDescriptions. + * Works with bottom context intent. + * + * @return true if the two AttributeDescriptions have the same value. + */ + public boolean equals(Object o) { + return this.getValue().equals(((AttributeDescription) o).getValue()); + } + + @Override + /** + * Calls HashCode from super class. + */ + public int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/org/thegalactic/descriptionset/AttributeDescriptionSet.java b/src/main/java/org/thegalactic/descriptionset/AttributeDescriptionSet.java new file mode 100644 index 000000000..41916f1ae --- /dev/null +++ b/src/main/java/org/thegalactic/descriptionset/AttributeDescriptionSet.java @@ -0,0 +1,252 @@ +package org.thegalactic.descriptionset; + +import java.util.TreeSet; +/** + * This class represents Description Sets of AttributeDescription. + * An attribute description is a set of binary attributes. + * Thus it represents a set of attribute set. + * + * Attribute description sets will always contain at most one attribute description, + * as the similarity of two attribute sets is another attribute set. + * + * @author Jessie Carbonnel + * + */ +public class AttributeDescriptionSet extends ComparableDescriptionSet { + + /** + * Generated Version UID. + */ + private static final long serialVersionUID = -5574025662501568193L; + + /* + * ------------ CONSTRUCTORS ---------------- + */ + + /** + * Constructs a new description set of binary attribute sets based on an existing set. + * + * @param s the existing set of descriptions representing binary attribute sets. + */ + public AttributeDescriptionSet(TreeSet s) { + super(s); + } + + /* + * ------------ INHERITED METHODS ---------------- + */ + + @Override + /** + * Copy/paste from ComparableSet. + * Not verified. + * + * Compares two attribute sets (AttributeDescription) depending on the lectic order. + * If the current attribute set is the bottom concept intent, it returns -1, + * If the specified attribute set is the bottom concept intent, it returns 1, + * unless the two sets both represent the bottom concept intent, therefore it returns 0. + * + * Each AttributeDescriptionSet contains only one attribute set, i.e., an AttributeDescription. + * The compareTo is performed on each set of the two AttributeDescriptionSets. + * + * @param set an AttributeDescriptionSet + * @return a negative integer, zero, or a positive integer as this AttributeDescriptionSet + * is less than, equal to, or greater than the specified AttributeDescriptionSet + * according to the lectic order. + */ + public int compareTo(ComparableDescriptionSet set) { + + // handling special case of bottom concept intent + if (this.isBot() && set.isBot()) { + return 0; + } else if (this.isBot()) { + return -1; + } else if (set.isBot()) { + return 1; + } + + // attribute set of the current AttributeDescriptionSet + TreeSet currentSet = new TreeSet(); + currentSet.addAll(this.first().getValue()); + + // attribute set of the AttributeDescriptionSet in parameter + TreeSet comparedSet = new TreeSet(); + comparedSet.addAll(set.first().getValue()); + + int cmp; + + // case of equality between this component and object + if (currentSet.equals(comparedSet)) { + cmp = 0; + } else { + // computes index i of the first element in set minus this + // if i doesn't exist, then this component is not smaller than the set by lectic order + final TreeSet setMinusThis = new TreeSet(comparedSet); + setMinusThis.removeAll(currentSet); + if (setMinusThis.isEmpty()) { + cmp = 1; + } else { + final Comparable i = setMinusThis.first(); + // compute this inter {1, ..., i-1} + final TreeSet setAiMinus1 = new TreeSet(); + for (final Object c : currentSet) { + if (i.compareTo(c) > 0) { + setAiMinus1.add(c); + } + } + // compute set inter {1, ..., i-1} + final TreeSet setBiMinus1 = new TreeSet(); + for (final Object c : comparedSet) { + if (i.compareTo(c) > 0) { + setBiMinus1.add(c); + } + } + // if setAiminus1 and setBiminus1 are equal then this component is smaller than B by lectic order + if (setAiMinus1.equals(setBiMinus1)) { + cmp = -1; + } else { + cmp = 1; + } + } + } + return cmp; + } + + @Override + /** + * Returns true if all attributes from the AttributeDescription + * of the current AttributeDescriptionSet + * are included in the attribute set + * of the AttributeDescriptionSet in parameter. + * (Implementation of the set inclusion) + * + * @param set an AttributeDescriptionSet + * @return true if the current attribute set is included in the specified one, else false + */ + public boolean isIncludedIn(ComparableDescriptionSet set) { + + if (set.isBot()) { + return true; // everything is included in the bottom concept + } else if (this.isBot()) { + return false; // the bottom concept is included in nothing + } else { + return (set.first().getValue().containsAll(this.first().getValue())); + } + } + + @Override + /** + * Returns true if the attribute set in parameter + * is included in the attribute set (AttributeDescription) + * of the current AttributeDescriptionSet. + * + * @param desc an AttributeDescription + * @return true if the specified attributeDescription is included in the AttributeDescriptionSet, + * else false. + */ + public boolean includes(AttributeDescription desc) { + if (this.isBot()) { + return true; // everything is included in the bottom concept + } else { + return (this.first().getValue().contains(desc.getValue())); + } + } + + @Override + /** + * Returns an AttributeDescriptionSet + * containing one AttributeDescription (i.e., a set of binary attributes) + * corresponding to the set intersection of the two AttributeDescriptions + * of the two AttributeDescriptionSets. + * + * @param set an AttributeDescriptionSet + * @return set intersection of the two description sets. + */ + public ComparableDescriptionSet getSimilarity( + ComparableDescriptionSet set) { + + // handling special case of bottom concept intent + if (this.isBot()) { + return set.clone(); + } else if (set.isBot()) { + return this.clone(); + } + + // buffer for the intersection + TreeSet intersection = new TreeSet(); + + // if an attribute is present in both sets + for (String c : this.first().getValue()) { + if (set.first().getValue().contains(c)) { + // adds it in the intersection + intersection.add(c); + } + } + + // creates a new AttributeDescription containing the intersection. + TreeSet ad = new TreeSet(); + ad.add(new AttributeDescription(intersection)); + + // returns an AttributeDescriptionSet containing the AttributeDescription representing the intersection + return new AttributeDescriptionSet(ad); + } + + @Override + /** + * Returns true if the current attribute description set represents the bottom concept intent. + * The bottom intent is an attribute description containing '*' only. + * + * @return true if the current attribute description represents BOT intent + */ + public boolean isBot() { + if (this.first().getValue().isEmpty()) { + return false; // if the attribute set is empty, it is not the bottom concept + } else { + return (this.first().getValue().first().equals("*")); + } + } + + @Override + /** + * The bottom concept intent is an attribute description containing '*' in its attribute set. + */ + public void setBot() { + AttributeDescription ad = new AttributeDescription(); + TreeSet attSet = new TreeSet(); + attSet.add("*"); + ad.setValue(attSet); + this.clear(); + this.add(ad); + } + + @Override + /** + * Compares the two AttributeDescriptionSets. + * Works for bottom concept. + * + * @return true if the two AttributeDescriptions + * contained in the two AttributeDescriptionSets + * have the same value. + */ + public boolean equals(Object s) { + return (this.first().getValue().equals(((AttributeDescriptionSet) s).first().getValue())); + } + + @Override + /** + * Returns a clone of this component. + * + * @return a clone of this component. + */ + public AttributeDescriptionSet clone() { + return (AttributeDescriptionSet) super.clone(); + } + + @Override + /** + * Calls HashCode from super class. + */ + public int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/org/thegalactic/descriptionset/ComparableDescriptionSet.java b/src/main/java/org/thegalactic/descriptionset/ComparableDescriptionSet.java new file mode 100644 index 000000000..b6ec2f66a --- /dev/null +++ b/src/main/java/org/thegalactic/descriptionset/ComparableDescriptionSet.java @@ -0,0 +1,171 @@ +package org.thegalactic.descriptionset; + +import java.util.TreeSet; + +import org.thegalactic.util.ComparableSet; + +/** + * This class allows to manage set of descriptions as a patterns. + * The descriptions in the description set have to be of the same type E. + * + * Description sets should be ordered by lectic order (to be defined with CompareTo). + * This order depends on the type of E, and should be implemented in a concrete sub-class. + * + * This class adds 3 new abstract methods to ComparableSet: + * - {@link #getSimilarity(ComparableDescriptionSet)} returning the similarity of two description sets. + * - {@link #isIncludedIn(ComparableDescriptionSet)} returning true if the current description set is + * included in the specified one, else false (define the subsumption relation). + * - {@link #includes(E)} returning true if the specified description is in the description set. + * - {@link #setBot()} initialising the description set to represents to bottom concept intent. + * - {@link #isBot()} returning true if the description represents to bottom concept intent. + * + * The super class ComparableSet initially took binary attributes arbitrary ordered. + * + * @author Jessie Carbonnel + * + * @param the type of descriptions managed in the set + */ +public abstract class ComparableDescriptionSet extends ComparableSet implements Cloneable { + + /** + * Generated Version UID. + */ + private static final long serialVersionUID = 6939073041798850884L; + + /* + * ------------- CONSTRUCTORS ------------------ + */ + + /** + * Constructs a new and empty ComparableDescriptionSet. + */ + public ComparableDescriptionSet() { + super(); + } + + /** + * Constructs a new ComparableDescriptionSet + * from an existing sorted set containing elements of the same type. + * + * @param set an existing set of descriptions. + */ + public ComparableDescriptionSet(final TreeSet set) { + super(set); + } + + /** + * Constructs a new ComparableDescriptionSet + * copying the specified one. + * + * @param set the existing ComparableDescriptionSet + */ + public ComparableDescriptionSet(final ComparableDescriptionSet set) { + super(set); + } + + /* + * ------------ FACTORY --------------- + */ + + /** + * Returns an instance of a description set depending on the specified Description type. + * + * @param type the type of the Descriptions of the ComparableDescriptionSet instance + * @return an instance of the description set handling descriptions with the specified type + * or null if the specified type is unknown. + */ + public static ComparableDescriptionSet create(String type) { + if (type.equals("attribute")) { + return new AttributeDescriptionSet(new TreeSet()); + } else if (type.equals("interval")) { + return new IntervalDescriptionSet(new TreeSet()); + } else { + return null; + } + } + + /* + * ------------- ABSTRACT METHODS ------------------ + */ + + /** + * To be overridden in the sub-classes depending on E. + * Compares description set depending on the lectic order. + * + * @param set a description set of the same description type + * @return a negative integer, zero, or a positive integer as this descriptions set + * is less than, equal to, or greater than the specified description set + * according to the lectic order. + */ + public abstract int compareTo(final ComparableDescriptionSet set); + + /** + * To be overridden in the sub-classes depending on E. + * Returns true if the current description set includes the specified description, else false. + * Does not means that the description set "contains" the specified description. + * + * @param desc a description of the same type of the ones handled in the description set. + * @return true if the current description set includes the specified description, else false. + */ + public boolean includes(final E desc) { + return this.contains(desc); + } + + /** + * To be overridden in the sub-classes depending on E. + * Returns true if the current description set is included in the specified one, else false. + * + * @param set a description set handling the same type of description as the current one. + * @return true if the current description set is included in the specified one, else false. + */ + public abstract boolean isIncludedIn(final ComparableDescriptionSet set); + + /** + * Returns a description set representing the similarity of the current description set + * and the specified one. + * + * @param set a description set handling the same type of description as the current one. + * @return the similarity of the current description set and the specified one. + */ + public abstract ComparableDescriptionSet getSimilarity(final ComparableDescriptionSet set); + + /** + * Returns true if the comparable set represents the bottom concept intent, else false. + * + * @return true if the comparable set represents the bottom concept intent, else false + */ + public abstract boolean isBot(); + + /** + * Initialises the description set as the bottom concept intent. + */ + public abstract void setBot(); + + /* + * ------------- IMPLEMENTED METHODS ------------------ + */ + + /** + * Returns a String representing the value of the description. + * + * @return a String representing the description. + */ + public String toString() { + String res = "{ "; + for (E d : this) { + res += d.toString() + " "; + } + res += "}"; + return res; + } + + @Override + /** + * Returns a clone of this component. + * + * @return a clone of this component. + */ + public ComparableDescriptionSet clone() { + return (ComparableDescriptionSet) super.clone(); + } +} diff --git a/src/main/java/org/thegalactic/descriptionset/Description.java b/src/main/java/org/thegalactic/descriptionset/Description.java new file mode 100644 index 000000000..0434f9f4f --- /dev/null +++ b/src/main/java/org/thegalactic/descriptionset/Description.java @@ -0,0 +1,152 @@ +package org.thegalactic.descriptionset; + +/** + * This class gives the minimal representation of the description of a piece data. + * This class encapsulates a piece of data of any type, the type being characterised by E. + * + * A description ensures to return a value of type E representing the data, + * to provide a String representing its type , + * and to determine a total order over descriptions of the same type. + * + * The elements of a given type may not form a total order, so it needs to be defined. + * + * @author Jessie Carbonnel + * + * @param the type of the description + */ + +public abstract class Description implements Comparable> { + + /* + * --------------- ATTRIBUTES --------------- + */ + + /** + * The value of the description of type E. + */ + private E value; + + /** + * The type of the description. + */ + private DescriptionType type; + + /* + * --------------- CONSTRUCTORS --------------- + */ + + /** + * Constructs a new description with the value v and of type t. + * + * @param t the type of the new description. + * @param v the value of the new description. + */ + public Description(DescriptionType t, E v) { + this.type = t; + this.value = v; + } + + /** + * Constructs a new description of type t, without specifying a value. + * + * @param t the type of the new description. + */ + public Description(DescriptionType t) { + this.type = t; + } + + /* + * -------- FACTORY ----------- + */ + + /** + * Takes a type of description in String format and return the corresponding instance. + * This methods has to be updated for each newly implemented description type. + * + * @param type the type of the description + * @return an instance of the description with the specified type + * or null if the specified type is unknown. + */ + public static Description create(String type) { + if (type.equals("attribute")) { + return new AttributeDescription(); + } else if (type.equals("interval")) { + return new IntervalDescription(); + } else { + System.err.println("Unknow description type: " + type); + return null; + } + } + + /* + * --------------- ABSTRACT METHODS --------------- + */ + + /** + * Compares the values of the two descriptions. + * The defined order can be arbitrary, based on a poset, or based on the compareTo() of E. + * + * @param d a value of the same type. + * @return a negative integer, zero, or a positive integer as this description + * is less than, equal to, or greater than the specified one. + */ + public abstract int compareTo(Description d); + + /** + * Initialises the description value depending on the specified String. + * The String should correspond to the description as extracted from a file representing a DescriptionSetContext. + * + * @param s the description in String format + */ + public abstract void initFromDescriptionSetContext(String s); + + /* + * --------------- IMPLEMENTED METHODS --------------- + */ + + /** + * Returns the value of the description. + * + * @return the value of the description. + */ + public E getValue() { + return this.value; + } + + /** + * Replaces the value of the description by the specified one. + * + * @param v the new value of the description. + */ + public void setValue(E v) { + this.value = v; + } + + /** + * Returns the type of the description. + * + * @return the description's type. + */ + public DescriptionType getType() { + return this.type; + } + + /** + * Replaces the type of the description by the specified one. + * + * @param t the new type of the description. + */ + public void setType(DescriptionType t) { + this.type = t; + } + + /** + * Returns a String representing the value of the description. + * + * @return a String representing the description. + */ + public String toString() { + return value.toString(); + } +} + diff --git a/src/main/java/org/thegalactic/descriptionset/DescriptionSetClosureSystem.java b/src/main/java/org/thegalactic/descriptionset/DescriptionSetClosureSystem.java new file mode 100644 index 000000000..1a88c29d5 --- /dev/null +++ b/src/main/java/org/thegalactic/descriptionset/DescriptionSetClosureSystem.java @@ -0,0 +1,53 @@ +package org.thegalactic.descriptionset; + + +import java.util.TreeSet; +import java.util.Vector; + +/** + * This class represents Closure Systems that handle Descriptions in place of binary attributes. + * It defines the necessary methods to implements in concrete sub-classes representing closure systems. + * + * @author Jessie Carbonnel + * + * @param the type of Description + */ +public abstract class DescriptionSetClosureSystem { + + /* + * ------------- ABSTRACT METHODS ---------------- + */ + + /** + * Returns a vector of description set containing + * the original set of description set + * plus the ones obtained with the similarity operation. + * + * @return the set of all description sets. + */ + public abstract Vector> getDescriptionSets(); + + /** + * Returns the closure of the description set in parameter. + * + * @param set a description set. + * @return the closure of the specified description set. + */ + public abstract ComparableDescriptionSet descriptionSetClosure(ComparableDescriptionSet set); + + /** + * Returns the closure of the specified set of observations. + * + * @param set a set of observations. + * @return the closure of the specified set of observations + */ + public abstract TreeSet observationClosure(TreeSet set); + + /** + * Returns a set of concepts representing all closures. + * + * @return the set of concepts representing all closures. + */ + public abstract Vector> allDescriptionClosures(); + +} diff --git a/src/main/java/org/thegalactic/descriptionset/DescriptionSetConcept.java b/src/main/java/org/thegalactic/descriptionset/DescriptionSetConcept.java new file mode 100644 index 000000000..6cd3525d9 --- /dev/null +++ b/src/main/java/org/thegalactic/descriptionset/DescriptionSetConcept.java @@ -0,0 +1,191 @@ +package org.thegalactic.descriptionset; + +import java.util.TreeSet; + +import org.thegalactic.dgraph.Node; +import org.thegalactic.util.ComparableSet; + +/** + * This class represents concepts that have + * a set of observations for extent + * and a description set for intent. + * + * @author Jessie Carbonnel. + * + * @param the type of the descriptions. + */ +public class DescriptionSetConcept extends Node { + + /* + * ------------- ATTRIBUTES ------------------ + */ + + /** + * Description set of the concept. + * Represents the intent. + */ + private ComparableDescriptionSet intent = null; + + /** + * Observation set of the concept. + * Represents the extent. + */ + private ComparableSet extent = null; + + /* + * ------------- CONSTRUCTORS ------------------ + */ + + /** + * Constructs a new DescriptionSetConcept with an extent being a ComparableSet + * and an intent being a ComparableDescriptionSet. + * + * @param a the intent + * @param b the extent + */ + public DescriptionSetConcept(ComparableDescriptionSet a, TreeSet b) { + intent = a; + extent = new ComparableSet(); + extent.addAll(b); + } + + /** + * Constructs a new DescriptionSetConcept + * having the specified observation set as extent + * and an empty intent. + * + * @param o a set of observations. + * @param type the type of descriptions of the intent. + */ + public DescriptionSetConcept(TreeSet o, String type) { + + extent = new ComparableSet(); + extent.addAll(o); + + this.intent = ComparableDescriptionSet.create(type); + } + + /* + * ------------ METHODS TO HANDLE EXTENT AND INTENT ------------- + */ + + /** + * Verifies if the concept has an intent. + * + * @return true if intent is different from null. + */ + public boolean hasIntent() { + return (intent == null); + } + + /** + * Verifies if the concept has an extent. + * + * @return true if extent is different from null. + */ + public boolean hasExtent() { + return (this.extent == null); + } + + /** + * Retrieves the concept's intent. + * Returns a description set. + * + * @return the concept's intent. + */ + public ComparableDescriptionSet getIntent() { + return this.intent; + } + + /** + * Retrieves the concept's extent. + * Returns a comparable set of String representing observations. + * + * @return the concept's extent. + */ + public ComparableSet getExtent() { + return this.extent; + } + + /** + * Returns true if the specified description is included in the intent, else false. + * Warning: included =! contained for description sets. + * + * @param d the description + * @return true if the specified description is included in the intent, else false. + */ + public boolean isIncludedInIntent(E d) { + return intent.includes(d); + } + + /** + * Returns true if the specified description is contained in the intent, else false. + * + * @param d the description + * @return true if the specified description is contained in the intent, else false. + */ + public boolean isContainedInIntent(E d) { + return intent.contains(d); + } + + /** + * Returns true if the observation in parameter is included in the extent, else false. + * + * @param o the observation. + * @return true if the specified observation is included in the extent, else false. + */ + public boolean isIncludedInExtent(String o) { + return extent.contains(o); + } + + /** + * Returns true if all the descriptions contained in the set in parameter + * are included in the concept's intent. Else, false. + * + * @param set the description set + * @return true if the description set is included in the intent. + */ + public boolean allIncludedInIntent(ComparableDescriptionSet set) { + return set.isIncludedIn(intent); + } + + /** + * Returns true if all the specified observations + * are included in the concept's extent. Else, false. + * + * @param set the observations set + * @return true if the specified observation set is included in the extent. + */ + public boolean allIncludedInExtent(ComparableSet set) { + return extent.containsAll(set); + } + + /* + * ------------------- INHERITED METHODS --------------- + */ + + @Override + /** + * Returns a String representing the concept's intent and extent. + */ + public String toString() { + return "(" + extent + "," + intent + ")"; + } + + @Override + /** + * Compare the equality of DescriptionSetConcepts + * based on their extent. + */ + public boolean equals(Object o) { + return this.getExtent().equals(((DescriptionSetConcept) o).getExtent()); + } + + @Override + /** + * Calls hashode from super class. + */ + public int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/org/thegalactic/descriptionset/DescriptionSetContext.java b/src/main/java/org/thegalactic/descriptionset/DescriptionSetContext.java new file mode 100644 index 000000000..8bd4da8f9 --- /dev/null +++ b/src/main/java/org/thegalactic/descriptionset/DescriptionSetContext.java @@ -0,0 +1,721 @@ +package org.thegalactic.descriptionset; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.Vector; + +import org.thegalactic.util.ComparableSet; + +/** + * This class represents context depicting each observation against one description. + * It extends DescriptionSetClosureSystems. + * + * A context is created from a file having this format: + * + * ************* + * DescriptionSetContext type + * Observations: o1 o2 ... on + * o1: d1 + * o2: d2 + * ... + * on: dn + * ************* + * + * The computation of all closures is based on nextClosure() algorithm. + * nextClosure() relies on observation closures, so it works for all kinds of descriptions. + * + * @author Jessie Carbonnel + * + * @param the type of descriptions. + */ +public class DescriptionSetContext extends DescriptionSetClosureSystem { + + /* + * -------------------- ATTRIBUTES ------------------- + */ + + /** + * The type of the descriptions handled in the context. + */ + private String type; + + /** + * A set of ComparableDescriptionSets + * corresponding to the ones defined in the context + * for each observation. + */ + private Vector> initialDescriptionSets; + + /** + * A set of ComparableDescriptionSets + * corresponding to the ones defined in the context + * (i.e., the ones in initialDescriptionSets) + * plus the ones obtained with the similarity operator + * over the set of initial DescriptionSets. + */ + private Vector> allDescriptionSets; + + /** + * The set of observations. + */ + private ComparableSet observations; + + /* + * ------------ ATTRIBUTES: INTENT / EXTENT ------------ + */ + + /** + * A map to associate the most specialised ComparableDescriptionSet corresponding to each observation. + * The ComparableDescriptionSets are the ones in "initialDescriptionSets" + */ + private TreeMap> specIntent; + + /** + * A map to associate to each observation, all the ComparableDescriptionSets characterising it. + * The ComparableDescriptionSet are the ones in "allDescriptionSets". + */ + private TreeMap>> intent; + + /** + * A map to associate a set of observations to each ComparableDescriptionSets. + * The ComparableDescriptionSets are the ones in the set named "allDescriptionSets" + */ + private TreeMap, TreeSet> extent; + + /* + * ------------ CONSTRUCTORS ------------ + */ + + /** + * Constructs a Context depending on a file representing observations and their descriptions. + * We assume that an observation is described by one description, and not by a description set. + * [This could be changed after + * initFromDescriptionSetContext(line) would need to be redefined for Description + * and to be added in ComparableDescriptionSet] + * + * The specified file should have this format: + * + * ************* + * DescriptionSetContext type + * Observations: o1 o2 ... on + * o1: d1 + * o2: d2 + * ... + * on: dn + * ************* + * + * @param filename the file depicting the context + * @throws IOException + */ + public DescriptionSetContext(String filename) { + + System.out.println("---------------"); + System.out.println("Creating DescriptionSet Context from file"); + System.out.println("---------------"); + + initialDescriptionSets = new Vector>(); + + observations = new ComparableSet(); + + specIntent = new TreeMap>(); + + try { + // Opening the file containing the context + + File f = new File(filename); + FileReader fr = new FileReader(f); + BufferedReader br = new BufferedReader(fr); + + // First line should states "DescriptionSetContext" + + String line = br.readLine(); + + if (line.contains("DescriptionSetContext")) { + + // Extracting the type + + line = line.substring(line.indexOf(" ") + 1, line.length()); + type = line; + } else { + System.err.println("No type detected, issue with first line of the file."); + } + + + // Second line should states "Observations" + + line = br.readLine(); + + if (line.contains("Observations: ")) { + + // Extracting all observations + + line = line.substring(line.indexOf(" ") + 1, line.length()); + for (String s : line.split(" ")) { + this.addObservation(s); + } + } else { + System.err.println("No observations detected, issue with second line of the file."); + } + + + // Retrieving the CDS corresponding to each observation + + line = br.readLine(); + + while (line != null) { + + // extracting the observation + + String o = line.substring(0, line.indexOf(":")); + + // extracting the description set + + // new ComparableDescriptionSet and Description + // based on the previously extracted type + + ComparableDescriptionSet set = ComparableDescriptionSet.create(type); + Description d = Description.create(type); + + // initialises the Description depending on the line + + line = line.substring(line.indexOf(":") + 2, line.length()); + + d.initFromDescriptionSetContext(line); + + // adds the Description to the DescriptionSet + + set.add(d); + + // adds the DescriptionSet to the set of initial CDS + + initialDescriptionSets.addElement(set.clone()); + + // Adds in SpecIntent + // Which associates each observation to its most specific CDS + + specIntent.putIfAbsent(o, set.clone()); + + line = br.readLine(); + } + br.close(); + } catch (FileNotFoundException exception) { + System.out.println("File not found."); + } catch (IOException exception) { + exception.printStackTrace(); + } + + // Computing all description sets + + computeAllDescriptionSets(); + + // Computing intent + + computeIntent(); + + // Computing extent + + computeExtent(); + + } + + /* + * -------------------- HANDLING METHODS FOR ATTRIBUTES ------------------- + */ + + /** + * Returns the set of observations. + * + * @return the set of observations. + */ + public TreeSet getObservations() { + return observations; + } + + /** + * Returns a set containing all the description sets. + * + * @return a set containing all the description sets. + */ + public Vector> getAllDescriptionSets() { + return allDescriptionSets; + } + + /** + * Adds the specified observation to the set of observations. + * + * @param o an observation + */ + public void addObservation(String o) { + this.observations.add(o); + } + + /** + * Adds the specified observations to the set of observations. + * + * @param o a set of observations + */ + public void addAllObservation(TreeSet o) { + this.observations.addAll(o); + } + + /** + * Prints the set of observations. + */ + public void printObservations() { + System.out.println("Observations: " + observations); + } + + /** + * Adds the specified description set to initalDescriptionSets. + * + * @param ds a description set. + */ + public void addDescriptionSetInIDS(ComparableDescriptionSet ds) { + this.initialDescriptionSets.add(ds); + } + + /** + * Adds the specified description sets to intialDescritionSets. + * + * @param set a set of description sets. + */ + public void addAllDescriptionInIDS(TreeSet> set) { + this.initialDescriptionSets.addAll(set); + } + + /** + * Adds the specified descriptions set to allDescriptionSets. + * + * @param ds a description set. + */ + public void addDescriptionSetInADS(ComparableDescriptionSet ds) { + this.allDescriptionSets.add(ds); + } + + /** + * Adds the specified description sets to allDescriptionSets. + * + * @param set a set of description sets. + */ + public void addAllDescriptionInADS(TreeSet> set) { + this.allDescriptionSets.addAll(set); + } + + /** + * Prints the set of initial description sets. + */ + public void printInitialDescriptionSets() { + System.out.println("Initial description sets: " + initialDescriptionSets); + } + + /** + * Prints the set of all description sets. + */ + public void printAllDescriptionSets() { + System.out.println("All description sets: " + allDescriptionSets); + } + + /* + * -------------------- GENERATIVE METHODS ------------------- + */ + + /** + * Computes the complete intent of each observation. + */ + public void computeIntent() { + + intent = new TreeMap>>(); + + // for each observation + + for (String o : observations) { + + // adds o as a new key in intent TreeMap + + intent.putIfAbsent(o, new TreeSet>()); + + // adds the description set characterising the observation in the context + + intent.get(o).add(getSpecIntent(o)); + + // for each description set + + for (ComparableDescriptionSet ds : allDescriptionSets) { + + // if the description set describing the observation in the context + // is included in the description set ds + + if (ds.isIncludedIn(getSpecIntent(o))) { + + // adds ds to the observation intent + intent.get(o).add(ds); + } + } + } + } + + /** + * Computes the extent of each description set. + */ + public void computeExtent() { + + extent = new TreeMap, TreeSet>(); + + // for each description set + + for (ComparableDescriptionSet ds : allDescriptionSets) { + + // adds the description set as a key in extent TreeMap + + extent.putIfAbsent(ds, new TreeSet()); + + // for each observation + + for (String o : observations) { + + // if ds is included in the observation description set + + if (ds.isIncludedIn(getSpecIntent(o))) { + + // adds o to the description set extent + + extent.get(ds).add(o); + } + } + } + } + + /** + * Computes all description sets. + * O(n2) + */ + public void computeAllDescriptionSets() { + + // adds existing description sets from the initial description sets + + allDescriptionSets = new Vector>(); + allDescriptionSets.addAll(initialDescriptionSets); + + // adds the description set representing the bottom concept intent + + ComparableDescriptionSet bot = ComparableDescriptionSet.create(type); + bot.setBot(); + allDescriptionSets.add(bot); + + // vector that will contain the computed similarities of the description set + // At each new steps + + Vector> stepn = new Vector>(); + + + // while we can compute new description sets + // by similarity operation on existing ones + + boolean continu = true; + while (continu) { + + // for each pair of description sets + + for (ComparableDescriptionSet cds1 : allDescriptionSets) { + + for (ComparableDescriptionSet cds2 : allDescriptionSets) { + + // computes their similarity + + ComparableDescriptionSet set = ComparableDescriptionSet.create(type); + set = cds1.getSimilarity(cds2); + + // adds the similarity description set in the set + + if (!stepn.contains(set)) { + + stepn.add(set.clone()); + } + } + } + + // keeps only the new description sets + + stepn.removeAll(allDescriptionSets); + + // if no new descriptions + + if (stepn.size() == 0) { + + // ends the loop + + continu = false; + } else { + + // else adds the new descriptions to 'allDescription' + + allDescriptionSets.addAll(stepn); + + // clears the buffer description set + + stepn.clear(); + } + } + } + + /* + * -------------------- HANDLING METHODS FOR EXTENT/INTENT ------------------- + */ + + /** + * Returns the most specialised description set representing an observation o. + * + * @param o an observation. + * @return the most specialised description set representing the observation. + */ + public ComparableDescriptionSet getSpecIntent(String o) { + return this.specIntent.get(o).clone(); + } + + /** + * Returns the most specific description set corresponding to a set of observations. + * If the set of observations is emptu, returns the description set representing the + * bottom concept intent. + * + * @param observations a set of observations + * @return the most specific description set corresponding to the observations + */ + public ComparableDescriptionSet getSpecIntent(final TreeSet observations) { + + // defines the most specific intent of the empty set of observations + + if (observations.isEmpty()) { + ComparableDescriptionSet cds = ComparableDescriptionSet.create(type); + cds.setBot(); + return cds.clone(); + } + + // computes the similarity of the description sets + // corresponding to the specified observations + + TreeSet ob = new TreeSet(); + ob.addAll(observations); + + ComparableDescriptionSet sim = getSpecIntent(ob.pollFirst()); + for (String o : ob) { + sim = sim.getSimilarity(getSpecIntent(o)); + } + return sim; + } + + /** + * This methods takes a description set ds and returns the set of description sets + * in which the description set ds is included. + * + * @param ds a description set. + * @return the set of description sets in which ds is included. + */ + public TreeSet> getMoreGeneralDescriptionSets(ComparableDescriptionSet ds) { + TreeSet> result = new TreeSet>(); + result.add(ds); + for (ComparableDescriptionSet desc : allDescriptionSets) { + if (ds.isIncludedIn(desc)) { + result.add(desc); + } + } + return result; + } + + /** + * Returns all the description sets corresponding to an observation o. + * + * @param o an observation. + * @return a set of description sets representing the observation. + */ + public TreeSet> getIntent(String o) { + return this.intent.get(o); + } + + /** + * Returns all the description sets corresponding to a set of observations o. + * + * @param o a set of observations + * @return a set of description sets representing the observations + */ + public TreeSet> getIntent(TreeSet o) { + return getMoreGeneralDescriptionSets(getSpecIntent(o)); + } + + /** + * Returns all observations represented by the specified description set. + * + * @param ds a description set. + * @return the set of all observations corresponding to the specified description set. + */ + public TreeSet getExtent(ComparableDescriptionSet ds) { + if (this.extent.get(ds) != null) { + return this.extent.get(ds); + } else { + return new TreeSet(); + } + } + + /** + * Returns all observations represented by a set of description sets ds. + * + * @param ds a set of description sets. + * @return the set of all observations corresponding to the description sets. + */ + public TreeSet getExtent(Vector> ds) { + + // creates an empty set of observations + + TreeSet ob = new TreeSet(); + + // adds the observations corresponding to the first description set of ds + + ob.addAll(getExtent(ds.get(0).clone())); + + // for each description in d + + for (ComparableDescriptionSet de : ds) { + + // keeps only the observations present in both extents + + ob.retainAll(getExtent(de)); + } + + return ob; + } + + /* + * -------------------- INHERITED METHODS ------------------- + */ + + @Override + /** + * Returns the set of all description set. + * + * @return the set of all description set. + */ + public Vector> getDescriptionSets() { + return allDescriptionSets; + } + + @Override + /** + * Returns the closure of the specified description set. + * + * @param set a description set. + * @return a description set representing the closure of the specified one. + */ + public ComparableDescriptionSet descriptionSetClosure(ComparableDescriptionSet set) { + return getSpecIntent(getExtent(set)).clone(); + } + + /** + * Returns the closure of the observation set. + * + * @param set an observation set. + * @return an observation set representing the closure of the specified one. + */ + public TreeSet observationClosure(final TreeSet set) { + return getExtent(getSpecIntent(set)); + } + + @Override + /** + * Returns the set of all concepts of the closure system. + * These concepts have a description set as intent. + * This method computes the set of all closures by using nextClosure() + * on the set of objects. + * Thus it is applicable for any type of descriptions. + * + * @return the set of all concepts + */ + public Vector> allDescriptionClosures() { + + Vector> allclosure = new Vector>(); + + // first closure: observation closure of the empty set + + TreeSet set = new TreeSet(); + + allclosure.add(new DescriptionSetConcept(this.observationClosure(set), type)); + + DescriptionSetConcept cl = allclosure.firstElement(); + + // next closure in lectic order + + boolean continu = true; + do { + cl = this.nextDescriptionSetClosure(cl); + + if (allclosure.contains(cl)) { + continu = false; + } else { + allclosure.add(cl); + } + } while (continu); + + return allclosure; + } + + /** + * Copy/Paste from org.thegalatic.lattice.ClosureSystem.java. + * Then, adapted to computes closure on observations + * instead of attributes. + * + * Computation of the next closure based on the set of observations + * of the specified concept. + * Works for observations depicted by DescriptionSets. + * + * Returns a DescriptionSetConcept, + * i.e., a Concept having a set of String as extent + * and a DescriptionSet as intent. + * + * @param cl a description set concept + * @return the next description set concept in the lectic order + */ + public DescriptionSetConcept nextDescriptionSetClosure(DescriptionSetConcept cl) { + + TreeSet set = new TreeSet(this.getObservations()); + + boolean success = false; + + TreeSet setA = new TreeSet(cl.getExtent()); + + String ni = set.last(); + + do { + ni = set.last(); + set.remove(ni); + + if (!setA.contains(ni)) { + + setA.add(ni); + + TreeSet setB = new TreeSet(); + setB.addAll(this.observationClosure(setA)); + + setB.removeAll(setA); + + if (setB.isEmpty() || setB.first().compareTo(ni) >= 1) { + + setA = this.observationClosure(setA); + + success = true; + + } else { + + setA.remove(ni); + } + } else { + + setA.remove(ni); + } + } while (!success && ni.compareTo(this.getObservations().first()) >= 1); + + return new DescriptionSetConcept(getSpecIntent(setA), setA); + } +} diff --git a/src/main/java/org/thegalactic/descriptionset/DescriptionType.java b/src/main/java/org/thegalactic/descriptionset/DescriptionType.java new file mode 100644 index 000000000..31fd1c825 --- /dev/null +++ b/src/main/java/org/thegalactic/descriptionset/DescriptionType.java @@ -0,0 +1,17 @@ +package org.thegalactic.descriptionset; +/** + * List of implemented description type. + * + * @author Jessie Carbonnel + * + */ +public enum DescriptionType { + /** + * Description type for attribute sets. + */ + attributeSet, + /** + * Description type for intervals. + */ + interval; +} diff --git a/src/main/java/org/thegalactic/descriptionset/IntervalDescription.java b/src/main/java/org/thegalactic/descriptionset/IntervalDescription.java new file mode 100644 index 000000000..fc942e338 --- /dev/null +++ b/src/main/java/org/thegalactic/descriptionset/IntervalDescription.java @@ -0,0 +1,95 @@ +package org.thegalactic.descriptionset; + +import org.thegalactic.util.Couple; + +/** + * This class implements descriptions of intervals. + * + *An interval is a description of type DescriptionType.interval. + * + *Type of the description is a Couple of Intefer, representing the min and max of the interval. + * + * @author Jessie Carbonnel + * + */ +public class IntervalDescription extends Description { + + /** + * Constructs an empty IntervalDescription. + */ + public IntervalDescription() { + super(DescriptionType.interval, new Couple(null, null)); + } + + /** + * Constructs an IntervalDescription with the specified value. + * + * @param c an interval + */ + public IntervalDescription(Couple c) { + super(DescriptionType.interval, c); + } + + @Override + /** + * Compares two Intervals. + * First compares them according to their range + * [1,2] < [1,3], + * then according to their min + * [1,2] < [3,4] + * [*,*] is the 'greatest' interval. + * + * @param d an interval description + * @return a negative integer, zero, or a positive integer as this description + * is less than, equal to, or greater than the specified one. + */ + public int compareTo(Description d) { + // if the current interval is [*,*], it is greater than all the others + if (this.getValue().getLeft().equals("*")) { + return 1; + } else if (d.getValue().getLeft().equals("*")) { + return -1; + } else { + int range1 = ((Integer) this.getValue().getLeft()) - ((Integer) this.getValue().getRight()); + int range2 = ((Integer) d.getValue().getLeft()) - ((Integer) d.getValue().getRight()); + + if (range1 == range2) { + return ((Integer) this.getValue().getLeft()).compareTo((Integer) d.getValue().getLeft()); + } else { + return range1 - range2; + } + } + } + + @Override + /** + * Takes an interval represented by a String + * and initialises the AttributeDescription's value accordingly. + * String Interval format: [a,b] + * + *@param s the interval description in String format + */ + public void initFromDescriptionSetContext(String s) { + this.getValue().setLeft(Integer.parseInt(s.substring(1, s.indexOf(',')))); + this.getValue().setRight(Integer.parseInt(s.substring(s.indexOf(",") + 1, s.length() - 1))); + } + + @Override + /** + * Compares the two IntervalDescriptions. + * + * @return true if the two IntervalDescriptions have the same value. + */ + public boolean equals(Object o) { + return this.getValue().getLeft().equals(((IntervalDescription) o).getValue().getLeft()) + && this.getValue().getRight().equals(((IntervalDescription) o).getValue().getRight()); + } + + @Override + /** + * Calls HashCode from super class. + */ + public int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/org/thegalactic/descriptionset/IntervalDescriptionSet.java b/src/main/java/org/thegalactic/descriptionset/IntervalDescriptionSet.java new file mode 100644 index 000000000..92e769043 --- /dev/null +++ b/src/main/java/org/thegalactic/descriptionset/IntervalDescriptionSet.java @@ -0,0 +1,163 @@ +package org.thegalactic.descriptionset; + +import java.util.TreeSet; + +import org.thegalactic.util.Couple; + +/** + * This class implements interval description sets. + * + * @author Jessie Carbonnel + * + */ +public class IntervalDescriptionSet extends ComparableDescriptionSet { + + /** + * Generated version UID. + */ + private static final long serialVersionUID = 7907048096315817000L; + + /** + * Constructs an IntervalDescriptionSet base on the specified set of interval descriptions. + * + * @param s a set of interval descriptions + */ + public IntervalDescriptionSet(TreeSet s) { + super(s); + } + + @Override + /** + * Compares two IntervalDescriptionSets. + * An IntervalDescriptionSet has at most one description. + * + * Uses the compareTo of IntervalDescription + */ + public int compareTo(ComparableDescriptionSet set) { + if (this.isBot() && set.isBot()) { + return 0; + } else if (this.isBot()) { + return 1; + } else if (set.isBot()) { + return -1; + } else { + return this.first().compareTo(set.first()); + } + } + + @Override + /** + * Returns true if the current interval is included + * in the specified interval. + * + * @param set a set of interval + * @return true if included in the specified interval + */ + public boolean isIncludedIn(ComparableDescriptionSet set) { + if (!this.isEmpty() && !set.isEmpty()) { + if (set.isBot()) { + return true; // everything included in the bottom concept + } else if (this.isBot()) { + return false; //the bottom concept is included in nothing + } else { + return (((Integer) this.first().getValue().getLeft()) >= ((Integer) set.first().getValue().getLeft()) + && ((Integer) this.first().getValue().getRight()) <= ((Integer) set.first().getValue().getRight())); + } + } else { + // case of top concept + return this.isEmpty(); + } + } + + @Override + /** + * Returns the larger common interval of the two intervals. + * + * @return an interval set containing one interval representing the similarity of the two specified ones + */ + public ComparableDescriptionSet getSimilarity( + ComparableDescriptionSet set) { + + // handling special case of bottom concept intent + if (this.isBot()) { + return set.clone(); + } else if (set.isBot()) { + return this.clone(); + } + + IntervalDescription d = new IntervalDescription(); + TreeSet s = new TreeSet(); + + if (!this.isEmpty() && !((IntervalDescriptionSet) set).isEmpty()) { + Integer min = new Integer(0); + Integer max = new Integer(0); + min = Math.max((Integer) this.first().getValue().getLeft(), (Integer) set.first().getValue().getLeft()); + max = Math.min((Integer) this.first().getValue().getRight(), (Integer) set.first().getValue().getRight()); + Couple c = new Couple(min, max); + d.setValue(c); + if (min <= max) { + s.add(d); + } + } + return new IntervalDescriptionSet(s); + } + + @Override + /** + * Bottom concept intent is [*,*] + */ + public void setBot() { + IntervalDescription id = new IntervalDescription(new Couple("*", "*")); + this.clear(); + this.add(id); + } + + @Override + /** + * Returns true if the current interval description set represents the bottom concept intent. + * + *@return true if the current interval description set represents the bottom concept intent + */ + public boolean isBot() { + if (this.isEmpty()) { + return false; + } else { + return this.first().getValue().getLeft().equals("*") && this.first().getValue().getRight().equals("*"); + } + } + + @Override + /** + * Compares the two IntervalDescriptionSets. + * + * @return true if the two IntervalDescriptions + * contained in the two IntervalDescriptionSets + * have the same value. + */ + public boolean equals(Object s) { + if (!this.isEmpty() && !((IntervalDescriptionSet) s).isEmpty()) { + return (this.first().getValue().equals(((IntervalDescriptionSet) s).first().getValue())); + } else { + return (this.isEmpty() && ((IntervalDescriptionSet) s).isEmpty()); + } + } + + @Override + /** + * Returns a clone of this component. + * + * @return a clone of this component. + */ + public IntervalDescriptionSet clone() { + return (IntervalDescriptionSet) super.clone(); + } + + @Override + /** + * Calls HashCode from super class. + */ + public int hashCode() { + return super.hashCode(); + } + +} diff --git a/src/main/java/org/thegalactic/descriptionset/TestDescriptionSet.java b/src/main/java/org/thegalactic/descriptionset/TestDescriptionSet.java new file mode 100644 index 000000000..fb9c7b2d0 --- /dev/null +++ b/src/main/java/org/thegalactic/descriptionset/TestDescriptionSet.java @@ -0,0 +1,139 @@ +package org.thegalactic.descriptionset; + +import org.thegalactic.lattice.ConceptLattice; + +/** + * This class tests methods handling description sets. + * + * @author Jessie Carbonnel + * + */ +public final class TestDescriptionSet { + + /** + * Constructor. + */ + private TestDescriptionSet() { + } + + /** + * Main. + * + * @param args main's arguments + */ + public static void main(String[] args) { + + try { + + // Creating description set context + // from an example file + // representing attributeSet descriptions + + String filename = "src/examples/descriptionSet/attributeSet.txt"; + + DescriptionSetContext context = new DescriptionSetContext(filename); + + // PRINTING OBSERVATIONS + + context.printObservations(); + + // PRINTING INITIAL DESCRIPTION SETS + + context.printInitialDescriptionSets(); + + // PRINTING ALL DESCRIPTION SETS + + context.printAllDescriptionSets(); + + // PRINTING MORE SPECIALISED INTENT + + System.out.println(); + for (String o : context.getObservations()) { + System.out.println("SpecInt(" + o + ") = " + context.getSpecIntent(o)); + } + + // PRINTING INTENT + + System.out.println(); + for (String o : context.getObservations()) { + System.out.println("Int(" + o + ") = " + context.getIntent(o)); + } + + // PRINTING EXTENT + + System.out.println(); + for (ComparableDescriptionSet ds : context.getAllDescriptionSets()) { + System.out.println("Ext(" + ds + ") = " + context.getExtent(ds)); + } + + // COMPUTING AND PRINTING ALL CLOSURES + + System.out.println(); + System.out.println("--------- ALL CLOSURES ---------"); + System.out.println(); + + System.out.println(context.allDescriptionClosures()); + + ConceptLattice cl = ConceptLattice.completeDescriptionLatticeLattice(context); + System.out.println(cl); + + System.out.println("---------------------------------------------------------------"); + + // Creating description set context + // from an example file + // representing attributeSet descriptions + + String filename2 = "src/examples/descriptionSet/interval.txt"; + + DescriptionSetContext context2 = new DescriptionSetContext(filename2); + + // PRINTING OBSERVATIONS + + context2.printObservations(); + + // PRINTING INITIAL DESCRIPTION SETS + + context2.printInitialDescriptionSets(); + + // PRINTING ALL DESCRIPTION SETS + + context2.printAllDescriptionSets(); + + // PRINTING MORE SPECIALISED INTENT + + System.out.println(); + for (String o : context2.getObservations()) { + System.out.println("SpecInt(" + o + ") = " + context2.getSpecIntent(o)); + } + + // PRINTING INTENT + + System.out.println(); + for (String o : context2.getObservations()) { + System.out.println("Int(" + o + ") = " + context2.getIntent(o)); + } + + // PRINTING EXTENT + + System.out.println(); + for (ComparableDescriptionSet ds : context2.getAllDescriptionSets()) { + System.out.println("Ext(" + ds + ") = " + context2.getExtent(ds)); + } + + // COMPUTING AND PRINTING ALL CLOSURES + + System.out.println(); + System.out.println("--------- ALL CLOSURES ---------"); + System.out.println(); + + System.out.println(context2.allDescriptionClosures()); + + ConceptLattice cl2 = ConceptLattice.completeDescriptionLatticeLattice(context2); + System.out.println(cl2); + + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/org/thegalactic/descriptionset/package-info.java b/src/main/java/org/thegalactic/descriptionset/package-info.java new file mode 100644 index 000000000..a450c0831 --- /dev/null +++ b/src/main/java/org/thegalactic/descriptionset/package-info.java @@ -0,0 +1,16 @@ +/* + * package-info.java + * + * Copyright: 2010-2015 Karell Bertet, France + * Copyright: 2015-2016 The Galactic Organization, France + * + * License: http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html CeCILL-B license + * + * This file is part of java-lattices. + * You can redistribute it and/or modify it under the terms of the CeCILL-B license. + */ + +/** + * This package is designed to represent classes to handle description sets. + */ +package org.thegalactic.descriptionset; diff --git a/src/main/java/org/thegalactic/lattice/ConceptLattice.java b/src/main/java/org/thegalactic/lattice/ConceptLattice.java index f91be7501..d6d45558b 100644 --- a/src/main/java/org/thegalactic/lattice/ConceptLattice.java +++ b/src/main/java/org/thegalactic/lattice/ConceptLattice.java @@ -12,6 +12,9 @@ * You can redistribute it and/or modify it under the terms of the CeCILL-B license. */ import org.thegalactic.context.Context; +import org.thegalactic.descriptionset.DescriptionSetClosureSystem; +import org.thegalactic.descriptionset.DescriptionSetConcept; + import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; @@ -120,6 +123,7 @@ public static ConceptLattice idealLattice(DAGraph dag) { /* * -------- STATIC CLOSEDSET LATTICE GENERATION FROM AN ImplicationalSystem OR A CONTEXT ------------------ */ + /** * Generates and returns the complete (i.e. transitively closed) closed set * lattice of the specified closure system, that can be an implicational @@ -137,6 +141,7 @@ public static ConceptLattice idealLattice(DAGraph dag) { public static ConceptLattice completeLattice(ClosureSystem init) { ConceptLattice lattice = new ConceptLattice(); // compute all the closed set with allClosures + Vector allclosure = init.allClosures(); for (Concept cl : allclosure) { lattice.addNode(cl); @@ -154,6 +159,35 @@ public static ConceptLattice completeLattice(ClosureSystem init) { return lattice; } + /** + * Computes the Complete Lattice of descriptionSets. + * Based on nextClosure() + * + * @param init a closure system representing description sets + * @return the complete lattice + */ + public static ConceptLattice completeDescriptionLatticeLattice(DescriptionSetClosureSystem init) { + ConceptLattice lattice = new ConceptLattice(); + // compute all the closed set with allClosures + + Vector allclosure = init.allDescriptionClosures(); + for (DescriptionSetConcept cl : allclosure) { + lattice.addNode(cl); + } + + // an edge corresponds to an inclusion between two closed sets + for (Object source : lattice.getNodes()) { + for (Object target : lattice.getNodes()) { + if (((DescriptionSetConcept) target).allIncludedInExtent((((DescriptionSetConcept) source).getExtent()))) { + lattice.addEdge((Node) source, (Node) target); + } + } + } + // Hasse diagram is computed + return lattice; + } + + /** * Generates and returns the Hasse diagram of the closed set lattice of the * specified closure system, that can be an implicational system @@ -181,11 +215,11 @@ public static ConceptLattice diagramLattice(ClosureSystem init) { //if (Diagram) { // computes the dependance graph of the closure system // addition of nodes in the precedence graph - ConcreteDGraph graph = new ConcreteDGraph(); - for (Comparable c : init.getSet()) { - graph.addNode(new Node(c)); - } - lattice.setDependencyGraph(graph); +// ConcreteDGraph graph = new ConcreteDGraph(); +// for (Comparable c : init.getSet()) { +// graph.addNode(new Node(c)); +// } +// lattice.setDependencyGraph(graph); // intialize the close set lattice with botom element Concept bot = new Concept(init.closure(new ComparableSet()), false); lattice.addNode(bot); @@ -231,11 +265,11 @@ public static ConceptLattice diagramIceberg(Context init, double support) { ConceptLattice lattice = new ConceptLattice(); // computes the dependance graph of the closure system // addition of nodes in the precedence graph - ConcreteDGraph graph = new ConcreteDGraph(); - for (Comparable c : init.getSet()) { - graph.addNode(new Node(c)); - } - lattice.setDependencyGraph(graph); +// ConcreteDGraph graph = new ConcreteDGraph(); +// for (Comparable c : init.getSet()) { +// graph.addNode(new Node(c)); +// } +// lattice.setDependencyGraph(graph); // intialize the close set lattice with bottom element Concept bot = new Concept(init.closure(new ComparableSet()), false); lattice.addNode(bot);