All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.exigen.ie.constrainer.impl.IntExpImpl Maven / Gradle / Ivy

package com.exigen.ie.constrainer.impl;
import java.util.Map;

import com.exigen.ie.constrainer.Constrainer;
import com.exigen.ie.constrainer.Constraint;
import com.exigen.ie.constrainer.Failure;
import com.exigen.ie.constrainer.FloatExp;
import com.exigen.ie.constrainer.IntBoolExp;
import com.exigen.ie.constrainer.IntExp;
import com.exigen.ie.constrainer.IntExpConst;
import com.exigen.ie.constrainer.NonLinearExpression;
///////////////////////////////////////////////////////////////////////////////
/*
 * Copyright Exigen Group 1998, 1999, 2000
 * 320 Amboy Ave., Metuchen, NJ, 08840, USA, www.exigengroup.com
 *
 * The copyright to the computer program(s) herein
 * is the property of Exigen Group, USA. All rights reserved.
 * The program(s) may be used and/or copied only with
 * the written permission of Exigen Group
 * or in accordance with the terms and conditions
 * stipulated in the agreement/contract under which
 * the program(s) have been supplied.
 */
///////////////////////////////////////////////////////////////////////////////

/**
 * A generic implementation of the IntExp interface.
 */
public abstract class IntExpImpl extends ExpressionImpl implements IntExp
{
  public IntExpImpl(Constrainer constrainer)
  {
    this(constrainer,"");
  }

  public IntExpImpl(Constrainer constrainer, String name)
  {
    super(constrainer,name);
  }

  public FloatExp asFloat()
  {
//    return new FloatExpIntExp(this);
    return getFloatExp(FloatExpIntExp.class, this);
  }

  public IntExp add(IntExp exp)
  {
//    return new IntExpAddExp(this,exp);
    return getIntExp(IntExpAddExp.class, this, exp);
  }

  public IntExp add(int value)
  {
//    return new IntExpAddValue(this,value);
    return getIntExp(IntExpAddValue.class, this, value);
  }

  public FloatExp add(FloatExp exp)
  {
//    return new FloatExpAddExp(this.asFloat(),exp);
    return getFloatExp(FloatExpAddExp.class, this.asFloat(), exp);
  }

  public FloatExp add(double value)
  {
    return asFloat().add(value);
  }


  public IntExp abs()
  {
    if (min() >= 0)
      return this;

    if(max() <= 0)
      return neg();

//    return new IntExpAbs(this);
    return getIntExp(IntExpAbs.class, this);
  }

  public IntExp neg()
  {
//    return new IntExpOpposite(this);
    return getIntExp(IntExpOpposite.class, this);
  }

  public boolean bound()
  {
    return min() == max();
  }

  public int value() throws Failure
  {
    int min = min();

    if (min != max())
      _constrainer.fail("Attempt to get value of an unbound expression"+this);

    return min;
  }

  public boolean contains(int value) // better to be redefined in subclasses
  {
    return (value >= min() && value <= max());
  }

  public int size() // better to be redefined in subclasses
  {
    return max() - min() + 1;
  }

  public Constraint equals(int value) // this == value
  {
    return new ConstraintExpEqualsValue(this,value);
  }

  public Constraint equals(IntExp exp) // this == exp
  {
    return new ConstraintExpEqualsExp(this,exp);
  }

  public Constraint equals(FloatExp exp)
  {
    return exp.equals(this);
  }

  public Constraint equals(IntExp exp, int value) // this == exp + value
  {
    return new ConstraintExpEqualsExp(this,exp,value);
  }

  public Constraint equals(FloatExp exp, double value)
  {
    return exp.equals(this,value);
  }

  public Constraint less(int value)
  {
    return new ConstraintExpLessValue(this,value);
  }

  public Constraint less(IntExp exp)
  {
    return new ConstraintExpLessExp(this,exp,1);
  }

  public Constraint lessOrEqual(int value)
  {
    return less(value+1);
  }

  public Constraint lessOrEqual(IntExp exp)
  {
    return new ConstraintExpLessExp(this,exp,0);
  }

  public Constraint lessOrEqual(FloatExp exp)
  {
    return exp.moreOrEqual(this);
  }

