    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    }