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}