001/** Base class for structured type. 002 003 Copyright (c) 1997-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 028 */ 029package ptolemy.data.type; 030 031import ptolemy.kernel.util.IllegalActionException; 032 033/////////////////////////////////////////////////////////////////// 034//// StructuredType 035 036/** 037 Base class for structured type. Making this an abstract class (not an 038 interface) allows the methods to be protected. 039 All the types of the same structured type (e.g. all the array types) 040 must form a lattice. Each instance of a structured type must know how 041 to compare itself with another instance of the same structured type, 042 and compute the least upper bound and greatest lower bound. This 043 class defines methods for these operations. 044 <p> 045 Subclasses should override clone() to do a deep cloning. 046 047 @author Yuhong Xiong, Steve Neuendorffer 048 @version $Id$ 049 @since Ptolemy II 0.4 050 @Pt.ProposedRating Red (yuhong) 051 @Pt.AcceptedRating Red (cxh) 052 */ 053public abstract class StructuredType implements Type { 054 /////////////////////////////////////////////////////////////////// 055 //// public methods //// 056 057 /** Return a new type which represents the type that results from 058 * adding a token of this type and a token of the given argument 059 * type. 060 * @param rightArgumentType The type to add to this type. 061 * @return A new type, or BaseType.GENERAL, if the operation does 062 * not make sense for the given types. 063 */ 064 @Override 065 public Type add(Type rightArgumentType) { 066 return TypeLattice.leastUpperBound(this, rightArgumentType); 067 } 068 069 /** Return a deep copy of this StructuredType. 070 * @return A StructuredType. 071 * @exception CloneNotSupportedException Not thrown in this base class. 072 */ 073 @Override 074 abstract public Object clone() throws CloneNotSupportedException; 075 076 /** Return a new type which represents the type that results from 077 * dividing a token of this type and a token of the given 078 * argument type. 079 * @param rightArgumentType The type to divide with this type. 080 * @return A new type, or BaseType.GENERAL, if the operation does 081 * not make sense for the given types. 082 */ 083 @Override 084 public Type divide(Type rightArgumentType) { 085 return TypeLattice.leastUpperBound(this, rightArgumentType); 086 } 087 088 /** Return the depth of a structured type. The depth of a 089 * structured type is the number of times a structured type 090 * contains other structured types. For example, an array 091 * of arrays has depth 2, and an array of arrays of records 092 * has depth 3. 093 * @return the depth of a structured type. 094 */ 095 public int depth() { 096 return 1; 097 } 098 099 /** Return a perfect hash for this type. This number corresponds 100 * uniquely to a particular type, and is used to improve 101 * performance of certain operations in the TypeLattice class. 102 * All instances of a particular type (e.g. integer array) must 103 * return the same number. Types that return HASH_INVALID will 104 * not have results in TypeLattice cached. Note that it is safer 105 * to return HASH_INVALID, than to return a number that is not 106 * unique, or different number for the same type from different 107 * instances. This base class returns HASH_INVALID. 108 * @return A number greater than or equal to 0, or HASH_INVALID. 109 */ 110 @Override 111 public int getTypeHash() { 112 return Type.HASH_INVALID; 113 } 114 115 /** Return true if this type does not correspond to a single token 116 * class. This occurs if the type is not instantiable, or it 117 * represents either an abstract base class or an interface. 118 * This method should be overridden in derived classes to return 119 * true only for types which are not abstract. 120 * @return true. 121 */ 122 @Override 123 public boolean isAbstract() { 124 return true; 125 126 } 127 128 /** Set the elements that have declared type BaseType.UNKNOWN to the 129 * specified type. 130 * @param type A Type. 131 */ 132 public abstract void initialize(Type type); 133 134 /** Return a new type which represents the type that results from 135 * moduloing a token of this type and a token of the given 136 * argument type. 137 * @param rightArgumentType The type to add to this type. 138 * @return A new type, or BaseType.GENERAL, if the operation does 139 * not make sense for the given types. 140 */ 141 @Override 142 public Type modulo(Type rightArgumentType) { 143 return TypeLattice.leastUpperBound(this, rightArgumentType); 144 } 145 146 /** Return a new type which represents the type that results from 147 * multiplying a token of this type and a token of the given 148 * argument type. 149 * @param rightArgumentType The type to multiply by this type. 150 * @return A new type, or BaseType.GENERAL, if the operation does 151 * not make sense for the given types. 152 */ 153 @Override 154 public Type multiply(Type rightArgumentType) { 155 return TypeLattice.leastUpperBound(this, rightArgumentType); 156 } 157 158 /** Return the type of the multiplicative identity for elements of 159 * this type. 160 * @return A new type, or BaseType.GENERAL, if the operation does 161 * not make sense for the given types. 162 */ 163 @Override 164 public Type one() { 165 return this; 166 } 167 168 /** Return a new type which represents the type that results from 169 * subtracting a token of this type and a token of the given 170 * argument type. 171 * @param rightArgumentType The type to add to this type. 172 * @return A new type, or BaseType.GENERAL, if the operation does 173 * not make sense for the given types. 174 */ 175 @Override 176 public Type subtract(Type rightArgumentType) { 177 return TypeLattice.leastUpperBound(this, rightArgumentType); 178 } 179 180 /** Update this StructuredType to the specified Structured Type. 181 * The specified type must have depth less than the MAXDEPTHBOUND, and 182 * have the same structure as this type. 183 * This method will only update the component type that is 184 * BaseType.UNKNOWN, and leave the constant part of this type intact. 185 * @param newType A StructuredType. 186 * @exception IllegalActionException If the specified type has a 187 * different structure. 188 */ 189 public void updateType(StructuredType newType) 190 throws IllegalActionException { 191 if (newType.depth() >= MAXDEPTHBOUND) { 192 throw new IllegalActionException( 193 "Large type structure detected during type resolution." 194 + " The structured type " + newType.toString() 195 + " has depth larger than the bound " 196 + MAXDEPTHBOUND 197 + ". This may be an indicator of type constraints " 198 + "in a model with no finite solution."); 199 } 200 } 201 202 /** Return the type of the additive identity for elements of 203 * this type. 204 * @return A new type, or BaseType.GENERAL, if the operation does 205 * not make sense for the given types. 206 */ 207 @Override 208 public Type zero() { 209 return this; 210 } 211 212 /////////////////////////////////////////////////////////////////// 213 //// protected methods //// 214 215 /** Compare this type with the specified type. The specified type 216 * must be of the same structured type, otherwise an exception will 217 * be thrown. 218 * This method returns one of ptolemy.graph.CPO.LOWER, 219 * ptolemy.graph.CPO.SAME, ptolemy.graph.CPO.HIGHER, 220 * ptolemy.graph.CPO.INCOMPARABLE, indicating this type is lower 221 * than, equal to, higher than, or incomparable with the 222 * specified type in the type hierarchy, respectively. 223 * @param type a StructuredType. 224 * @return An integer. 225 * @exception IllegalArgumentException If the specified type is 226 * not the same structured type as this one. 227 */ 228 protected abstract int _compare(StructuredType type); 229 230 /** Return a static instance of this structured type. The return 231 * value is used by TypeLattice to represent this type. 232 * @return a StructuredType. 233 */ 234 protected abstract StructuredType _getRepresentative(); 235 236 /** Return the greatest lower bound of this type with the specified 237 * type. The specified type must be of the same structured type, 238 * otherwise an exception will be thrown. 239 * @param type a StructuredType. 240 * @return a StructuredType. 241 * @exception IllegalArgumentException If the specified type is 242 * not the same structured type as this one. 243 */ 244 protected abstract StructuredType _greatestLowerBound(StructuredType type); 245 246 /** Return the least upper bound of this type with the specified 247 * type. The specified type must be of the same structured type, 248 * otherwise an exception will be thrown. 249 * @param type a StructuredType. 250 * @return a StructuredType. 251 * @exception IllegalArgumentException If the specified type is 252 * not the same structured type as this one. 253 */ 254 protected abstract StructuredType _leastUpperBound(StructuredType type); 255 256 /** Set up a bound for the max depth of structured types. This bound 257 * is used to detect infinite iterations. 258 */ 259 protected static final int MAXDEPTHBOUND = 20; 260}