CrossEqual.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.general;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import org.csp.constraint.model.UnsizedConstraint;
- import org.csp.constraint.model.Value;
- import org.csp.constraint.model.Variable;
- /**
- * Constraint specifying that associate variables from two different lists. When
- * the a variable of one list has the expected value, the variable of the same
- * index of the other list has the other expected value. Example : let's have
- * two array of variables (A, B, C) and (D, E, F). The constraint can specify
- * that when a variable of the first array has a value V1, the corresponding
- * variable of the second array has a value V2. Suppose that during a
- * propagation B take V1 as a value. Then the constraint will value E=V2.
- */
- public class CrossEqual<T> extends UnsizedConstraint<T> {
- /** Left array. */
- private List<Variable<T>> left_;
- /** Left value. */
- private Value<T> leftValue_;
- /** Right array. */
- private List<Variable<T>> right_;
- /** Right value. */
- private Value<T> rightValue_;
- /**
- * Constructor.
- * @param leftArray
- * First array
- * @param leftValue
- * Expected value for the first array
- * @param rightArray
- * Second array
- * @param rightValue
- * Expected value for the second array
- */
- public CrossEqual(final List<Variable<T>> leftArray,
- final Value<T> leftValue, final List<Variable<T>> rightArray,
- final Value<T> rightValue) {
- super("CROSS_EQUAL", new ArrayList<Variable<T>>());
- // Initialize attributes
- left_ = leftArray;
- leftValue_ = leftValue;
- right_ = rightArray;
- rightValue_ = rightValue;
- // Both vector variables are implied in the constraint
- addVariables(leftArray);
- addVariables(rightArray);
- }
- /**
- * {@inheritDoc}
- */
- @Override
- public void propagate() {
- // Propagate in both ways
- propagate(left_, leftValue_, right_, rightValue_);
- propagate(right_, rightValue_, left_, leftValue_);
- }
- /**
- * Propagate constraint in one way : check "from" variables and deduce
- * possible values for "to" variables.
- * @param from
- * List of variables at the origin of the propagation
- * @param fromValue
- * Value at the origin of the propagation
- * @param to
- * List of variables to update
- * @param toValue
- * Value associated to the fromValue
- */
- protected void propagate(final List<Variable<T>> from,
- final Value<T> fromValue, final List<Variable<T>> to,
- final Value<T> toValue) {
- // Iterate with the index to find the corresponding variable in "to"
- for (int index = 0; index < from.size(); index++) {
- // Get the "from" variable
- final Variable<T> var = from.get(index);
- if (var.isBound() && var.getValue().equals(fromValue)) {
- // When the "from" variable is bound with the expected value,
- // the corresponding "to" variable should also be bound.
- if (to.get(index).setValue(toValue)) {
- addRecentChangedVariable(to.get(index));
- }
- } else if (!var.contains(fromValue)) {
- // When the expected value is no more in the "from" variable
- // domain, the corresponding "to" value must not be in the
- // domain of the "to" variable.
- if (to.get(index).removeValue(toValue)) {
- addRecentChangedVariable(to.get(index));
- }
- }
- }
- }
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- // String builder
- final StringBuilder builder = new StringBuilder();
- // Display the constraint
- builder.append("CROSS_EQUAL(" + leftValue_ + " in (");
- Iterator<Variable<T>> vars = left_.iterator();
- while (vars.hasNext()) {
- // Display every variable
- builder.append(vars.next().getName());
- if (vars.hasNext()) {
- // Next variable
- builder.append(", ");
- } else {
- // Last variable
- builder.append(") equals " + rightValue_ + " in (");
- }
- }
- vars = right_.iterator();
- while (vars.hasNext()) {
- // Display every variable
- builder.append(vars.next().getName());
- if (vars.hasNext()) {
- // Next variable
- builder.append(", ");
- } else {
- // Last variable
- builder.append("))");
- }
- }
- return builder.toString();
- }
- }