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    }