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

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

package com.exigen.ie.constrainer.impl;
import com.exigen.ie.constrainer.Failure;
import com.exigen.ie.constrainer.IntVar;
import com.exigen.ie.tools.FastVector;

//
//: DomainImplWithHoles.java
//
/**
 * A implementation of the Domain interface that
 * supports a vector of intervals where each interval defines
 * the only possible values.
 * @see DomainInterval
 */
public final class DomainImplWithHoles extends DomainImpl
{
  private FastVector    _values; // vector of DomainUnterval(s), for example domain {0,1,2,5,6,9}
                             // contains 3 intervals [(0;2), (5;6), (9;9)]

  public DomainImplWithHoles(IntVar var, int min, int max) //throws Failure
  {
    super(var,min,max);
    _values = new FastVector();
    _values.addElement(new DomainInterval(min,max));
  }

  FastVector values()
  {
    return _values;
  }

  public boolean contains(int value)
  {
    if (value < _min || value > _max)
      return false;
    for(int i=0; i<_values.size(); i++)
    {
      DomainInterval interval = (DomainInterval)_values.elementAt(i);
      if (value >= interval.from && value <= interval.to)
        return true;
    }
    return false;
  }

  public int max()
  {
    //DomainInterval interval = (DomainInterval)_values.lastElement();
    //return interval.to;
    return _max;
  }

  public int min()
  {
    //DomainInterval interval = (DomainInterval)_values.firstElement();
    //return interval.from;
    return _min;
  }

  public void force(FastVector values) //throws Failure
  {
    _values = values;
    DomainInterval first = (DomainInterval)_values.firstElement();
    _min = first.from;
    DomainInterval last = (DomainInterval)_values.lastElement();
    _max = last.to;
  }

  public void forceMin(int min)
  {
    _min = min;
  }

  public void forceMax(int max)
  {
    _max = max;
  }

  public boolean removeValue(int value) throws Failure
  {
    if (value == _min)
      return setMin(value+1);
    if (value == _max)
      return setMax(value-1);

    //constrainer().addUndo(_variable);
    _variable.addUndo();

    for(int i=0; i<_values.size(); i++)
    {
      DomainInterval interval = (DomainInterval)_values.elementAt(i);
      if (value >= interval.from && value <= interval.to)
      {
        if (interval.from == interval.to)
        {
          if (_values.size()==1)
          {
            constrainer().fail("remove"); // "Empty domain of "+_variable
          }
          _values.removeElementAt(i);
        }
        else
        if (value == interval.from)
        {
          interval.from++;
        }
        else
        if (value == interval.to)
        {
          interval.to--;
        }
        else
        {
          int from1 = interval.from;
          int to1 = value-1;
          int from2 = value+1;
          int to2 = interval.to;
          interval.to = to1;
          _values.insertElementAt(new DomainInterval(from2,to2),i+1);
        }
        return true;
      }
    }
    return false; // not in domain - impossible
  }

  public boolean setMax(int M) throws Failure
  {
    if (M >= _max)
      return false;

    if (M < _min)
    {
      constrainer().fail("Max < Min for "+_variable);
    }

    //constrainer().addUndo(_variable);
    _variable.addUndo();

    // remove a hole
    while(!_values.isEmpty())
    {
      DomainInterval interval = (DomainInterval)_values.lastElement();
      if (M < interval.from)
      {
        _values.removeLast();
        continue;
      }

      if (M >= interval.to)
        break;

      // (M >= interval.from && M < interval.to)
      interval.to = M;
      break;
    }

    DomainInterval interval = (DomainInterval)_values.lastElement();
    _max = interval.to;

    return true;
  }

  public boolean setMin(int m) throws Failure
  {
    if (m <= min())
      return false;

    if (m > max())
    {
      constrainer().fail("Min > Max for "+_variable);
    }

    //constrainer().addUndo(_variable);
    _variable.addUndo();

    // remove hole
    while(!_values.isEmpty())
    {
      DomainInterval interval = (DomainInterval)_values.firstElement();
      if (m > interval.to)
      {
        _values.removeElementAt(0);
        continue;
      }

      if (m <= interval.from)
        break;

      // (m > interval.from && m <= interval.to)
      interval.from = m;
      break;
    }

    DomainInterval interval = (DomainInterval)_values.firstElement();
    _min = interval.from;
    return true;
  }

  public boolean setValue(int value) throws Failure
  {
    //Debug.print("setValue " + value);
    if (_min==value && _max==value)
    {
      //constrainer().fail("Redundant value "+_variable);
      return false;
    }

    if (!contains(value))
    {
      constrainer().fail("attempt to set invalid value for "+_variable);
    }

    //constrainer().addUndo(_variable);
    _variable.addUndo();

    _values.clear();
    _values.addElement(new DomainInterval(value,value));
    _min = value;
    _max = value;
    return true;
  }

  public int size()
  {
    int s = 0;
    for(int i=0; i<_values.size(); i++)
    {
      DomainInterval interval = (DomainInterval)_values.elementAt(i);
      s += (interval.to - interval.from +1);
    }
    return s;
  }

  public String toString()
  {
    //return "["+min()+((size()==1) ? "" : ";"+max())+"]"
    //        +((values().size()==1)?"":"-"+values().size()+"intervals");
    return _values.toString();
  }

} // end of DomainImplWithHoles




© 2015 - 2024 Weber Informatics LLC | Privacy Policy