DiscreteDomain.java
/* Copyright 2015 Laurent COCAULT
* Licensed to Laurent COCAULT under one or more contributor license agreements.
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership. Laurent COCAULT licenses this file to You
* under the Apache License, Version 2.0 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.csp.constraint.model;
import java.util.Iterator;
import java.util.TreeSet;
/**
* Represents a domain as a set of values.
*/
public class DiscreteDomain<T extends Value<T>> implements Domain<T> {
/**
* Values of the domain.
*/
private TreeSet<T> values_;
/**
* Default constructor.
*/
public DiscreteDomain() {
values_ = new TreeSet<T>();
}
/**
* Add a value to the domain.
* @param value
* Value to add
*/
public void addValue(final T value) {
values_.add(value);
}
/**
* {@inheritDoc}
*/
@Override
public boolean contains(final Value<T> value) {
return values_.contains(value);
}
/**
* {@inheritDoc}
*/
@Override
public Domain<T> copy() {
final DiscreteDomain<T> copy = new DiscreteDomain<T>();
copy.values_ = new TreeSet<T>(values_);
return copy;
}
/**
* {@inheritDoc}
*/
@Override
public Value<T> getFirstValue() throws EmptyDomainException {
if (values_.isEmpty()) {
throw new EmptyDomainException();
}
return values_.first();
}
/**
* {@inheritDoc}
*/
@Override
public int getSize() {
return values_.size();
}
/**
* {@inheritDoc}
*/
@Override
public Value<T> getValue() throws UnboundDomainException {
if (!hasSingleValue()) {
throw new UnboundDomainException();
}
return getFirstValue();
}
/**
* {@inheritDoc}
*/
@Override
public boolean hasSingleValue() {
return values_.size() == 1;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isEmpty() {
return values_.isEmpty();
}
/**
* {@inheritDoc}
*/
@Override
public boolean isInDomain(final Value<T> value) {
return values_.contains(value);
}
/**
* {@inheritDoc}
*/
@Override
public Iterator<T> iterator() {
return values_.iterator();
}
/**
* {@inheritDoc}
*/
@Override
public boolean reduceToDomainIntersection(final Domain<T> other) {
boolean domainChanged = false;
final Iterator<T> values = values_.iterator();
// Run through the possible values of the domain and check if it also in
// the other domain. If a value is not found in the other domain it is
// removed.
while (values.hasNext()) {
final Value<T> value = values.next();
if (!other.isInDomain(value)) {
// The value is not in the other domain, remove it
values.remove();
domainChanged = true;
}
}
return domainChanged;
}
/**
* {@inheritDoc}
*/
@Override
public boolean removeValue(final Value<T> value) {
return values_.remove(value);
}
/**
* {@inheritDoc}
*/
@Override
public boolean setValue(final Value<T> value) {
final boolean domainChanged = !(hasSingleValue() && isInDomain(value));
if (domainChanged) {
// The domain is reduced to only one value
values_.clear();
values_.add(value.value());
}
return domainChanged;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return values_.toString();
}
}