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

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

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

import com.exigen.ie.constrainer.EventOfInterest;
import com.exigen.ie.constrainer.Failure;
import com.exigen.ie.constrainer.IntExp;
import com.exigen.ie.constrainer.IntVar;
import com.exigen.ie.constrainer.NonLinearExpression;
import com.exigen.ie.constrainer.Observer;
import com.exigen.ie.constrainer.Subject;
import com.exigen.ie.tools.Reusable;
import com.exigen.ie.tools.ReusableFactory;
//
//: IntExpAddExp.java
//
/**
 * An implementation of the expression: (IntExp1 + IntExp2).
 */
public final class IntExpAddExp extends IntExpImpl
{
  private IntExp  _exp1;
  private IntExp  _exp2;
  private Observer _observer;

  private IntVar _sum;

  static final private int[] event_map = { MIN, MIN,
                                           MAX, MAX,
                                           MIN | MAX | VALUE, VALUE
                                         };

  class ExpAddExpObserver extends Observer
  {
      ExpAddExpObserver()
      {
        //super(event_map);
      }

    public void update(Subject exp, EventOfInterest event)
      throws Failure
    {
 //     IntEvent e = (IntEvent) event;

 //     int type = e.type();
 //     if ((type & MIN) != 0)
        _sum.setMin(calc_min());

 //     if ((type & MAX) != 0)
        _sum.setMax(calc_max());

    }


      public String toString()
      {
        return "ExpAddExpObserver: ";
      }

      public Object master()
      {
        return IntExpAddExp.this;
      }

  public int subscriberMask()
  {
    return MIN | MAX | VALUE;
  }


  } //~ ExpAddExpObserver


  public IntExpAddExp(IntExp exp1, IntExp exp2)
  {
    super(exp1.constrainer());

    if(constrainer().showInternalNames())
    {
      _name = "("+exp1.name()+"+"+exp2.name()+")";
    }

    _exp1 = exp1;
    _exp2 = exp2;

//    int trace = IntVarImplTrace.TRACE_ALL;
    int trace = 0;
    _sum = constrainer().addIntVarTraceInternal(calc_min(), calc_max(), _name, IntVar.DOMAIN_PLAIN, trace);

    _exp1.attachObserver(_observer = new ExpAddExpObserver());
    _exp2.attachObserver(_observer);
  }

  public void onMaskChange()
  {
//    _observer.publish(publisherMask(), _exp1);
//    _observer.publish(publisherMask(), _exp2);
  }


  public void attachObserver(Observer observer)
  {
    super.attachObserver(observer);
    _sum.attachObserver(observer);
  }

  public void reattachObserver(Observer observer)
  {
    super.reattachObserver(observer);
    _sum.reattachObserver(observer);
  }

  public void detachObserver(Observer observer)
  {
    super.detachObserver(observer);
    _sum.detachObserver(observer);
  }



  public int calc_max()
  {
    return _exp1.max()+_exp2.max();
  }

  public int calc_min()
  {
    return _exp1.min() + _exp2.min();
  }

  public int max()
  {
    return _sum.max();
  }

  public int min()
  {
    return _sum.min();
  }



  public void setMax(int max) throws Failure
  {
    if (max >= _sum.max())
      return;

    int max1 = max - _exp2.min();
    if (max1 < _exp1.max())
      _exp1.setMax(max1);
    int max2 = max - _exp1.min();
    if (max2 < _exp2.max())
      _exp2.setMax(max2);
  }

  public void setMin(int min) throws Failure
  {

    if (min <= _sum.min())
      return;

    int min1 = min - _exp2.max();
    if (min1 > _exp1.min())
      _exp1.setMin(min1);
    int min2 = min - _exp1.max();
    if (min2 > _exp2.min())
      _exp2.setMin(min2);
  }

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

  public void removeValue(int value) throws Failure
  {
    int Max = max();
    if (value > Max)
      return;
    int Min = min();
    if (value < Min)
      return;
    if (Min == Max)
      constrainer().fail("remove for IntExpAddExp");
    if (value == Max)
      setMax(value-1);
    if (value == Min)
      setMin(value+1);
  }

  public boolean isLinear(){
    return (_exp1.isLinear() && _exp2.isLinear());
  }

  public double calcCoeffs(Map map, double factor) throws NonLinearExpression{
    return (_exp1.calcCoeffs(map, factor) + _exp2.calcCoeffs(map, factor));
  }

  static final class IntEventAddExp extends IntEvent
  {

    static ReusableFactory _factory = new ReusableFactory()
    {
        protected Reusable createNewElement()
        {
          return new IntEventAddExp();
        }

    };

    static IntEventAddExp getEvent(IntEvent event, IntExp exp)
    {
      IntEventAddExp ev = (IntEventAddExp) _factory.getElement();
      ev.init(event, exp);
      return ev;
    }




    int _type;
    IntExp _second;
    IntEvent _event;

    public String name()
    {
      return "Event AddExp";
    }



    public void init(IntEvent e, IntExp second)
    {
      _event = e;
      _second = second;
      _type = e.type();
      if (!_second.bound())
        _type &= ~(REMOVE | VALUE);
    }

    public int type()
    {
      return _type;
    }



    public int removed(int i)
    {
      return _event.removed(i) + _second.min();
    }


    public int min()
    {
      return _event.min() + _second.min();
    }

    public int max()
    {
      return _event.max() + _second.max();
    }

    public int oldmin()
    {
      return _event.oldmin() + _second.min();
    }


    public int oldmax()
    {
      return _event.oldmax() + _second.max();
    }

    public int numberOfRemoves()
    {
      if ((_type & REMOVE) != 0)
        return _event.numberOfRemoves();
      return 0;
    }

  }

} // ~IntExpAddExp




© 2015 - 2024 Weber Informatics LLC | Privacy Policy