001 package ifs.extension;
002
003 import ifs.model.Value;
004
005 /**
006 * This class describing an assignment of a value to a variable together with a counter (used by CBS).
007 *
008 * Counter also supports ageing: the counter is multiplied by aging factor for each iteration.
009 *
010 * @author <a href="mailto:muller@ktiml.mff.cuni.cz">Tomáš Müller</a>
011 * @version 1.0
012 */
013 public class Assignment {
014 private static org.apache.log4j.Logger sLogger = org.apache.log4j.Logger.getLogger(Assignment.class);
015 private Value iValue;
016 private double iCounter = 1.0;
017 private long iLastRevision;
018 private double iAgeing = 1.0;
019
020 /** Constructor
021 * @param iteration current iteration
022 * @param value value
023 * @param ageing ageing factor
024 */
025 public Assignment(long iteration, Value value, double ageing) {
026 iValue = value;
027 iLastRevision = iteration;
028 iAgeing = ageing;
029 }
030
031 /** Returns value */
032 public Value getValue() {
033 return iValue;
034 }
035
036 /** Increments counter
037 * @param iteration current iteration
038 */
039 public void incCounter(long iteration) {
040 revise(iteration);
041 iCounter += 1.0;
042 }
043
044 /** Set counter
045 * @param cnt new value
046 */
047 public void setCounter(double cnt) {
048 iCounter = cnt;
049 }
050
051 /** Get counter
052 * @param iteration current iteration
053 */
054 public double getCounter(long iteration) {
055 if (iteration == 0l)
056 return iCounter;
057 if (iAgeing == 1.0)
058 return iCounter;
059 return iCounter * Math.pow(iAgeing, iteration - iLastRevision);
060 }
061
062 /** Revise counter. If ageing is used, counter is adopted to the current iteration: it is multiplited by ageing factor powered by the number of iterations since last revision.
063 */
064 public synchronized void revise(long iteration) {
065 if (iAgeing == 1.0)
066 return;
067 iCounter *= Math.pow(iAgeing, iteration - iLastRevision);
068 iLastRevision = iteration;
069 }
070
071 /** Combine two integers (for hash code)
072 */
073 public static int combine(int a, int b) {
074 int ret = 0;
075 for (int i = 0; i < 15; i++)
076 ret = ret | ((a & (1 << i)) << i) | ((b & (1 << i)) << (i + 1));
077 return ret;
078 }
079
080 public int hashCode() {
081 return iValue.hashCode();
082 }
083
084 public boolean equals(Object o) {
085 try {
086 Assignment a = (Assignment)o;
087 return a.getValue().getId() == getValue().getId();
088 }
089 catch (Exception e) {
090 return false;
091 }
092 }
093
094 /** Returns comparator of assignments */
095 public static java.util.Comparator getComparator(long iteration) {
096 return new AssignmentComparator(iteration);
097 }
098
099 /** String representation */
100 public String toString() {
101 return toString(0l, true);
102 }
103
104 /** String representation (e.g., 10x A := a)*/
105 public String toString(long iteration, boolean assignment) {
106 return (assignment ? getCounter(iteration) + "x " : "")
107 + getValue().variable().getName()
108 + (assignment ? " := " : " != ")
109 + getValue().getName();
110 }
111
112 /** Compare two assignments (their counters) */
113 public int compareTo(long iteration, Assignment a) {
114 int cmp =
115 getValue().variable().getName().compareTo(
116 a.getValue().variable().getName());
117 if (cmp != 0)
118 return cmp;
119 if (getCounter(iteration) != a.getCounter(iteration))
120 return (getCounter(iteration) < a.getCounter(iteration) ? 1 : -1);
121 return getValue().getName().compareTo(a.getValue().getName());
122 }
123
124 /** Assignment comparator */
125 public static class AssignmentComparator implements java.util.Comparator {
126 private long iIteration;
127 public AssignmentComparator(long iteration) {
128 iIteration = iteration;
129 }
130 public int compare(Object o1, Object o2) {
131 if (o1 == null
132 || o2 == null
133 || !(o1 instanceof Assignment)
134 || !(o2 instanceof Assignment))
135 return 0;
136 return ((Assignment)o1).compareTo(iIteration, (Assignment)o2);
137 }
138 }
139 }