/******************************************************************************* * Copyright 2014 Felipe Takiyama * * Licensed 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 br.usp.poli.takiyama.prv; import br.usp.poli.takiyama.common.Constraint; import br.usp.poli.takiyama.common.InequalityConstraint; /** * A binding is an ordered pair of terms (t1, t2). The first term (t1) must be a * {@link LogicalVariable} and the second term (t2) may be a {@link Constant} * or another {@link LogicalVariable}. * We say that t2 replaces t1. * * @author Felipe Takiyama * */ public class Binding { private final LogicalVariable firstTerm; private final Term secondTerm; /* ************************************************************************ * Constructors * ************************************************************************/ /** * Creates a binding composed by the specified terms. * * @param t1 The logical variable being replaced * @param t2 The replacement */ private Binding(LogicalVariable t1, Term t2) { firstTerm = t1; secondTerm = t2; } /* ************************************************************************ * Static factories * ************************************************************************/ /** * Returns a binding with the specified terms. * * @param t1 The logical variable being replaced * @param t2 The replacement * @return The binding t1/t2 */ public static Binding getInstance(LogicalVariable t1, Term t2) { return new Binding(t1, t2); } /* ************************************************************************ * Getters * ************************************************************************/ /** * Returns the first term of this binding. * @return The first term of this binding. */ public LogicalVariable firstTerm() { return firstTerm; } /** * Returns the second term of this binding. * @return The second term of this binding. */ public Term secondTerm() { return secondTerm; } /** * Returns <code>true</code> if this binding contains the specified term. * * @param t The term to search for. * @return <code>true</code> if this binding contains the specified term, * <code>false</code> otherwise. */ public boolean contains(Term t) { return t.equals(firstTerm) || t.equals(secondTerm); } /** * Returns <code>true</code> if: * <li> The second term is a {@link Constant} and it belongs to first * term's population <b>or</b> * <li> The second term is a {@link LogicalVariable} and both terms have * the same population * * @return <code>true</code> if second term is in first term's population * or if second term and first term have the same population, * <code>false</code> otherwise. */ public boolean isValid() { boolean isValid = false; if (secondTerm.isConstant()) { Constant c = (Constant) secondTerm; isValid = firstTerm.population().contains(c); } else { LogicalVariable lv = (LogicalVariable) secondTerm; isValid = firstTerm.population().equals(lv.population()); } return isValid; } /** * Returns this binding converted to {@link InequalityConstraint}. * * @return This binding converted to inequality constraint */ public Constraint toInequalityConstraint() { return InequalityConstraint.getInstance(firstTerm, secondTerm); } /* ************************************************************************ * hashCode, equals and toString * ************************************************************************/ @Override public boolean equals(Object other) { // Tests if both refer to the same object if (this == other) return true; // Tests if the Object is an instance of this class if (!(other instanceof Binding)) return false; // Tests if both have the same attributes Binding targetObject = (Binding) other; return (this.firstTerm == null) ? (targetObject.firstTerm == null) : (this.firstTerm.equals(targetObject.firstTerm)) && (this.secondTerm == null) ? (targetObject.secondTerm == null) : (this.secondTerm.equals(targetObject.secondTerm)); } @Override public int hashCode() { // Algorithm extracted from Bloch,J. Effective Java int result = 17; result = 31 + result + firstTerm.hashCode(); result = 31 + result + secondTerm.hashCode(); return result; } @Override public String toString() { return firstTerm.toString() + "/" + secondTerm.toString(); } }