  public Constraint more(int value)
  {
    return new ConstraintExpMoreValue(this,value);
  }

  public Constraint more(IntExp exp)
  {
    return new ConstraintExpLessExp(exp,this,1);
  }

  public Constraint moreOrEqual(int value)
  {
    return more(value-1);
  }

  public Constraint moreOrEqual(IntExp exp)
  {
    return new ConstraintExpLessExp(exp,this,0);
  }

  public Constraint moreOrEqual(FloatExp exp)
  {
    return exp.lessOrEqual(this);
  }

  public IntExp mul(int c)
  {
    //Debug.print("Create " + this + " * " + Integer.toString(c));
    if ( c == 1 )
      return this;

    if ( c > 0 )
//      return new IntExpMultiplyPositive(this,c);
      return getIntExp(IntExpMultiplyPositive.class, this, c);

    if ( c == 0 )
//      return new IntExpConst(constrainer(),0);
      return getIntExp(IntExpConst.class, 0);

//    if ( c < 0 )
      return neg().mul(-c);
  }

  public IntExp mul(IntExp exp)
  {
    if (exp.bound())
      return mul(exp.max());

    if(exp == this)
      return sqr();

    return mul_1(exp);
  }

  IntExp mul_1(IntExp exp)
  {
//    return new IntExpMulExp(this,exp);
    return getIntExp(IntExpMulExp.class, this, exp);
  }

/*
  IntExp mul_2(IntExp exp)
  {
    if (exp.min() >= 0)
      return mulPositive(exp);

    if (exp.max() <= 0)
      return mulNegative(exp);

    int c = -exp.min();

    return mulPositive(exp.add(c)).add(this.mul(-c));
  }

  IntExp mulPositive(IntExp exp)
  {

    if (this.min() >= 0)
//      return new IntExpMulExpPP(this,exp);
      return getIntExp(IntExpMulExpPP.class, this, exp);

     if (this.max() <= 0)
//      return (new IntExpMulExpPP(neg(),exp)).neg();
      return getIntExp(IntExpMulExpPP.class, neg(), exp).neg();

     int c = - min();

//     return new IntExpMulExpPP(add(c),exp).add(exp.mul(-c));
     return getIntExp(IntExpMulExpPP.class, add(c), exp).add(exp.mul(-c));
  }

  IntExp mulNegative(IntExp exp)
  {
    return mulPositive(exp.neg()).neg();
  }

*/

  public IntExp div (IntExp divisor) throws Failure
  {
    divisor.removeValue (0);
    if (divisor == this) {
      return new IntExpConst (this.constrainer (), 1);
    }
    if (divisor.bound ()) {
      int value;
      try {
        value = divisor.value ();
      } catch (Exception e) {
        value = 0;
      }
      return this.div (value);
    }

    return getIntExp(IntExpDivExp.class, this, divisor);
  }

  public FloatExp mul(FloatExp exp)
  {
    return exp.mul(this);
  }

  public FloatExp mul(double c)
  {
    return this.asFloat().mul(c);
  }


  /** changed by SV 02.13.03
   *  to fixed invalid behaviour
   */
  public IntExp div (int c) {
    if (c == 0) {
      throw new IllegalArgumentException("div(IntExp exp, int value): value == 0");
    } else if (c == 1) {
      return this;
    } else if (c == -1) {
      return this.neg ();
    } else {
      return getIntExp (IntExpDivValue.class, this, c);
    }
  }
  public FloatExp div(double c)
  {
    return this.asFloat().div(c);
  }

  public IntExp sqr()
  {
//    return new IntExpSqr(this);
    return getIntExp(IntExpSqr.class, this);
  }

  public IntExp sub(int value)
  {
    return add(-value);
  }


  public FloatExp sub(double value)
  {
    return add(-value);
  }

  public IntExp sub(IntExp exp)
  {
    return add(exp.neg());
  }

  public FloatExp sub(FloatExp exp)
  {
    return add(exp.neg());
  }

  /**
   * Returns a String representation of this object.
   * @return a String representation of this object.
   */
  public String toString()
  {
    return name() + domainToString();
  }

