DiscreteDomain.java

  1. /* Copyright 2015 Laurent COCAULT
  2.  * Licensed to Laurent COCAULT under one or more contributor license agreements.
  3.  * See the NOTICE file distributed with this work for additional information
  4.  * regarding copyright ownership. Laurent COCAULT licenses this file to You
  5.  * under the Apache License, Version 2.0 (the "License"); you may not use this
  6.  * file except in compliance with the License.  You may obtain a copy of the
  7.  * License at
  8.  *
  9.  *   http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.csp.constraint.model;

  18. import java.util.Iterator;
  19. import java.util.TreeSet;

  20. /**
  21.  * Represents a domain as a set of values.
  22.  */
  23. public class DiscreteDomain<T extends Value<T>> implements Domain<T> {

  24.     /**
  25.      * Values of the domain.
  26.      */
  27.     private TreeSet<T> values_;

  28.     /**
  29.      * Default constructor.
  30.      */
  31.     public DiscreteDomain() {
  32.         values_ = new TreeSet<T>();
  33.     }

  34.     /**
  35.      * Add a value to the domain.
  36.      * @param value
  37.      *            Value to add
  38.      */
  39.     public void addValue(final T value) {
  40.         values_.add(value);
  41.     }

  42.     /**
  43.      * {@inheritDoc}
  44.      */
  45.     @Override
  46.     public boolean contains(final Value<T> value) {
  47.         return values_.contains(value);
  48.     }

  49.     /**
  50.      * {@inheritDoc}
  51.      */
  52.     @Override
  53.     public Domain<T> copy() {
  54.         final DiscreteDomain<T> copy = new DiscreteDomain<T>();
  55.         copy.values_ = new TreeSet<T>(values_);
  56.         return copy;
  57.     }

  58.     /**
  59.      * {@inheritDoc}
  60.      */
  61.     @Override
  62.     public Value<T> getFirstValue() throws EmptyDomainException {
  63.         if (values_.isEmpty()) {
  64.             throw new EmptyDomainException();
  65.         }
  66.         return values_.first();
  67.     }

  68.     /**
  69.      * {@inheritDoc}
  70.      */
  71.     @Override
  72.     public int getSize() {
  73.         return values_.size();
  74.     }

  75.     /**
  76.      * {@inheritDoc}
  77.      */
  78.     @Override
  79.     public Value<T> getValue() throws UnboundDomainException {
  80.         if (!hasSingleValue()) {
  81.             throw new UnboundDomainException();
  82.         }
  83.         return getFirstValue();
  84.     }

  85.     /**
  86.      * {@inheritDoc}
  87.      */
  88.     @Override
  89.     public boolean hasSingleValue() {
  90.         return values_.size() == 1;
  91.     }

  92.     /**
  93.      * {@inheritDoc}
  94.      */
  95.     @Override
  96.     public boolean isEmpty() {
  97.         return values_.isEmpty();
  98.     }

  99.     /**
  100.      * {@inheritDoc}
  101.      */
  102.     @Override
  103.     public boolean isInDomain(final Value<T> value) {
  104.         return values_.contains(value);
  105.     }

  106.     /**
  107.      * {@inheritDoc}
  108.      */
  109.     @Override
  110.     public Iterator<T> iterator() {
  111.         return values_.iterator();
  112.     }

  113.     /**
  114.      * {@inheritDoc}
  115.      */
  116.     @Override
  117.     public boolean reduceToDomainIntersection(final Domain<T> other) {
  118.         boolean domainChanged = false;
  119.         final Iterator<T> values = values_.iterator();
  120.         // Run through the possible values of the domain and check if it also in
  121.         // the other domain. If a value is not found in the other domain it is
  122.         // removed.
  123.         while (values.hasNext()) {
  124.             final Value<T> value = values.next();
  125.             if (!other.isInDomain(value)) {
  126.                 // The value is not in the other domain, remove it
  127.                 values.remove();
  128.                 domainChanged = true;
  129.             }
  130.         }
  131.         return domainChanged;
  132.     }

  133.     /**
  134.      * {@inheritDoc}
  135.      */
  136.     @Override
  137.     public boolean removeValue(final Value<T> value) {
  138.         return values_.remove(value);
  139.     }

  140.     /**
  141.      * {@inheritDoc}
  142.      */
  143.     @Override
  144.     public boolean setValue(final Value<T> value) {
  145.         final boolean domainChanged = !(hasSingleValue() && isInDomain(value));
  146.         if (domainChanged) {
  147.             // The domain is reduced to only one value
  148.             values_.clear();
  149.             values_.add(value.value());
  150.         }
  151.         return domainChanged;
  152.     }

  153.     /**
  154.      * {@inheritDoc}
  155.      */
  156.     @Override
  157.     public String toString() {
  158.         return values_.toString();
  159.     }

  160. }