001/* A RelationList object contains the information of the relations of a 002 guard expression. 003 004 Copyright (c) 2003-2013 The Regents of the University of California. 005 All rights reserved. 006 Permission is hereby granted, without written agreement and without 007 license or royalty fees, to use, copy, modify, and distribute this 008 software and its documentation for any purpose, provided that the above 009 copyright notice and the following two paragraphs appear in all copies 010 of this software. 011 012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 013 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 014 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 015 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 016 SUCH DAMAGE. 017 018 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 020 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 021 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023 ENHANCEMENTS, OR MODIFICATIONS. 024 025 PT_COPYRIGHT_VERSION_2 026 COPYRIGHTENDKEY 027 */ 028package ptolemy.domains.modal.kernel; 029 030import java.util.LinkedList; 031import java.util.ListIterator; 032 033/////////////////////////////////////////////////////////////////// 034//// RelationList 035 036/** 037 A RelationList object contains a list of relations of a guard expression. 038 Relations are comparison operations, for example "x ≥ 10", where x is 039 a variable. This class provides facilities for measuring how far the 040 expression is from the threshold; for example, if x = 7, then the 041 distance to the threshold is 3. Moreover, it provides a mechanism 042 for recording the current distance (via a "commit") and then later 043 accessing that distance and comparing it against the current distance. 044 The information 045 includes relation type and the difference information. (See 046 {@link ParseTreeEvaluatorForGuardExpression} for the detailed explanation 047 of relation type and difference.) This attribute is non-persistent and will 048 not be exported into MoML. 049 <p> 050 This class is designed to be used with ParseTreeEvaluatorForGuardExpression. 051 The common usage would be like: 052 <p> 053 <i>Construct a relation list for a transition with the first argument of the 054 constructor as that transition.</i> 055 <pre> 056 _relationList = new RelationList(); 057 </pre> 058 <p> 059 <i>Associate the relation list with the an object of 060 ParseTreeEvaluatorForGuardExpression</i> 061 <pre> 062 _parseTreeEvaluator = 063 new ParseTreeEvaluatorForGuardExpression(_relationList, getErrorTolerance()); 064 </pre> 065 <p> 066 See {@link Transition} for the detailed usage. 067 068 @author Haiyang Zheng 069 @version $Id$ 070 @since Ptolemy II 8.0 071 @Pt.ProposedRating Yellow (hyzheng) 072 @Pt.AcceptedRating Red (hyzheng) 073 */ 074public class RelationList { 075 /** Construct a relation list. 076 */ 077 public RelationList() { 078 _relationList = new LinkedList(); 079 } 080 081 /////////////////////////////////////////////////////////////////// 082 //// public methods //// 083 084 /** Construct a relation node with the given type and difference 085 * information of a relation, and add it to the end of the relation 086 * list. 087 * @param type The relation type of the relation. 088 * @param difference The difference of the relation. 089 */ 090 public void addRelation(int type, double difference) { 091 _relationList.add(new RelationNode(type, difference)); 092 } 093 094 /** Reset the relation list by resetting each relation node. 095 */ 096 public void resetRelationList() { 097 ListIterator relations = _relationList.listIterator(); 098 while (relations.hasNext()) { 099 ((RelationNode) relations.next()).reset(); 100 } 101 } 102 103 /** Record the current relation values so that when getPreviousMaximumDistance() 104 * is called, these recorded values are used. 105 * @see #getPreviousMaximumDistance() 106 */ 107 public void commitRelationValues() { 108 ListIterator relations = _relationList.listIterator(); 109 while (relations.hasNext()) { 110 ((RelationNode) relations.next()).commit(); 111 } 112 } 113 114 /** Destroy the relation list by deleting all the contained elements. 115 */ 116 public void destroy() { 117 _relationList.clear(); 118 } 119 120 /** Return the previous difference of the relation that has the 121 * maximum current difference. This is the value as of the last 122 * call to commitRelationValues(). 123 * @see #commitRelationValues() 124 * @return The previous distance of a relation. 125 */ 126 public double getPreviousMaximumDistance() { 127 return ((RelationNode) _relationList.get(_maximumDifferenceIndex)) 128 .getPreviousDifference(); 129 } 130 131 /** Return true if there exists an event caused by the type change of 132 * any relation. 133 * @return True If there exits an event. 134 */ 135 public boolean hasEvent() { 136 boolean result = false; 137 ListIterator relations = _relationList.listIterator(); 138 while (relations.hasNext() && !result) { 139 result = result || ((RelationNode) relations.next()).hasEvent(); 140 } 141 return result; 142 } 143 144 /** Return true if the relation list is empty. 145 * @return True If the relation list is empty. 146 */ 147 public boolean isEmpty() { 148 return _relationList.size() == 0; 149 } 150 151 /** Return the number of relations in the relation list. 152 * @return the number of relations in the relation list. 153 */ 154 public int length() { 155 return _relationList.size(); 156 } 157 158 /** Return the maximum current difference of all the relations by iterating 159 * the relation list. 160 * @return maximumDistance The maximum current distance. 161 */ 162 public double getMaximumDifference() { 163 double maxDifference = 0.0; 164 double difference = 0.0; 165 int index = 0; 166 _maximumDifferenceIndex = 0; 167 ListIterator relations = _relationList.listIterator(); 168 while (relations.hasNext()) { 169 RelationNode relation = (RelationNode) relations.next(); 170 difference = Math.abs(relation.getDifference()); 171 if (relation.typeChanged() && difference > maxDifference) { 172 maxDifference = difference; 173 _maximumDifferenceIndex = index; 174 } 175 index++; 176 } 177 return maxDifference; 178 } 179 180 /** Update the relation in the relation list referred by the 181 * relation index argument with the given type and difference 182 * information. 183 * @param relationIndex The position of the relation in the 184 * relation list. 185 * @param type The current type of the relation. 186 * @param difference The current difference of the relation. 187 */ 188 public void setRelation(int relationIndex, int type, double difference) { 189 RelationNode relationNode = (RelationNode) _relationList 190 .get(relationIndex); 191 relationNode.setType(type); 192 relationNode.setDifference(difference); 193 } 194 195 /////////////////////////////////////////////////////////////////// 196 //// private fields //// 197 // The index for the relation with the maximum current difference. 198 private int _maximumDifferenceIndex; 199 200 // The relation list. 201 private LinkedList _relationList; 202}