  static public String domainToString(int min, int max)
  {
    return min == max ? "["+min+"]" : "["+min+".."+max+"]";
  }

  public String domainToString()
  {
    return domainToString(min(), max());
  }

  public void setValue(int value) throws Failure
  {
    setMin(value);
    setMax(value);
  }

  public void removeValue(int value) throws Failure
  {
    int min, max;
    if (value == (min = min()))
    {
      setMin(min + 1);
    }
    else if (value ==(max = max()))
    {
      setMax(max - 1);
    }
    else
    {
      removeValueInternal(value);
    }

  }

  protected void removeValueInternal(int value) throws Failure {}

  public void removeRange(int min, int max) throws Failure
  {
/* commented by SV 02.06.03 by SV due to domain improvements
    if(min > max)
      throw new IllegalArgumentException("removeRange: min > max");

    if(min <= min())
    {
      setMin(max + 1);
    }
    else if(max >= max())
    {
      setMax(min - 1);
    }
    else // min() < min <= max < max()
    {
      removeRangeInternal(min,max);
    }
*/
    removeRangeInternal(min,max); // added by SV 02.06.03 by SV due to domain improvements
  }

  protected void removeRangeInternal(int min, int max) throws Failure {}


  // Only variables should implement propagation.
  public void propagate() throws Failure
  {
  }
/*
  public final IntEventBool createIntEventBool(boolean b)
  {
    IntEventBool e = (IntEventBool)_constrainer._int_event_bool_factory.getElement();
    e.exp(this);
    e.init(b);
    return e;
  }
*/

/*
  public final IntEventAddExp createIntEventAddExp(IntEvent e, IntExp second)
  {
    IntEventAddExp exp = (IntEventAddExp)_constrainer._int_event_add_exp_factory.getElement();
    exp.exp(this);
    exp.init(e, second);
    return exp;
  }

  public final IntEventAddValue createIntEventAddValue(IntEvent e, int value)
  {
    IntEventAddValue exp = (IntEventAddValue)_constrainer._int_event_add_value_factory.getElement();
    exp.exp(this);
    exp.init(e, value);
    return exp;
  }

  public final IntEventMulPositiveValue createIntEventMulPositiveValue(IntEvent e, int value)
  {
    IntEventMulPositiveValue exp = (IntEventMulPositiveValue)_constrainer._int_event_mul_positive_value_factory.getElement();
    exp.exp(this);
    exp.init(e, value);
    return exp;
  }


  public final IntEventOpposite createIntEventOpposite(IntEvent e)
  {
    IntEventOpposite exp = (IntEventOpposite)_constrainer._int_event_opposite_factory.getElement();
    exp.exp(this);
    exp.init(e);
    return exp;
  }

  public final IntEventDomain createIntEventDomain(IntDomainHistory hist)
  {
    IntEventDomain exp = (IntEventDomain)_constrainer._int_event_domain_factory.getElement();
    exp.exp(this);
    exp.init(hist);
    return exp;
  }

*/

  public boolean valid()
  {
    return min() <= max();
  }

  public void iterateDomain(IntExp.IntDomainIterator it) throws Failure
  {
    for(int i = min() ; i <= max(); ++i)
    {
      if (contains(i))
      {
        boolean res = it.doSomethingOrStop(i);
        if (!res)
          return;
      }
    }
  }

  public IntExp rangeViolation(int rangeMin, int rangeMax)
  {
//    // An implementation as expression.
//    // ((this < rangeMin)*(rangeMin - this) + (this > rangeMax)*(this - rangeMax)).
//    IntExp v1 = lt(rangeMin).mul(sub(rangeMin).neg());
//    IntExp v2 = gt(rangeMax).mul(sub(rangeMax));
//    return v1.add(v2);

//    return new IntExpRangeViolation(this,rangeMin,rangeMax);
    return (IntExp)getExpression( IntExpRangeViolation.class,
                  new Object[]{this, new Integer(rangeMin), new Integer(rangeMax)} );
    }

  public IntBoolExp eq(IntExp exp)
  {
//    return new IntBoolExpEqExp(this, exp);
    return getIntBoolExp(IntBoolExpEqExp.class, this, exp);
  }

