001/* A collection that contains Unit constraints. 002 003 Copyright (c) 2003-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_3 025 COPYRIGHTENDKEY 026 @Pt.ProposedRating Red (rowland) 027 @Pt.AcceptedRating Red (rowland) 028 */ 029package ptolemy.moml.unit; 030 031import java.util.Iterator; 032import java.util.List; 033import java.util.Vector; 034 035import ptolemy.actor.IOPort; 036import ptolemy.actor.IORelation; 037import ptolemy.actor.TypedCompositeActor; 038import ptolemy.kernel.ComponentEntity; 039import ptolemy.kernel.util.IllegalActionException; 040 041/////////////////////////////////////////////////////////////////// 042//// UnitConstraints 043 044/** 045 UnitConstraints represents a group, with duplicates allowed, of 046 UnitConstraints. The are two general ways to create an instance of this class. 047 The first requires you to create an instance without any UnitConstraints and 048 then add them with the method addConstraint. The second is to specify a 049 TypedCompositeActor as well as specific nodes and relations in the 050 TypedCompositeActor, and have the UnitConstraintCollection constructor 051 determine which UnitConstraints belong to the collection. 052 @author Rowland R Johnson 053 @version $Id$ 054 @since Ptolemy II 8.0 055 @Pt.ProposedRating Red (cxh) 056 @Pt.AcceptedRating Red (cxh) 057 */ 058public class UnitConstraints implements UnitPresentation { 059 /** Construct an empty collection of Unit constraints. 060 * 061 */ 062 public UnitConstraints() { 063 _constraints = new Vector(); 064 } 065 066 /** Construct a collection of Unit constraints from the specified 067 * componentEntities and relations of a model. 068 * <p> 069 * For each componentEntity each constraints in 070 * the form of Unit equation is retrieved and then used a basis to create a 071 * Unit constraint to add to the collection. Each port on the 072 * componentEntity is inspected to see if it has a Unit specified for it. 073 * If so, then that Unit specification is used to create a corresponding 074 * Unit constraint that gets added to the collection. 075 * <p> 076 * A component entity itself may have Unit constraint(s) that then get added 077 * to the collection. For example, the AddSubtract actor would likely have a 078 * constraint that requires that the plus, and minus ports be equal. 079 * <p> 080 * The relations are then considered. Any relation that connects two ports 081 * seen on a component entity in the first step is used to create a Unit 082 * equation that gets added to the collection. 083 * @param model The model containing the component entities. 084 * @param entities The component entities. 085 * @param relations The relations. 086 */ 087 public UnitConstraints(TypedCompositeActor model, Vector entities, 088 Vector relations) throws IllegalActionException { 089 this(); 090 _model = model; 091 _bindings = new Bindings(entities); 092 093 for (int i = 0; i < entities.size(); i++) { 094 ComponentEntity componentEntity = (ComponentEntity) entities 095 .elementAt(i); 096 Vector actorConstraints = new Vector(); 097 List unitsAttrs = componentEntity 098 .attributeList(UnitAttribute.class); 099 100 for (int j = 0; j < unitsAttrs.size(); j++) { 101 UnitAttribute attr = (UnitAttribute) unitsAttrs.get(j); 102 103 if (attr.getName().equals("_unitConstraints")) { 104 actorConstraints 105 .addAll(attr.getUnitConstraints().getConstraints()); 106 } 107 } 108 109 for (int j = 0; j < actorConstraints.size(); j++) { 110 UnitEquation uEquation = ((UnitEquation) actorConstraints 111 .elementAt(j)).copy(); 112 _equationVisitor.expand(uEquation, componentEntity); 113 uEquation.setSource(componentEntity); 114 addConstraint(uEquation); 115 } 116 117 Iterator iter = componentEntity.portList().iterator(); 118 119 while (iter.hasNext()) { 120 IOPort actorPort = (IOPort) iter.next(); 121 UnitExpr rhsExpr = null; 122 UnitAttribute ua = (UnitAttribute) actorPort 123 .getAttribute("_units"); 124 125 if (ua != null) { 126 rhsExpr = ua.getUnitExpr(); 127 } 128 129 if (rhsExpr != null) { 130 UnitExpr lhsExpr = new UnitExpr(actorPort); 131 UnitEquation uC = new UnitEquation(lhsExpr, rhsExpr); 132 uC.setSource(actorPort); 133 addConstraint(uC); 134 } 135 } 136 } 137 138 for (int i = 0; i < relations.size(); i++) { 139 IORelation relation = (IORelation) relations.elementAt(i); 140 List ports = relation.linkedPortList(); 141 IOPort inputPort = null; 142 Iterator portIter = ports.iterator(); 143 144 while (portIter.hasNext()) { 145 IOPort port = (IOPort) portIter.next(); 146 147 if (port.isOutput()) { 148 inputPort = port; 149 } 150 } 151 152 if (inputPort != null && _bindings.bindingExists(inputPort 153 .getName(inputPort.getContainer().getContainer()))) { 154 Iterator portsIterator = ports.iterator(); 155 156 while (portsIterator.hasNext()) { 157 IOPort outPort = (IOPort) portsIterator.next(); 158 159 if (outPort != inputPort && _bindings.bindingExists(outPort 160 .getName(outPort.getContainer().getContainer()))) { 161 UnitExpr lhsUExpr = new UnitExpr(outPort); 162 UnitExpr rhsUExpr = new UnitExpr(inputPort); 163 UnitEquation uC = new UnitEquation(lhsUExpr, rhsUExpr); 164 uC.setSource(relation); 165 this.addConstraint(uC); 166 } 167 } 168 } 169 } 170 } 171 172 /////////////////////////////////////////////////////////////////// 173 //// public methods //// 174 175 /** Add a UnitConstraint to the collection. 176 * @param constraint The UnitConstraint to be added to the collection. 177 */ 178 public void addConstraint(UnitConstraint constraint) { 179 _constraints.add(constraint); 180 } 181 182 /** Generate a complete solution. 183 * @return The solution. 184 */ 185 public Solution completeSolution() throws IllegalActionException { 186 Solution solution = null; 187 188 if (_debug) { 189 System.out.println( 190 "Constraints\n" + descriptiveForm() + "\\Constraints"); 191 } 192 193 Solution G = new Solution(_model, _bindings.variableLabels(), 194 getConstraints()); 195 solution = G.completeSolution(); 196 return solution; 197 } 198 199 /** 200 * @see ptolemy.moml.unit.UnitPresentation#descriptiveForm() 201 */ 202 @Override 203 public String descriptiveForm() { 204 if (_constraints == null) { 205 return null; 206 } 207 208 StringBuffer retv = new StringBuffer(); 209 210 if (!_constraints.isEmpty()) { 211 retv.append(((UnitEquation) _constraints.elementAt(0)) 212 .descriptiveForm()); 213 } 214 215 for (int i = 1; i < _constraints.size(); i++) { 216 retv.append(";" 217 + ((UnitEquation) _constraints.get(i)).descriptiveForm()); 218 } 219 220 return retv.toString(); 221 } 222 223 /** Get the constraints in the collection. 224 * @return The constraints. 225 */ 226 public Vector getConstraints() { 227 return _constraints; 228 } 229 230 /** Generate the minimal span solutions of the collection. 231 * @return The minimal span solutions. 232 */ 233 public Vector minimalSpanSolutions() throws IllegalActionException { 234 Vector solutions = null; 235 236 if (_debug) { 237 System.out.println( 238 "Constraints\n" + descriptiveForm() + "\\Constraints"); 239 } 240 241 Solution G = new Solution(_model, _bindings.variableLabels(), 242 getConstraints()); 243 244 //G.setDebug(_debug); 245 solutions = G.minimalSpanSolutions(); 246 247 if (_debug) { 248 System.out.println(G.headerInfo()); 249 250 for (int i = 0; i < solutions.size(); i++) { 251 System.out.println( 252 ((Solution) solutions.elementAt(i)).stateInfo()); 253 } 254 } 255 256 return solutions; 257 } 258 259 /////////////////////////////////////////////////////////////////// 260 //// private methods //// 261 //private void _debug(String msg) { 262 // if (_debug) { 263 // System.out.println(msg); 264 // } 265 //} 266 267 /////////////////////////////////////////////////////////////////// 268 //// private variables //// 269 private Bindings _bindings = null; 270 271 private Vector _constraints = null; 272 273 private boolean _debug = false; 274 275 private static ExpandPortNames _equationVisitor = new ExpandPortNames(); 276 277 private TypedCompositeActor _model = null; 278}