/*
* Copyright (c) 2005 Thomas Weise
*
* E-Mail : tweise@gmx.de
* Creation Date : 2005-11-28 06:09:33
* Original Filename: org.dgpf.automaton.expressions.UnaryExpression.java
* Version : 2.2.1
* Last modification: 2006-05-08
* by: Thomas Weise
*
* License : GNU LESSER GENERAL PUBLIC LICENSE
* Version 2.1, February 1999
* You should have received a copy of this license along
* with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307, USA or download the license under
* http://www.gnu.org/copyleft/lesser.html.
*
* Warranty : This software is provided "as is" without any
* warranty; without even the implied warranty of
* merchantability or fitness for a particular purpose.
* See the Gnu Lesser General Public License for more
* details.
*/
package org.dgpf.gp.automaton.expressions;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import org.dgpf.gp.automaton.base.Automaton;
import org.dgpf.gp.automaton.base.Expression;
import org.dgpf.gp.automaton.search.ExpressionHandler;
import org.sfc.utils.ICloneable;
/**
* The unary expression class.
* All calculative unary expressions are disabled, since they're
* basically not needed and can be emulated by binary expressions.
*
*
* @author Thomas Weise
*/
public final class UnaryExpression extends Expression
{
/**
* The serial version uid.
*/
private static final long serialVersionUID = 1;
/**
* The ! operation.
*/
public static final UnaryOperation LNOT = new LNot();
/**
* The ~ operation.
*/
public static final UnaryOperation BNOT = new BNot();
/**
* The - operation.
*/
public static final UnaryOperation MINUS = new Minus();
/**
* The handler used by this class.
*/
public static final ExpressionHandler HANDLER =
UnaryExpressionHandler.INSTANCE;
/**
* The sub-expression.
*/
private Expression m_sub ;
/**
* The binary operation to be performed by this expression.
*/
private transient UnaryOperation m_operation ;
/**
* The internal operation id.
*/
private int m_op ;
/**
* Create a new unary expression.
* @param p_sub The sub-expression.
* @param p_operation The unary operation to be performed by this
* expression.
*/
public UnaryExpression(final UnaryOperation p_operation,
final Expression p_sub)
{
super(1 + p_sub.get_complexity());
this.m_op = p_operation.m_id;
this.m_operation = p_operation;
this.m_sub = p_sub;
}
/**
* Initialize this unary expression.
* @param p_sub The sub-expression.
*/
final void init (final Expression p_sub)
{
this.m_sub = p_sub;
this.set_ticks(1 + p_sub.get_complexity());
}
/**
* Obtain the count of memory cells this item needs.
* @return The count of memory cells this item needs.
*/
@Override
public final int get_memory_size ()
{
return this.m_sub.get_memory_size();
}
/**
* Returns the operation executed by this expression.
* @return The operation executed by this expression.
*/
public final UnaryOperation get_operation()
{
return this.m_operation;
}
/**
* Returns the sub-expression the operation of this unary expression is
* applied to.
* @return The sub-expression the operation of this unary expression is
* applied to.
*/
public final Expression get_sub ()
{
return this.m_sub;
}
/**
* Checks wether this object is equal to another object.
* @param p_object The object to compare with.
* @return true
if and only if the two objects are exactly
* equal.
*/
@Override
public final boolean equals (final Object p_object)
{
UnaryExpression l_be;
if(p_object == this) return true;
if(p_object instanceof UnaryExpression)
{
l_be = ((UnaryExpression)p_object);
if(l_be.m_op == this.m_op)
{
return (l_be.m_sub.equals(this.m_sub));
}
}
return false;
}
/**
* Checks wether this expression has side effects, returns true
* if so.
* @return true
if and only if this expression has side
* effects.
*/
@Override
public final boolean has_side_effect ()
{
return this.m_sub.has_side_effect();
}
/**
* Reconstitute the ArrayList
instance from a stream (that is,
* deserialize it).
* @param p_s The input stream.
* @throws IOException If something io-like went wrong.
* @throws ClassNotFoundException If a needed class could not be found.
*/
private final void readObject(final ObjectInputStream p_s)
throws IOException, ClassNotFoundException
{
p_s.defaultReadObject();
this.m_operation = UnaryExpressionHandler.get_op(this.m_op);
}
/**
* This method is called when the construct is executed. It performs the
* work of the construct.
* @param p_automate The automate it is invoked on.
* @return The return value of the construct.
*/
@Override
public final int execute (final Automaton p_automate)
{
return this.m_operation.execute(this.m_sub.execute(p_automate));
}
/**
* Store this objects content into a string builder.
* @param p_sb The string builder to store stuff into.
*/
@Override
public final void to_string (final StringBuilder p_sb)
{
p_sb.append(this.m_operation.m_op);
this.m_sub.to_string(p_sb);
p_sb.append(')');
}
/**
* Returns the genetic handler of the code construct.
* @return The genetic handler of the code construct.
*/
@Override
public final ExpressionHandler get_handler ()
{
return HANDLER;
}
/**
* The internal operation class.
*
* @author Thomas Weise
*/
public static abstract class UnaryOperation implements Serializable,
ICloneable
{
/**
* The operation's name.
*/
final char[] m_op ;
/**
* The class of the operation.
*/
UnaryOperation[] m_class;
/**
* The id of the operation.
*/
int m_id ;
/**
* Create a new operation.
* @param p_operation The operation string.
*/
UnaryOperation (final char[] p_operation)
{
super();
this.m_op = p_operation;
}
/**
* Clone this object.
* @return A perfect copy of this object.
*/
@Override
public Object clone ()
{
try
{
return super.clone();
}
catch(CloneNotSupportedException l_cnse)
{
return this; //will never happen.
}
}
/**
* Calculate the expression's value for the specified automate.
* @param p_param The parameter.
* @return The value of the expression.
*/
abstract int execute (final int p_param);
}
/**
* The logical not-operation.
*
* @author Thomas Weise
*/
private static final class LNot extends UnaryOperation
{
/**
* The serial version uid.
*/
private static final long serialVersionUID = 1;
/**
* The name of this unary operation.
*/
private static final char[] NAME = new char[] {'(', '!'};
/**
* Create a new operation.
*/
LNot()
{
super(NAME);
}
/**
* Calculate the expression's value for the specified automate.
* @param p_param The parameter.
* @return The value of the expression.
*/
@Override
final int execute (final int p_param)
{
return ((p_param == FALSE) ? TRUE : FALSE);
}
}
/**
* The minus-operation.
*
* @author Thomas Weise
*/
private static final class Minus extends UnaryOperation
{
/**
* The serial version uid.
*/
private static final long serialVersionUID = 1;
/**
* The name of this unary operation.
*/
private static final char[] NAME = new char[] {'(', '-'};
/**
* Create a new operation.
*/
Minus()
{
super(NAME);
}
/**
* Calculate the expression's value for the specified automate.
* @param p_param The parameter.
* @return The value of the expression.
*/
@Override
final int execute (final int p_param)
{
return (-p_param);
}
}
/**
* The binary not-operation.
*
* @author Thomas Weise
*/
private static final class BNot extends UnaryOperation
{
/**
* The serial version uid.
*/
private static final long serialVersionUID = 1;
/**
* The name of this unary operation.
*/
private static final char[] NAME = new char[] {'(', '~'};
/**
* Create a new operation.
*/
BNot()
{
super(NAME);
}
/**
* Calculate the expression's value for the specified automate.
* @param p_param The parameter.
* @return The value of the expression.
*/
@Override
final int execute (final int p_param)
{
return (~(p_param));
}
}
}