001/* An actor that performs a specified logic operation on the input. 002 003 Copyright (c) 1998-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.lib.logic; 029 030import java.util.Locale; 031 032import ptolemy.actor.lib.Transformer; 033import ptolemy.data.BooleanToken; 034import ptolemy.data.Token; 035import ptolemy.data.type.BaseType; 036import ptolemy.kernel.CompositeEntity; 037import ptolemy.kernel.util.Attribute; 038import ptolemy.kernel.util.IllegalActionException; 039import ptolemy.kernel.util.InternalErrorException; 040import ptolemy.kernel.util.NameDuplicationException; 041import ptolemy.kernel.util.StringAttribute; 042 043// NOTE: If you update the list of functions, then you will want 044// to update the list in actor/lib/logic/logic.xml. 045/////////////////////////////////////////////////////////////////// 046//// LogicFunction 047 048/** 049 <p>Produce an output token on each firing with a value that is 050 equal to the specified logic operator of the input(s). 051 The functions are:</p> 052 <ul> 053 <li> <b>and</b>: The logical and operator. 054 This is the default function for this actor.</li> 055 <li> <b>or</b>: The logical or operator.</li> 056 <li> <b>xor</b>: The logical xor operator.</li> 057 <li> <b>nand</b>: The logical nand operator. 058 Equivalent to the negation of <i>and</i>.</li> 059 <li> <b>nor</b>: The logical nor operator. 060 Equivalent to the negation of <i>or</i>.</li> 061 <li> <b>xnor</b>: The logical xnor operator. 062 Equivalent to the negation of <i>xor</i>.</li> 063 </ul> 064 <p> 065 NOTE: All operators have 066 a single input port, which is a multiport, and a single output port, which 067 is not a multiport. All ports have type boolean.</p> 068 <p> 069 This actor does not require that each input 070 channel have a token upon firing. As long as one channel contains a 071 token, output will be produced. If no input tokens are available at 072 all, then no output is produced. At most one token is consumed 073 on each input channel.</p> 074 075 @author Paul Whitaker 076 @deprecated Use LogicGate instead. 077 @version $Id$ 078 @since Ptolemy II 1.0 079 @Pt.ProposedRating Green (pwhitake) 080 @Pt.AcceptedRating Green (pwhitake) 081 */ 082@Deprecated 083public class LogicFunction extends Transformer { 084 /** Construct an actor with the given container and name. Set the 085 * logic function to the default ("and"). Set the types of the ports 086 * to boolean. 087 * @param container The container. 088 * @param name The name of this actor. 089 * @exception IllegalActionException If the actor cannot be contained 090 * by the proposed container. 091 * @exception NameDuplicationException If the container already has an 092 * actor with this name. 093 */ 094 public LogicFunction(CompositeEntity container, String name) 095 throws NameDuplicationException, IllegalActionException { 096 super(container, name); 097 098 // Parameters 099 function = new StringAttribute(this, "function"); 100 function.setExpression("and"); 101 _function = _AND; 102 _negate = false; 103 104 // Ports 105 input.setMultiport(true); 106 output.setMultiport(false); 107 input.setTypeEquals(BaseType.BOOLEAN); 108 output.setTypeEquals(BaseType.BOOLEAN); 109 110 _attachText("_iconDescription", 111 "<svg>\n" + "<rect x=\"-30\" y=\"-15\" " 112 + "width=\"60\" height=\"30\" " 113 + "style=\"fill:white\"/>\n" + "</svg>\n"); 114 } 115 116 /////////////////////////////////////////////////////////////////// 117 //// ports and parameters //// 118 119 /** The function to compute. This is a string-valued attribute 120 * that defaults to "and". 121 */ 122 public StringAttribute function; 123 124 /////////////////////////////////////////////////////////////////// 125 //// public methods //// 126 127 /** Override the base class to determine which function is being 128 * specified. Read the value of the function attribute and set 129 * the cached value appropriately. 130 * @param attribute The attribute that changed. 131 * @exception IllegalActionException If the function is not recognized. 132 */ 133 @Override 134 public void attributeChanged(Attribute attribute) 135 throws IllegalActionException { 136 if (attribute == function) { 137 String functionName = function.getExpression().trim() 138 .toLowerCase(Locale.getDefault()); 139 140 if (functionName.equals("and")) { 141 _function = _AND; 142 _negate = false; 143 } else if (functionName.equals("or")) { 144 _function = _OR; 145 _negate = false; 146 } else if (functionName.equals("xor")) { 147 _function = _XOR; 148 _negate = false; 149 } else if (functionName.equals("nand")) { 150 _function = _AND; 151 _negate = true; 152 } else if (functionName.equals("nor")) { 153 _function = _OR; 154 _negate = true; 155 } else if (functionName.equals("xnor")) { 156 _function = _XOR; 157 _negate = true; 158 } else { 159 throw new IllegalActionException(this, 160 "Unrecognized logic function: " + functionName 161 + ". Valid functions are 'and', 'or', 'xor', " 162 + "'nand', 'nor', and 'xnor'."); 163 } 164 } else { 165 super.attributeChanged(attribute); 166 } 167 } 168 169 /** Consume at most one input token from each input channel, 170 * and produce a token on the output port. If there is no 171 * input on any channel, then produce no output. 172 * @exception IllegalActionException If there is no director. 173 */ 174 @Override 175 public void fire() throws IllegalActionException { 176 super.fire(); 177 BooleanToken value = null; 178 BooleanToken in = null; 179 180 for (int i = 0; i < input.getWidth(); i++) { 181 if (input.hasToken(i)) { 182 in = (BooleanToken) input.get(i); 183 184 if (in != null) { 185 value = _updateFunction(in, value); 186 } 187 } 188 } 189 190 if (value != null) { 191 if (_negate) { 192 value = value.not(); 193 } 194 195 output.send(0, value); 196 } 197 } 198 199 /////////////////////////////////////////////////////////////////// 200 //// protected methods //// 201 202 /** Calculate the function on the given arguments. 203 * @param in The new input value. Should never be null. 204 * @param old The old result value, or null if there is none. 205 * @return The result of applying the function. 206 * @exception IllegalActionException If thrown by BooleanToken operations. 207 */ 208 protected BooleanToken _updateFunction(BooleanToken in, BooleanToken old) 209 throws IllegalActionException { 210 Token result; 211 212 if (old == null) { 213 result = in; 214 } else { 215 switch (_function) { 216 case _AND: 217 result = old.and(in); 218 break; 219 220 case _OR: 221 result = old.or(in); 222 break; 223 224 case _XOR: 225 result = old.xor(in); 226 break; 227 228 default: 229 throw new InternalErrorException( 230 "Invalid value for _function private variable. " 231 + "LogicFunction actor (" + getFullName() + ")" 232 + " on function type " + _function); 233 } 234 } 235 236 return (BooleanToken) result; 237 } 238 239 /////////////////////////////////////////////////////////////////// 240 //// protected variables //// 241 242 /** An indicator for the function to compute. 243 * Valid values are {@link #_AND}, {@link #_OR}, and {@link #_XOR}. 244 */ 245 protected int _function; 246 247 /** True if the intermediate results should be negated. */ 248 protected boolean _negate; 249 250 /** Perform a logical AND. */ 251 protected static final int _AND = 0; 252 253 /** Perform a logical OR. */ 254 protected static final int _OR = 1; 255 256 /** Perform a logical XOR. */ 257 protected static final int _XOR = 2; 258}