001/* Interface representing a dependency between ports. 002 003 Copyright (c) 2008-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 */ 028package ptolemy.actor.util; 029 030/////////////////////////////////////////////////////////////////// 031//// SuperdenseDependency 032 033/** 034 This dependency represents causal relationships that have a real value 035 and a superdense time index. If the real value is infinite, this 036 represents the lack of a causal relationship. 037 A finite positive real value represents a causal dependency with (typically) 038 a time delay. A zero value represents no time delay, but whether there is 039 an immediate causal relationship depends on the index. If the index is 0, 040 then there is an immediate causal relationship. Otherwise, there is not. 041 See the paper "Causality Interfaces for Actor Networks" by Ye Zhou and 042 Edward A. Lee, ACM Transactions on Embedded Computing Systems (TECS), 043 April 2008, as available as <a href="http://www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-148.pdf"> 044 Technical Report No. UCB/EECS-2006-148</a>, 045 November 16, 2006. 046 047 @author Edward A. Lee, Slobodan Matic, Jia Zou 048 @version $Id$ 049 @since Ptolemy II 8.0 050 @Pt.ProposedRating Yellow (eal) 051 @Pt.AcceptedRating Red (eal) 052 */ 053public class SuperdenseDependency extends BooleanDependency { 054 055 /** Construct a dependency with the specified value. 056 * The constructor is private. Use valueOf() to construct 057 * an instance. 058 * @param time The real part of the dependency. 059 * @param index The supersense index part of the dependency. 060 */ 061 private SuperdenseDependency(double time, int index) { 062 super(time != Double.POSITIVE_INFINITY); 063 _time = time; 064 _index = index; 065 } 066 067 /////////////////////////////////////////////////////////////////// 068 //// public methods //// 069 070 /** Return Dependency.LESS_THAN, EQUALS, or GREATER_THAN depending 071 * on whether the argument is less than, equal to, or greater than 072 * this dependency. Real dependencies are totally ordered, so 073 * this never returns Dependency.INCOMPARABLE. The order is the 074 * usual numerical ordering of doubles, with Double.POSITIVE_INFINITY 075 * on top. 076 * <p> 077 * In the case where both dependencies have _time value equal to 078 * Double.POSITIVE_INFINITY, these two dependencies are equal, even 079 * though its indices may differ. This conforms with valueOf() method. 080 * @see #valueOf(double, int) 081 * @param dependency The dependency to compare against. 082 * @return The result of comparison. 083 * @exception ClassCastException If the argument is not an instance 084 * of SuperdenseDependency. 085 */ 086 @Override 087 public int compareTo(Dependency dependency) { 088 if (equals(dependency)) { 089 return Dependency.EQUALS; 090 } 091 if (((SuperdenseDependency) dependency)._time == Double.POSITIVE_INFINITY 092 && _time == Double.POSITIVE_INFINITY) { 093 return Dependency.EQUALS; 094 } 095 if (_time < ((SuperdenseDependency) dependency)._time) { 096 return Dependency.LESS_THAN; 097 } 098 if (_time == ((SuperdenseDependency) dependency)._time 099 && _index < ((SuperdenseDependency) dependency)._index) { 100 return Dependency.LESS_THAN; 101 } 102 return Dependency.GREATER_THAN; 103 } 104 105 /** Return true if the value of this dependency equals that 106 * of the specified one, and the specified one is an instance 107 * of RealDependency. 108 * <p> 109 * In the case where both dependencies have _time value equal to 110 * Double.POSITIVE_INFINITY, these two dependencies are equal, even 111 * though its indices may differ. This conforms with valueOf() method. 112 * @see #valueOf(double, int) 113 * @param object The object to compare against. 114 * @return true if this object is the same as the object argument. 115 */ 116 @Override 117 public boolean equals(Object object) { 118 // See http://www.technofundo.com/tech/java/equalhash.html 119 if (object == this) { 120 return true; 121 } 122 if (object == null || object.getClass() != getClass()) { 123 return false; 124 } else { 125 if (((SuperdenseDependency) object)._time == Double.POSITIVE_INFINITY 126 && _time == Double.POSITIVE_INFINITY) { 127 return true; 128 } 129 return _time == ((SuperdenseDependency) object)._time 130 && _index == ((SuperdenseDependency) object)._index; 131 } 132 } 133 134 /** Return the same hashCode that that Java Double object would 135 * return had it the same value as the real part of the value 136 * of this dependency. 137 */ 138 @Override 139 public int hashCode() { 140 long v = Double.doubleToLongBits(_time); 141 return (int) (v ^ v >>> 32); 142 } 143 144 /** Return the index value of this dependency. 145 * @return The index part of the dependency. 146 */ 147 public int indexValue() { 148 return _index; 149 } 150 151 /** Return a dependency that results from parallel composition of 152 * this one and the specified one. 153 * @param dependency The dependency to add. 154 * @return A dependency whose value is the minimum of the two dependency 155 * values. 156 * @exception ClassCastException if dependency is not a SuperdenseDependency. 157 */ 158 @Override 159 public Dependency oPlus(Dependency dependency) { 160 // NOTE: Findbugs reports this as an Unchecked/unconfirmed cast 161 if (((SuperdenseDependency) dependency)._time < _time 162 || ((SuperdenseDependency) dependency)._time == _time 163 && ((SuperdenseDependency) dependency)._index < _index) { 164 return dependency; 165 } 166 return this; 167 } 168 169 /** Return the dependency that when added to any other 170 * dependency using oPlus() yields the other dependency. 171 * @return The additive identity. 172 */ 173 @Override 174 public Dependency oPlusIdentity() { 175 return OPLUS_IDENTITY; 176 } 177 178 /** Return a dependency that results from serial composition of 179 * this one and the specified one. The real part of the result 180 * is the sum of the real parts of this and the specified dependency. 181 * The index, however, will be nonzero only if the specified 182 * dependency has a real part equal to 0.0. In that case, 183 * the index of the result will be the sum of indices of 184 * this and the specified dependency. 185 * NOTE: This implementation of oTimes is not commutative. 186 * Fortunately, the theory does not require it to be. 187 * @param dependency The dependency to multiply. 188 * @return A dependency whose value is the sum of the value of 189 * this one and the specified one. 190 * @exception ClassCastException if dependency is not a RealDependency. 191 */ 192 @Override 193 public Dependency oTimes(Dependency dependency) { 194 int index = 0; 195 // NOTE: Findbugs reports this as an Unchecked/unconfirmed cast 196 if (((SuperdenseDependency) dependency)._time == 0.0) { 197 index = _index + ((SuperdenseDependency) dependency)._index; 198 } 199 return new SuperdenseDependency( 200 _time + ((SuperdenseDependency) dependency)._time, index); 201 } 202 203 /** Return the dependency that when multiplied by any other 204 * dependency using oTimes() yields the other dependency. 205 * @return The multiplicative identity. 206 */ 207 @Override 208 public Dependency oTimesIdentity() { 209 return OTIMES_IDENTITY; 210 } 211 212 /** Return the time value of this dependency. 213 * @return The real part of the dependency. 214 */ 215 public double timeValue() { 216 return _time; 217 } 218 219 /** Return a string representation in the form 220 * "SuperdenseDependency(_time, _index)". 221 * @return A string representation. 222 */ 223 @Override 224 public String toString() { 225 return "SuperdenseDependency(" + _time + ", " + _index + ")"; 226 } 227 228 /** Return an instance of SuperdenseDependency with the specified 229 * time and index value. This is preferable to use over the constructor 230 * because it uses the same instances for the most common 231 * values. 232 * @param time The time value. 233 * @param index The index value. 234 * @return an instance of RealDependency, if value 235 * is (0.0, 0) then {@link #OTIMES_IDENTITY} is returned, if 236 * value is (Double.POSITIVE_INFINITY, n) for any n, 237 * then {@link #OPLUS_IDENTITY} 238 * is returned. Otherwise the SuperdenseDependency constructor 239 * is called. 240 */ 241 public static SuperdenseDependency valueOf(double time, int index) { 242 if (time == 0.0 && index == 0) { 243 return OTIMES_IDENTITY; 244 } else if (time == Double.POSITIVE_INFINITY) { 245 return OPLUS_IDENTITY; 246 } 247 return new SuperdenseDependency(time, index); 248 } 249 250 /////////////////////////////////////////////////////////////////// 251 //// public variables //// 252 253 // NOTE: FindBugs suggests that both these fields be final 254 // "MS: Field isn't final but should be (MS_SHOULD_BE_FINAL) 255 // A mutable static field could be changed by malicious code or by 256 // accident from another package. The field could be made final to avoid 257 // this vulnerability." 258 259 /** The additive identity. */ 260 public static final SuperdenseDependency OPLUS_IDENTITY = new SuperdenseDependency( 261 Double.POSITIVE_INFINITY, 0); 262 263 /** The multiplicative identity. */ 264 public static final SuperdenseDependency OTIMES_IDENTITY = new SuperdenseDependency( 265 0.0, 0); 266 267 /////////////////////////////////////////////////////////////////// 268 //// private variables //// 269 270 /** The superdense time index. */ 271 private int _index; 272 273 /** The real (time) value. */ 274 private double _time; 275 276}