package org.dgpf.gp.regression.base;
import org.dgpf.gp.regression.expressions.Costs;
/**
* A formula holds one single expression and a target variable where it
* will be assigned to.
*
* @author Thomas Weise
*/
public final class Formula extends FormulaBase
{
/**
* The serial version uid.
*/
private static final long serialVersionUID = 1;
/**
* The expression.
*/
private final Expression m_expression ;
/**
* The identifier of the variable to assign to.
*/
private final int m_variable ;
/**
* Create a new formula.
* @param p_expression The expression to compute.
* @param p_variable The variable to assign the expression's result to.
*/
public Formula (final Expression p_expression,
final int p_variable)
{
super();
this.m_expression = p_expression.get_handler().optimize(p_expression);
this.m_variable = p_variable;
}
/**
* Obtain the expression computed by this formula.
* @return The expression computed by this formula.
*/
public final Expression get_expression()
{
return this.m_expression;
}
/**
* Obtain the variable the formula's result will be assigned to.
* @return The variable the formula's result will be assigned to.
*/
public final int get_variable()
{
return this.m_variable;
}
/**
* Returns the costs that will arise when executing this expression.
* This is defined as the costs of exactly this expression plus the costs
* of all sub-expressions.
* @return The costs of executing this expression.
*/
@Override
public final double get_costs ()
{
return (Costs.VARIABLE_ACCESS_COSTS + this.m_expression.get_costs());
}
/**
* Returns the count of variable used.
* @return The count of variable used.
*/
@Override
public final int get_variable_count ()
{
return Math.max((this.m_variable + 1),
this.m_expression.get_variable_count());
}
/**
* 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)
{
AggregationUtils.get_variable_name(this.m_variable, p_sb);
p_sb.append(AggregationUtils.EQU);
this.m_expression.to_string(p_sb);
}
/**
* Compute the expression value.
* @param p_calculator The calculator this expression should be evaluated
* on.
* @return The computed expression value.
*/
@Override
public final double compute (final Calculator p_calculator)
{
double l_d;
l_d = this.m_expression.compute(p_calculator);
p_calculator.set_variable(this.m_variable, l_d);
return l_d;
}
/**
* Check if another object is equal to this one.
* @param p_o The object to check.
* @return <code>true</code> if and only if <code>p_o</code> is exactly
* the same object than this one.
*/
@Override
public final boolean equals (final Object p_o)
{
Formula l_f;
if(p_o == this) return true;
if(p_o instanceof Formula)
{
l_f = ((Formula)p_o);
return ((l_f.m_expression.equals(this.m_expression)) &&
(l_f.m_variable == this.m_variable));
}
return false;
}
/**
* Get a string that can be copy-pasted into a java file an that creates
* this construct.
* @param p_b The string builder to add with.
*/
@Override
public final void to_creation_string (final StringBuilder p_b)
{
p_b.append("new Formula(");
this.m_expression.to_creation_string(p_b);
p_b.append(", ");
p_b.append(this.m_variable);
p_b.append(')');
}
/**
* Replace a variable in all sub expressions of this formula.
* @param p_old_var The old variable to be replaced.
* @param p_new_var The new replacement.
* @return This formula, where all occurences of
* <code>p_old_var</code> have been replaced by
* <code>p_new_var</code>.
*/
public Formula replace_var(final int p_old_var,
final int p_new_var)
{
Expression e;
int t;
e = this.m_expression.get_handler().replace_var(this.m_expression,
p_old_var, p_new_var);
t = this.m_variable;
if(t == p_old_var) t = p_new_var;
if((t == this.m_variable) && (e == this.m_expression)) return this;
return new Formula(e, t);
}
/**
* Check how the specified variable is used.
* @param p_index The index of the variable.
* @return An or-combination of <code>1</code> if the variable is read and
* <code>2</code> if it is written to.
*/
@Override
public final int get_variable_usage (final int p_index)
{
return (((this.m_variable == p_index) ? 2 : 0) |
this.m_expression.get_variable_usage(p_index));
}
/**
* Obtain the depth of the construct.
* @return The depth of the construct.
*/
@Override
public int get_depth ()
{
return this.m_expression.get_depth();
}
}