001/* Base class for data capsules.
002
003 Copyright (c) 1997-2015 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.data;
029
030import ptolemy.data.type.TypeLattice;
031import ptolemy.graph.CPO;
032import ptolemy.kernel.util.IllegalActionException;
033
034///////////////////////////////////////////////////////////////////
035//// AbstractConvertibleToken
036
037/**
038 The Token base class provides a very general interface for building
039 new data types.  However, in many ways, the interface is rather complex
040 in order to allow consistent implementation of Token operations that
041 operate on tokens that are defined in different classes.  In particular,
042 this requires the duplicate operation and operationReverse methods.
043
044 <p> This base class is intended to make it easy to implement tokens
045 that perform operations on other data types.  In most (but not all)
046 cases, these operations to be performed only on types that can be
047 losslessly converted to this type (or vice versa).  The operations are
048 implemented to first perform the conversion to the same type, and then
049 to perform the operation.  This class provides a base class
050 implementation of the operation methods which performs the appropriate
051 conversion, and then defers to a protected _operation method if the
052 type of the argument of the operation is less than or equal to this
053 type.  If the argument type is greater than this type, then the
054 appropriate method is called on that type.  If the types are
055 incomparable, then this class throws an exception. The protected
056 methods should be overridden in derived classes to provide
057 type-specific operations.
058
059 @author Steve Neuendorffer
060 @version $Id$
061 @since Ptolemy II 2.1
062 @Pt.ProposedRating Yellow (neuendor)
063 @Pt.AcceptedRating Red
064
065 */
066public abstract class AbstractConvertibleToken extends Token {
067
068    ///////////////////////////////////////////////////////////////////
069    ////                         public methods                    ////
070
071    /** Return a new token whose value is the sum of this token and
072     *  the argument. Type conversion also occurs here, so that the
073     *  operation is performed at the least type necessary to ensure
074     *  precision.  The returned type is the same as the type chosen
075     *  for the operation.  Generally, this is higher of the type of
076     *  this token and the argument type.  Subclasses should not
077     *  generally override this method, but override the protected
078     *  _add() method to ensure that type conversion is performed
079     *  consistently.
080     *  @param rightArgument The token to add to this token.
081     *  @return A new token containing the result.
082     *  @exception IllegalActionException If the argument token and
083     *  this token are of incomparable types, or the operation does
084     *  not make sense for the given types.
085     */
086    @Override
087    public Token add(Token rightArgument) throws IllegalActionException {
088        int typeInfo = TypeLattice.compare(getType(), rightArgument);
089
090        if (typeInfo == CPO.SAME) {
091            return _add(rightArgument);
092        } else if (typeInfo == CPO.HIGHER) {
093            AbstractConvertibleToken convertedArgument = (AbstractConvertibleToken) getType()
094                    .convert(rightArgument);
095
096            try {
097                return _add(convertedArgument);
098            } catch (IllegalActionException ex) {
099                // If the type-specific operation fails, then create a
100                // better error message that has the types of the
101                // arguments that were passed in.
102                throw new IllegalActionException(null, ex,
103                        notSupportedMessage("add", this, rightArgument));
104            }
105        } else if (typeInfo == CPO.LOWER) {
106            return rightArgument.addReverse(this);
107        } else {
108            // The types are incomparable.
109            // However, if the rightArgument is a composite type, then
110            // addition can still happen between the this token and
111            // the elements of the composite type.
112            if (rightArgument instanceof AbstractNotConvertibleToken) {
113                return rightArgument.addReverse(this);
114            } else {
115                throw new IllegalActionException(
116                        notSupportedIncomparableMessage("add", this,
117                                rightArgument));
118            }
119        }
120    }
121
122    /** Return a new token whose value is the sum of this token
123     *  and the argument. Type conversion also occurs here, so that the
124     *  operation is performed at the least type necessary to ensure
125     *  precision.  The returned type is the same as the type chosen
126     *  for the operation.  Generally, this is higher of the type of
127     *  this token and the argument type.  Subclasses should not
128     *  generally override this method, but override the protected
129     *  _add() method to ensure that type conversion is performed
130     *  consistently.
131     *  @param leftArgument The token to add this token to.
132     *  @return A new token containing the result.
133     *  @exception IllegalActionException If the argument token and
134     *  this token are of incomparable types, or the operation does
135     *  not make sense for the given types.
136     */
137    @Override
138    public Token addReverse(ptolemy.data.Token leftArgument)
139            throws IllegalActionException {
140        int typeInfo = TypeLattice.compare(leftArgument, getType());
141
142        // We would normally expect this to be LOWER, since this will almost
143        // always be called by subtract, so put that case first.
144        if (typeInfo == CPO.LOWER) {
145            AbstractConvertibleToken convertedArgument = (AbstractConvertibleToken) getType()
146                    .convert(leftArgument);
147
148            try {
149                Token result = convertedArgument._add(this);
150                return result;
151            } catch (IllegalActionException ex) {
152                // If the type-specific operation fails, then create a
153                // better error message that has the types of the
154                // arguments that were passed in.
155                throw new IllegalActionException(null, ex,
156                        notSupportedMessage("addReverse", this, leftArgument));
157            }
158        } else if (typeInfo == CPO.SAME) {
159            Token result = ((AbstractConvertibleToken) leftArgument)._add(this);
160            return result;
161        } else if (typeInfo == CPO.HIGHER) {
162            Token result = leftArgument.add(this);
163            return result;
164        } else {
165            throw new IllegalActionException(notSupportedIncomparableMessage(
166                    "addReverse", this, leftArgument));
167        }
168    }
169
170    /** Return a new token whose value is the value of this token
171     *  divided by the value of the argument token.  Type conversion
172     *  also occurs here, so that the operation is performed at the
173     *  least type necessary to ensure precision.  The returned type
174     *  is the same as the type chosen for the operation.  Generally,
175     *  this is higher of the type of this token and the argument
176     *  type.  Subclasses should not generally override this method,
177     *  but override the protected _divide() method to ensure that type
178     *  conversion is performed consistently.
179     *  @param rightArgument The token to divide into this token.
180     *  @return A new token containing the result.
181     *  @exception IllegalActionException If the argument token
182     *   and this token are of incomparable types, or the operation
183     *   does not make sense for the given types.
184     */
185    @Override
186    public final Token divide(Token rightArgument)
187            throws IllegalActionException {
188        int typeInfo = TypeLattice.compare(getType(), rightArgument);
189
190        if (typeInfo == CPO.SAME) {
191            Token result = _divide(rightArgument);
192            return result;
193        } else if (typeInfo == CPO.HIGHER) {
194            AbstractConvertibleToken convertedArgument = (AbstractConvertibleToken) getType()
195                    .convert(rightArgument);
196
197            try {
198                Token result = _divide(convertedArgument);
199                return result;
200            } catch (IllegalActionException ex) {
201                // If the type-specific operation fails, then create a
202                // better error message that has the types of the
203                // arguments that were passed in.
204                throw new IllegalActionException(null, ex,
205                        notSupportedMessage("divide", this, rightArgument));
206            }
207        } else if (typeInfo == CPO.LOWER) {
208            Token result = rightArgument.divideReverse(this);
209            return result;
210        } else {
211            throw new IllegalActionException(notSupportedIncomparableMessage(
212                    "divide", this, rightArgument));
213        }
214    }
215
216    /** Return a new token whose value is the value of the argument token
217     *  divided by the value of this token. Type conversion
218     *  also occurs here, so that the operation is performed at the
219     *  least type necessary to ensure precision.  The returned type
220     *  is the same as the type chosen for the operation.  Generally,
221     *  this is higher of the type of this token and the argument
222     *  type.  Subclasses should not generally override this method,
223     *  but override the protected _divide() method to ensure that type
224     *  conversion is performed consistently.
225     *  @param leftArgument The token to be divided by the value of this token.
226     *  @return A new token containing the result.
227     *  @exception IllegalActionException If the argument token and
228     *  this token are of incomparable types, or the operation does
229     *  not make sense for the given types.
230     */
231    @Override
232    public final Token divideReverse(Token leftArgument)
233            throws IllegalActionException {
234        int typeInfo = TypeLattice.compare(leftArgument, getType());
235
236        // We would normally expect this to be LOWER, since this will almost
237        // always be called by subtract, so put that case first.
238        if (typeInfo == CPO.LOWER) {
239            AbstractConvertibleToken convertedArgument = (AbstractConvertibleToken) getType()
240                    .convert(leftArgument);
241
242            try {
243                Token result = convertedArgument._divide(this);
244                return result;
245            } catch (IllegalActionException ex) {
246                // If the type-specific operation fails, then create a
247                // better error message that has the types of the
248                // arguments that were passed in.
249                throw new IllegalActionException(null, ex, notSupportedMessage(
250                        "divideReverse", this, leftArgument));
251            }
252        } else if (typeInfo == CPO.SAME) {
253            Token result = ((AbstractConvertibleToken) leftArgument)
254                    ._divide(this);
255            return result;
256        } else if (typeInfo == CPO.HIGHER) {
257            Token result = leftArgument.divide(this);
258            return result;
259        } else {
260            throw new IllegalActionException(notSupportedIncomparableMessage(
261                    "divideReverse", this, leftArgument));
262        }
263    }
264
265    /** Test that the value of this token is close to the first argument,
266     *  where "close" means that the distance between them is less than
267     *  or equal to the second argument.  This method only makes sense
268     *  for tokens where the distance between them is reasonably
269     *  represented as a double. If the argument token is not of
270     *  the same type as this token, then either this token or the
271     *  argument will be converted, if possible, to the type of the other.
272     *  <p>
273     *  Subclasses should not
274     *  generally override this method, but override the protected
275     *  _isCloseTo() method to ensure that type conversion is performed
276     *  consistently.
277     *  @param token The token to test closeness of this token with.
278     *  @param epsilon The value that we use to determine whether two
279     *   tokens are close.
280     *  @return A boolean token that contains the value true if the
281     *   value and units of this token are close to those of the
282     *   argument token.
283     *  @exception IllegalActionException If the argument token and
284     *   this token are of incomparable types, or the operation does
285     *   not make sense for the given types.
286     */
287    @Override
288    public final BooleanToken isCloseTo(Token token, double epsilon)
289            throws IllegalActionException {
290        // Note that if we had absolute(), subtraction() and islessThan()
291        // we could perhaps define this method for all tokens.
292        int typeInfo = TypeLattice.compare(getType(), token);
293
294        if (typeInfo == CPO.SAME) {
295            return _isCloseTo(token, epsilon);
296        } else if (typeInfo == CPO.HIGHER) {
297            AbstractConvertibleToken convertedArgument = (AbstractConvertibleToken) getType()
298                    .convert(token);
299
300            try {
301                BooleanToken result = _isCloseTo(convertedArgument, epsilon);
302                return result;
303            } catch (IllegalActionException ex) {
304                // If the type-specific operation fails, then create a
305                // better error message that has the types of the
306                // arguments that were passed in.
307                throw new IllegalActionException(null, ex,
308                        notSupportedMessage("isCloseTo", this, token));
309            }
310        } else if (typeInfo == CPO.LOWER) {
311            return token.isCloseTo(this, epsilon);
312        } else {
313            throw new IllegalActionException(
314                    notSupportedIncomparableMessage("isCloseTo", this, token));
315        }
316    }
317
318    /** Test for equality of the values of this Token and the argument
319     *  Token.  The argument and this token are converted to
320     *  equivalent types, and then compared.  Generally, this is the
321     *  higher of the type of this token and the argument type.  This
322     *  method defers to the _isEqualTo method to perform a
323     *  type-specific equality check.  Derived classes should override
324     *  that method to provide type specific actions for equality
325     *  testing.
326     *
327     *  @param rightArgument The token with which to test equality.
328     *  @return A BooleanToken which contains the result of the test.
329     *  @exception IllegalActionException If the argument token and
330     *  this token are of incomparable types, or the operation does
331     *  not make sense for the given types.
332     */
333    @Override
334    public final BooleanToken isEqualTo(Token rightArgument)
335            throws IllegalActionException {
336        int typeInfo = TypeLattice.compare(getType(), rightArgument);
337
338        if (typeInfo == CPO.SAME) {
339            return _isEqualTo(rightArgument);
340        } else if (typeInfo == CPO.HIGHER) {
341            AbstractConvertibleToken convertedArgument = (AbstractConvertibleToken) getType()
342                    .convert(rightArgument);
343
344            try {
345                BooleanToken result = _isEqualTo(convertedArgument);
346                return result;
347            } catch (IllegalActionException ex) {
348                // If the type-specific operation fails, then create a
349                // better error message that has the types of the
350                // arguments that were passed in.
351                throw new IllegalActionException(null, ex,
352                        notSupportedMessage("isEqualTo", this, rightArgument));
353            }
354        } else if (typeInfo == CPO.LOWER) {
355            return rightArgument.isEqualTo(this);
356        } else {
357            throw new IllegalActionException(notSupportedIncomparableMessage(
358                    "isEqualTo", this, rightArgument));
359        }
360    }
361
362    /** Return a new token whose value is the value of this token
363     *  modulo the value of the argument token.  Type conversion
364     *  also occurs here, so that the operation is performed at the
365     *  least type necessary to ensure precision.  The returned type
366     *  is the same as the type chosen for the operation.  Generally,
367     *  this is higher of the type of this token and the argument
368     *  type.  Subclasses should not override this method,
369     *  but override the protected _modulo() method to ensure that type
370     *  conversion is performed consistently.
371     *  @param rightArgument The token to divide into this token.
372     *  @return A new token containing the result.
373     *  @exception IllegalActionException If the argument token and
374     *  this token are of incomparable types, or the operation does
375     *  not make sense for the given types.
376     */
377    @Override
378    public final Token modulo(Token rightArgument)
379            throws IllegalActionException {
380        int typeInfo = TypeLattice.compare(getType(), rightArgument);
381
382        if (typeInfo == CPO.SAME) {
383            Token result = _modulo(rightArgument);
384            return result;
385        } else if (typeInfo == CPO.HIGHER) {
386            AbstractConvertibleToken convertedArgument = (AbstractConvertibleToken) getType()
387                    .convert(rightArgument);
388
389            try {
390                Token result = _modulo(convertedArgument);
391                return result;
392            } catch (IllegalActionException ex) {
393                // If the type-specific operation fails, then create a
394                // better error message that has the types of the
395                // arguments that were passed in.
396                throw new IllegalActionException(null, ex,
397                        notSupportedMessage("modulo", this, rightArgument));
398            }
399        } else if (typeInfo == CPO.LOWER) {
400            Token result = rightArgument.moduloReverse(this);
401            return result;
402        } else {
403            throw new IllegalActionException(notSupportedIncomparableMessage(
404                    "modulo", this, rightArgument));
405        }
406    }
407
408    /** Return a new token whose value is the value of the argument token
409     *  modulo the value of this token.  Type conversion
410     *  also occurs here, so that the operation is performed at the
411     *  least type necessary to ensure precision.  The returned type
412     *  is the same as the type chosen for the operation.  Generally,
413     *  this is higher of the type of this token and the argument
414     *  type.  Subclasses should not override this method,
415     *  but override the protected _modulo() method to ensure that type
416     *  conversion is performed consistently.
417     *  @param leftArgument The token to apply modulo to by the value
418     *  of this token.
419     *  @return A new token containing the result.
420     *  @exception IllegalActionException If the argument token and
421     *  this token are of incomparable types, or the operation does
422     *  not make sense for the given types.
423     */
424    @Override
425    public final Token moduloReverse(Token leftArgument)
426            throws IllegalActionException {
427        int typeInfo = TypeLattice.compare(leftArgument, getType());
428
429        // We would normally expect this to be LOWER, since this will almost
430        // always be called by modulo, so put that case first.
431        if (typeInfo == CPO.LOWER) {
432            AbstractConvertibleToken convertedArgument = (AbstractConvertibleToken) getType()
433                    .convert(leftArgument);
434
435            try {
436                Token result = convertedArgument._modulo(this);
437                return result;
438            } catch (IllegalActionException ex) {
439                // If the type-specific operation fails, then create a
440                // better error message that has the types of the
441                // arguments that were passed in.
442                throw new IllegalActionException(null, ex, notSupportedMessage(
443                        "moduloReverse", this, leftArgument));
444            }
445        } else if (typeInfo == CPO.SAME) {
446            Token result = ((AbstractConvertibleToken) leftArgument)
447                    ._modulo(this);
448            return result;
449        } else if (typeInfo == CPO.HIGHER) {
450            Token result = leftArgument.modulo(this);
451            return result;
452        } else {
453            throw new IllegalActionException(notSupportedIncomparableMessage(
454                    "moduloReverse", this, leftArgument));
455        }
456    }
457
458    /** Return a new token whose value is the value of this token
459     *  multiplied by the value of the argument token.  Type conversion
460     *  also occurs here, so that the operation is performed at the
461     *  least type necessary to ensure precision.  The returned type
462     *  is the same as the type chosen for the operation.  Generally,
463     *  this is higher of the type of this token and the argument
464     *  type.  Subclasses should not generally override this method,
465     *  but override the protected _multiply() method to ensure that type
466     *  conversion is performed consistently.
467     *  @param rightArgument The token to multiply this token by.
468     *  @return A new token containing the result.
469     *  @exception IllegalActionException If the argument token
470     *   and this token are of incomparable types, or the operation
471     *   does not make sense for the given types.
472     */
473    @Override
474    public final Token multiply(Token rightArgument)
475            throws IllegalActionException {
476        int typeInfo = TypeLattice.compare(getType(), rightArgument);
477
478        if (typeInfo == CPO.SAME) {
479            Token result = _multiply(rightArgument);
480            return result;
481        } else if (typeInfo == CPO.HIGHER) {
482            AbstractConvertibleToken convertedArgument = (AbstractConvertibleToken) getType()
483                    .convert(rightArgument);
484
485            try {
486                Token result = _multiply(convertedArgument);
487                return result;
488            } catch (IllegalActionException ex) {
489                // If the type-specific operation fails, then create a
490                // better error message that has the types of the
491                // arguments that were passed in.
492                throw new IllegalActionException(null, ex,
493                        notSupportedMessage("multiply", this, rightArgument));
494            }
495        } else if (typeInfo == CPO.LOWER) {
496            Token result = rightArgument.multiplyReverse(this);
497            return result;
498        } else {
499            throw new IllegalActionException(notSupportedIncomparableMessage(
500                    "multiply", this, rightArgument));
501        }
502    }
503
504    /** Return a new token whose value is the value of the argument token
505     *  multiplied by the value of this token.  Type conversion
506     *  also occurs here, so that the operation is performed at the
507     *  least type necessary to ensure precision.  The returned type
508     *  is the same as the type chosen for the operation.  Generally,
509     *  this is higher of the type of this token and the argument
510     *  type.  Subclasses should not generally override this method,
511     *  but override the protected _multiply() method to ensure that type
512     *  conversion is performed consistently.
513     *  @param leftArgument The token to be multiplied by the value of
514     *  this token.
515     *  @return A new token containing the result.
516     *  @exception IllegalActionException If the argument token and
517     *  this token are of incomparable types, or the operation does
518     *  not make sense for the given types.
519     */
520    @Override
521    public final Token multiplyReverse(Token leftArgument)
522            throws IllegalActionException {
523        int typeInfo = TypeLattice.compare(leftArgument, getType());
524
525        // We would normally expect this to be LOWER, since this will almost
526        // always be called by multiply, so put that case first.
527        if (typeInfo == CPO.LOWER) {
528            AbstractConvertibleToken convertedArgument = (AbstractConvertibleToken) getType()
529                    .convert(leftArgument);
530
531            try {
532                Token result = convertedArgument._multiply(this);
533                return result;
534            } catch (IllegalActionException ex) {
535                // If the type-specific operation fails, then create a
536                // better error message that has the types of the
537                // arguments that were passed in.
538                throw new IllegalActionException(null, ex, notSupportedMessage(
539                        "multiplyReverse", this, leftArgument));
540            }
541        } else if (typeInfo == CPO.SAME) {
542            Token result = ((AbstractConvertibleToken) leftArgument)
543                    ._multiply(this);
544            return result;
545        } else if (typeInfo == CPO.HIGHER) {
546            Token result = leftArgument.multiply(this);
547            return result;
548        } else {
549            throw new IllegalActionException(notSupportedIncomparableMessage(
550                    "multiplyReverse", this, leftArgument));
551        }
552    }
553
554    /** Return a new token whose value is the value of the argument token
555     *  subtracted from the value of this token.   Type conversion
556     *  also occurs here, so that the operation is performed at the
557     *  least type necessary to ensure precision.  The returned type
558     *  is the same as the type chosen for the operation.  Generally,
559     *  this is higher of the type of this token and the argument
560     *  type.  Subclasses should not override this method,
561     *  but override the protected _subtract() method to ensure that type
562     *  conversion is performed consistently.
563     *  @param rightArgument The token to subtract from this token.
564     *  @return A new token containing the result.
565     *  @exception IllegalActionException If the argument token and
566     *  this token are of incomparable types, or the operation does
567     *  not make sense for the given types.
568     */
569    @Override
570    public final Token subtract(Token rightArgument)
571            throws IllegalActionException {
572        int typeInfo = TypeLattice.compare(getType(), rightArgument);
573
574        if (typeInfo == CPO.SAME) {
575            Token result = _subtract(rightArgument);
576            return result;
577        } else if (typeInfo == CPO.HIGHER) {
578            AbstractConvertibleToken convertedArgument = (AbstractConvertibleToken) getType()
579                    .convert(rightArgument);
580
581            try {
582                Token result = convertedArgument._subtract(this);
583                return result;
584            } catch (IllegalActionException ex) {
585                // If the type-specific operation fails, then create a
586                // better error message that has the types of the
587                // arguments that were passed in.
588                throw new IllegalActionException(null, ex,
589                        notSupportedMessage("subtract", this, rightArgument));
590            }
591
592        } else if (typeInfo == CPO.LOWER) {
593            Token result = rightArgument.subtractReverse(this);
594            return result;
595        } else {
596            throw new IllegalActionException(notSupportedIncomparableMessage(
597                    "subtract", this, rightArgument));
598        }
599    }
600
601    /** Return a new token whose value is the value of this token
602     *  subtracted from the value of the argument token.   Type conversion
603     *  also occurs here, so that the operation is performed at the
604     *  least type necessary to ensure precision.  The returned type
605     *  is the same as the type chosen for the operation.  Generally,
606     *  this is higher of the type of this token and the argument
607     *  type.  Subclasses should not override this method,
608     *  but override the protected _subtract() method to ensure that type
609     *  conversion is performed consistently.
610     *  @param leftArgument The token to subtract this token from.
611     *  @return A new token containing the result.
612     *  @exception IllegalActionException If the argument token and
613     *  this token are of incomparable types, or the operation does
614     *  not make sense for the given types.
615     */
616    @Override
617    public final Token subtractReverse(Token leftArgument)
618            throws IllegalActionException {
619        int typeInfo = TypeLattice.compare(leftArgument, getType());
620
621        // We would normally expect this to be LOWER, since this will almost
622        // always be called by subtract, so put that case first.
623        if (typeInfo == CPO.LOWER) {
624            AbstractConvertibleToken convertedArgument = (AbstractConvertibleToken) getType()
625                    .convert(leftArgument);
626
627            try {
628                Token result = convertedArgument._subtract(this);
629                return result;
630            } catch (IllegalActionException ex) {
631                // If the type-specific operation fails, then create a
632                // better error message that has the types of the
633                // arguments that were passed in.
634                throw new IllegalActionException(null, ex, notSupportedMessage(
635                        "subtractReverse", this, leftArgument));
636            }
637        } else if (typeInfo == CPO.SAME) {
638            Token result = ((AbstractConvertibleToken) leftArgument)
639                    ._subtract(this);
640            return result;
641        } else if (typeInfo == CPO.HIGHER) {
642            Token result = leftArgument.subtract(this);
643            return result;
644        } else {
645            throw new IllegalActionException(notSupportedIncomparableMessage(
646                    "subtractReverse", this, leftArgument));
647        }
648    }
649
650    ///////////////////////////////////////////////////////////////////
651    ////                         protected methods                 ////
652
653    /** Return a new token whose value is the value of the
654     *  argument Token added to the value of this Token.  It is assumed
655     *  that the type of the argument is the same as the type of this class.
656     *  This method should be overridden in derived
657     *  classes to provide type specific actions for add.
658     *  @param rightArgument The token whose value we add to the value of
659     *   this token.
660     *  @exception IllegalActionException If this method is not
661     *   supported by the derived class.
662     *  @return A new Token containing the result that is of the same class
663     *  as this token.
664     */
665    protected abstract Token _add(Token rightArgument)
666            throws IllegalActionException;
667
668    /** Return a new token whose value is the value of this token
669     *  divided by the value of the argument token. It is assumed
670     *  that the type of the argument is the same as the type of this class.
671     *  This method should be overridden in derived
672     *  classes to provide type specific actions for divide.
673     *  @param rightArgument The token to divide this token by.
674     *  @exception IllegalActionException If this method is not
675     *   supported by the derived class.
676     *  @return A new Token containing the result that is of the same class
677     *  as this token.
678     */
679    protected abstract Token _divide(Token rightArgument)
680            throws IllegalActionException;
681
682    /** Test that the value of this token is close to the first argument,
683     *  where "close" means that the distance between them is less than
684     *  or equal to the second argument.  This method only makes sense
685     *  for tokens where the distance between them is reasonably
686     *  represented as a double. It is assumed that the type of
687     *  the argument is the same as the type of this class.
688     *  This method should be overridden in derived classes to
689     *  provide type specific actions for the comparison.
690     *  @param token The token with which to test closeness.
691     *  @param epsilon The value that we use to determine whether two
692     *   tokens are close.
693     *  @exception IllegalActionException If this method is not
694     *   supported by a derived class.
695     *  @return A token that contains the result of the test.
696     */
697    protected abstract BooleanToken _isCloseTo(Token token, double epsilon)
698            throws IllegalActionException;
699
700    /** Test for equality of the values of this token and the argument.
701     *  It is assumed that the type of the argument is the
702     *  same as the type of this class.  This method should be
703     *  overridden in derived classes to provide type specific actions
704     *  for the comparison.
705     *  @param token The token with which to test equality.
706     *  @exception IllegalActionException If this method is not
707     *   supported by a derived class.
708     *  @return A token that contains the result of the test.
709     */
710    protected abstract BooleanToken _isEqualTo(Token token)
711            throws IllegalActionException;
712
713    /** Return a new token whose value is the value of this token
714     *  modulo the value of the argument token.  It is assumed
715     *  that the type of the argument is the same as the type of this class.
716     *  This method should be overridden in derived
717     *  classes to provide type specific actions for modulo.
718     *  @param rightArgument The token to modulo this token by.
719     *  @exception IllegalActionException If this method is not
720     *   supported by the derived class.
721     *  @return A new Token containing the result that is of the same class
722     *  as this token.
723     */
724    protected abstract Token _modulo(Token rightArgument)
725            throws IllegalActionException;
726
727    /** Return a new token whose value is the value of this token
728     *  multiplied by the value of the argument token.  It is assumed
729     *  that the type of the argument is the same as the type of this class.
730     *  This method should be overridden in derived
731     *  classes to provide type specific actions for multiply.
732     *  @param rightArgument The token to multiply this token by.
733     *  @exception IllegalActionException If this method is not
734     *   supported by the derived class.
735     *  @return A new Token containing the result that is of the same class
736     *  as this token.
737     */
738    protected abstract Token _multiply(Token rightArgument)
739            throws IllegalActionException;
740
741    /** Return a new token whose value is the value of the argument token
742     *  subtracted from the value of this token.  It is assumed
743     *  that the type of the argument is the same as the type of this class.
744     *  This method should be overridden in derived
745     *  classes to provide type specific actions for subtract.
746     *  @param rightArgument The token to subtract from this token.
747     *  @exception IllegalActionException If this method is not
748     *   supported by the derived class.
749     *  @return A new Token containing the result that is of the same class
750     *  as this token.
751     */
752    protected abstract Token _subtract(Token rightArgument)
753            throws IllegalActionException;
754}