001/* Interface representing a dependency between ports.
002
003 Copyright (c) 2008-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 */
028package ptolemy.actor.util;
029
030///////////////////////////////////////////////////////////////////
031//// BooleanDependency
032
033/**
034 This dependency represents causal relationships that are either
035 present or not. That is, given any two ports, either one depends
036 causally on the other or not. See the paper "Causality Interfaces for
037 Actor Networks" by Ye Zhou and Edward A. Lee, ACM Transactions on
038 Embedded Computing Systems (TECS), April 2008, as available as <a
039 href="http://www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-148.pdf">
040 Technical Report No. UCB/EECS-2006-148</a>, November 16, 2006.
041
042 @author Edward A. Lee
043 @version $Id$
044 @since Ptolemy II 8.0
045 @Pt.ProposedRating Yellow (eal)
046 @Pt.AcceptedRating Red (eal)
047 */
048public class BooleanDependency implements Dependency {
049
050    /** Construct a dependency with the specified value.
051     *  Note that the constructor is private. Use valueOf()
052     *  to create instances.
053     *  @param value The value.
054     */
055    protected BooleanDependency(boolean value) {
056        _value = value;
057    }
058
059    ///////////////////////////////////////////////////////////////////
060    ////                         public methods                    ////
061
062    /** Return Dependency.LESS_THAN, EQUALS, or GREATER_THAN depending
063     *  on whether the argument is less than, equal to, or greater than
064     *  this dependency. Boolean dependencies are totally ordered, so
065     *  this never returns Dependency.INCOMPARABLE. The order is that
066     *  the OPLUS_IDENTITY (false) is less than OTIMES_IDENTITY (true).
067     *  @param dependency The dependency to compare against.
068     *  @return The result of comparison.
069     */
070    @Override
071    public int compareTo(Dependency dependency) {
072        if (equals(dependency)) {
073            return Dependency.EQUALS;
074        }
075        if (_value) {
076            return Dependency.LESS_THAN;
077        }
078        return Dependency.GREATER_THAN;
079    }
080
081    /** Return true if the value of this dependency equals that
082     *  of the specified one, and the specified one is an instance
083     *  of RealDependency.
084     *  @param object The object to compare against.
085     *  @return true if the values are equal
086     */
087    @Override
088    public boolean equals(Object object) {
089        // See http://www.technofundo.com/tech/java/equalhash.html
090        if (object == this) {
091            return true;
092        }
093        if (object == null || object.getClass() != getClass()) {
094            return false;
095        } else {
096            return _value == ((BooleanDependency) object)._value;
097        }
098    }
099
100    /** Return the same hashCode that that Java Boolean object would
101     *  return had it the same value, which is
102     *  the integer 1231 if this object represents true,
103     *  and the integer 1237 if this object represents false.
104     *  @return A hash code for this object.
105     */
106    @Override
107    public int hashCode() {
108        if (_value) {
109            return 1231;
110        }
111        return 1237;
112    }
113
114    /** Return a dependency that results from parallel composition of
115     *  this one and the specified one. This is a dependency whose
116     *  value is the logical OR of the value of this dependency and
117     *  specified one.
118     *  @param d The dependency to add.
119     *  @return A dependency whose value is the logical OR of the two dependency
120     *   values.
121     *  @exception ClassCastException if d is not a BooleanDependency.
122     */
123    @Override
124    public Dependency oPlus(Dependency d) {
125        // FIXME: Findbugs reports this as an Unchecked/unconfirmed cast
126        if (((BooleanDependency) d)._value || _value) {
127            return OTIMES_IDENTITY;
128        }
129        return OPLUS_IDENTITY;
130    }
131
132    /** Return the dependency that when added to any other
133     *  dependency using oPlus() yields the other dependency.
134     *  @return The additive identity.
135     */
136    @Override
137    public Dependency oPlusIdentity() {
138        return OPLUS_IDENTITY;
139    }
140
141    /** Return a dependency that results from serial composition of
142     *  this one and the specified one. This is a dependency whose
143     *  value is the logical AND of the value of this dependency and
144     *  specified one.
145     *  @param d The dependency to multiply.
146     *  @return A dependency whose value is the logical AND of the value of
147     *   this one and the specified one.
148     *  @exception ClassCastException if d is not a BooleanDependency.
149     */
150    @Override
151    public Dependency oTimes(Dependency d) {
152        // FIXME: Findbugs reports this as an Unchecked/unconfirmed cast
153        if (_value && ((BooleanDependency) d)._value) {
154            return OTIMES_IDENTITY;
155        }
156        return OPLUS_IDENTITY;
157    }
158
159    /** Return the dependency that when multiplied by any other
160     *  dependency using oTimes() yields the other dependency.
161     *  @return The multiplicative identity.
162     */
163    @Override
164    public Dependency oTimesIdentity() {
165        return OTIMES_IDENTITY;
166    }
167
168    /** Return a string representation in the form
169     *  "BooleanDependency(value)", where value is "true"
170     *  or "false".
171     *  @return A string representation.
172     */
173    @Override
174    public String toString() {
175        if (_value) {
176            return "BooleanDependency(true)";
177        }
178        return "BooleanDependency(false)";
179    }
180
181    /** Return an instance of BooleanDependency with the specified
182     *  value. This is preferable to use over the constructor
183     *  because there are only ever two possible values.
184     *  @param value  The specified value.
185     *  @return an instance of BooleanDependency, if value
186     *  is true, then {@link #OTIMES_IDENTITY} is returned, if
187     *  value is false, then {@link #OPLUS_IDENTITY}.
188     */
189    public static BooleanDependency valueOf(boolean value) {
190        if (value) {
191            return OTIMES_IDENTITY;
192        }
193        return OPLUS_IDENTITY;
194    }
195
196    ///////////////////////////////////////////////////////////////////
197    ////                         public variables                  ////
198
199    // FIXME: FindBugs suggests that both these fields be final
200    // "MS: Field isn't final but should be (MS_SHOULD_BE_FINAL)
201    // A mutable static field could be changed by malicious code or by
202    // accident from another package. The field could be made final to avoid
203    // this vulnerability."
204
205    /** The additive identity, which has value false and indicates
206     *  that there is no dependency.
207     */
208    public static final BooleanDependency OPLUS_IDENTITY = new BooleanDependency(
209            false);
210
211    /** The multiplicative identity, which has value true and
212     *  indicates that there is a dependency.
213     */
214    public static final BooleanDependency OTIMES_IDENTITY = new BooleanDependency(
215            true);
216
217    ///////////////////////////////////////////////////////////////////
218    ////                         private variables                 ////
219
220    /** The value. */
221    protected boolean _value;
222}