001/* A Synchronous default operator. 002 003 Copyright (c) 2004-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; 029 030import ptolemy.actor.TypedAtomicActor; 031import ptolemy.actor.TypedIOPort; 032import ptolemy.kernel.CompositeEntity; 033import ptolemy.kernel.util.IllegalActionException; 034import ptolemy.kernel.util.NameDuplicationException; 035import ptolemy.kernel.util.StringAttribute; 036 037/////////////////////////////////////////////////////////////////// 038//// Default 039 040/** 041 A Synchronous default operator. 042 043 <p>When the <i>preferred</i> input has a token, then the output is equal 044 to that token. If the <i>preferred</i> input is absent, then the output is 045 equal to the <i>alternate</i> input (whether it is absent or not). 046 This actor is non-strict, in that can produce an output even if 047 <i>alternate</i> input is unknown. Thus, it can be used to break 048 causality loops. 049 <p> 050 This actor is inspired by the "default" operator in the synchronous 051 language SIGNAL, and is similar to the "followed by" operator in Lustre. 052 But in the context of the Ptolemy II SR domain, its 053 behavior is deterministic. This is because the Ptolemy II SR domain 054 has a Lustre or Esterel style master clock, and this actor is given 055 the opportunity to fire on each tick of that master clock. In SIGNAL, 056 by contrast, this actor can be used to "upsample" to a higher rate 057 clock; however, without considerable care, its use in SIGNAL results 058 in nondeterminism. 059 060 <p>This actor is typically used in the SR domain, but 061 may also be used inside the Continuous domain.</p> 062 063 <p>P. Caspi, D. Pilaud, N. Halbwachs, and J. A. Plaice, "LUSTRE: A 064 Declarative Language for Programming Synchronous Systems," 065 Conference Record of the 14th Annual ACM Symp. on Principles of 066 Programming Languages, Munich, Germany, January, 1987.</p> 067 068 <p>A. Benveniste and P. Le Guernic, "Hybrid Dynamical Systems Theory 069 and the SIGNAL Language," IEEE Tr. on Automatic Control, Vol. 35, 070 No. 5, pp. 525-546, May 1990.</p> 071 072 @author Edward A. Lee 073 @version $Id$ 074 @since Ptolemy II 10.0 075 @Pt.ProposedRating Yellow (eal) 076 @Pt.AcceptedRating Red (cxh) 077 */ 078public class Default extends TypedAtomicActor { 079 /** Construct an actor in the specified container with the specified 080 * name. 081 * @param container The container. 082 * @param name The name of this actor within the container. 083 * @exception IllegalActionException If the actor cannot be contained 084 * by the proposed container. 085 * @exception NameDuplicationException If the name coincides with 086 * an actor already in the container. 087 */ 088 public Default(CompositeEntity container, String name) 089 throws IllegalActionException, NameDuplicationException { 090 super(container, name); 091 092 preferred = new TypedIOPort(this, "preferred", true, false); 093 alternate = new TypedIOPort(this, "alternate", true, false); 094 095 StringAttribute controlCardinal = new StringAttribute(alternate, 096 "_cardinal"); 097 controlCardinal.setExpression("SOUTH"); 098 099 output = new TypedIOPort(this, "output", false, true); 100 101 // Default type constraints are the right ones, so we need not 102 // explicitly declare them here. 103 } 104 105 /////////////////////////////////////////////////////////////////// 106 //// ports and parameters //// 107 108 /** The preferred input port. If there is a token here, then that 109 * token is produced on the output. Any data type is accepted. 110 */ 111 public TypedIOPort preferred; 112 113 /** The alternate input port. If there is no token on the preferred 114 * input port, then the output will equal whatever is here (including 115 * absent). Any data type is accepted. 116 */ 117 public TypedIOPort alternate; 118 119 /** The output port. The type is greater than or equal to the 120 * types of the two input ports. 121 */ 122 public TypedIOPort output; 123 124 /////////////////////////////////////////////////////////////////// 125 //// public methods //// 126 127 /** If the <i>preferred</i> input is known and present, then its token is 128 * sent to the output port. Otherwise, the output is obtained from 129 * the <i>alternate</i> input port. 130 * @exception IllegalActionException If there is no director. 131 */ 132 @Override 133 public void fire() throws IllegalActionException { 134 super.fire(); 135 if (preferred.isKnown(0)) { 136 if (preferred.hasToken(0)) { 137 output.send(0, preferred.get(0)); 138 } else { 139 // NOTE: It is essential that preferred be known 140 // to be absent before we produce the alternate, 141 // or else this will not implement a monotonic function. 142 if (alternate.isKnown(0)) { 143 if (alternate.hasToken(0)) { 144 output.send(0, alternate.get(0)); 145 } else { 146 output.send(0, null); 147 } 148 } 149 } 150 } 151 } 152 153 /** Return false. This actor is non-strict in that it can produce 154 * an output even if alternate input is unknown. 155 * @return False. 156 */ 157 @Override 158 public boolean isStrict() { 159 return false; 160 } 161 162 /** Override the base class to declare that the <i>output</i> 163 * does not depend on the <i>alternate</i> in a firing. 164 * @exception IllegalActionException If the superclass throws it. 165 */ 166 @Override 167 public void preinitialize() throws IllegalActionException { 168 super.preinitialize(); 169 removeDependency(alternate, output); 170 } 171}