  public IntBoolExp eq(int value)
  {
//    return new IntBoolExpEqValue(this, value);
    return getIntBoolExp(IntBoolExpEqValue.class, this, value);
  }

  public IntBoolExp eq(double value)
  {
    return asFloat().eq(value);
  }

  public IntBoolExp ne(IntExp exp)
  {
//    return (new IntBoolExpEqExp(this, exp)).not();
    return getIntBoolExp(IntBoolExpEqExp.class, this, exp).not();
  }

  public IntBoolExp ne(int value)
  {
//    return ne(new IntExpConst(_constrainer, value));
    return ne( getIntExp(IntExpConst.class, value) );
  }

  public IntBoolExp ne(double value)
  {
    return asFloat().ne(value);
  }

  public IntBoolExp lt(IntExp exp)
  {
//    return new IntBoolExpLessExp(this,exp);
    return getIntBoolExp(IntBoolExpLessExp.class, this, exp);
  }

  public IntBoolExp lt(int value)
  {
//    return lt(new IntExpConst(_constrainer, value));
    return lt( getIntExp(IntExpConst.class, value) );
  }

  public IntBoolExp lt(double value)
  {
    return asFloat().lt(value);
  }

  public IntBoolExp gt(IntExp exp)
  {
//    return new IntBoolExpLessExp(exp, this);
    return getIntBoolExp(IntBoolExpLessExp.class, exp, this);
  }

  public IntBoolExp gt(int value)
  {
//    return gt(new IntExpConst(_constrainer, value));
    return gt( getIntExp(IntExpConst.class, value) );
  }

  public IntBoolExp gt(double value)
  {
    return asFloat().gt(value);
  }


  public IntBoolExp le(IntExp exp)
  {
//    return new IntBoolExpLessExp(this,exp,1);
    return getIntBoolExp(IntBoolExpLessExp.class, this, exp, 1);
//    return lt(exp.add(1));
  }

  public IntBoolExp le(int value)
  {
    return lt(value + 1);
  }

  public IntBoolExp le(double value)
  {
    return asFloat().le(value);
  }

  public IntBoolExp ge(IntExp exp)
  {
//    return new IntBoolExpLessExp(exp, this, 1);
    return getIntBoolExp(IntBoolExpLessExp.class, exp, this, 1);
//    return gt(exp.sub(1));
  }

  public IntBoolExp ge(int value)
  {
    return gt(value - 1);
  }

  public IntBoolExp ge(double value)
  {
    return asFloat().ge(value);
  }

  public IntExp mod(int c)
  {
    throw new UnsupportedOperationException("mod");
  }

  public FloatExp mod(double c)
  {
    throw new UnsupportedOperationException("mod");
  }

  public FloatExp pow(double value) throws Failure {
    return asFloat().pow(value);
  }

  public IntExp pow(int value)
  {
    switch(value)
    {
      case 0:
//        return new IntExpConst(constrainer(),1);
        return getIntExp(IntExpConst.class, 1);
      case 1:
        return this;
      case 2:
        return sqr();
      default:
        if(value > 0)
        {
//          return new IntExpPowIntValue(this,value);
          return getIntExp(IntExpPowIntValue.class, this, value);
        }
        else // if(value < 0)
        {
          throw new IllegalArgumentException("pow(IntExp exp, int value): value < 0");
        }
    }
  }
  public IntExp pow(IntExp pow_exp) throws Failure
  {
    if (pow_exp.max () < 0) {
      throw new IllegalArgumentException("pow(IntExp exp, IntExp pow_exp): pow_exp < 0");
    } else {
      pow_exp.setMin (0);
      return getIntExp(IntExpPowIntExp.class, this, pow_exp);
    }
  }

  public double calcCoeffs(Map map) throws NonLinearExpression{
    return calcCoeffs(map, 1);
  }

  public double calcCoeffs(Map map, double factor) throws NonLinearExpression
  {
    throw new NonLinearExpression(this);
  }

  public boolean isLinear(){
    return false;
  }
} // ~IntExpImpl




© 2015 - 2024 Weber Informatics LLC | Privacy Policy