/* * Copyright 2007-2008, Christof Lutteroth, lutteroth@cs.auckland.ac.nz * Copyright 2007-2008, James Kim, jkim202@ec.auckland.ac.nz * Copyright 2010, Clemens Zeidler * Distributed under the terms of the MIT License. */ #include "Variable.h" #include #include "Constraint.h" #include "LinearSpec.h" // Toggle debug output //#define DEBUG_VARIABLE #ifdef DEBUG_VARIABLE # define STRACE(x) debug_printf x #else # define STRACE(x) ; #endif /** * Gets index of the variable. * * @return the index of the variable */ int32 Variable::Index() const { return fLS->IndexOf(this); } int32 Variable::GlobalIndex() const { return fLS->GlobalIndexOf(this); } /** * Gets the current linear specification. * * @return the current linear specification */ LinearSpec* Variable::LS() const { return fLS; } /** * Gets the value. * * @return the value */ double Variable::Value() const { return fValue; } /** * Sets the value. * * @param value the value */ void Variable::SetValue(double value) { fValue = value; } /** * Gets the minimum value of the variable. * * @return the minimum value of variable */ double Variable::Min() const { return fMin; } /** * Sets the minimum value of the variable. * * @param min minimum value */ void Variable::SetMin(double min) { SetRange(min, fMax); } /** * Gets the maximum value of the variable. * * @return the maximum value of variable */ double Variable::Max() const { return fMax; } /** * Sets the maximum value of the variable. * * @param max maximum value */ void Variable::SetMax(double max) { SetRange(fMin, max); } /** * Sets the minimum and maximum values of the variable. * * @param min minimum value * @param max maximum value */ void Variable::SetRange(double min, double max) { fMin = min; fMax = max; if (fIsValid) fLS->UpdateRange(this); } const char* Variable::Label() { return fLabel.String(); } void Variable::SetLabel(const char* label) { fLabel = label; } /** * Returns index of the variable as String. * E.g. "Var2" * * @return the String index of the variable */ BString Variable::ToString() const { BString string = "x"; string << Index() << " "; if (fLabel) { string << fLabel << ": "; if (!fIsValid) string << "(invalid)"; } else { if (!fIsValid) string << "(invalid," << (addr_t)this << ")"; else string << Index() << ": "; } string << Value(); BString pointerString; pointerString.SetToFormat("%p", this); string << " (" << pointerString << ")"; return string; } /** * Adds a constraint that sets this variable equal to the given one. * * @param var variable that should have the same value * @return the new equality constraint */ Constraint* Variable::IsEqual(Variable* var) { if (!fIsValid) return NULL; return fLS->AddConstraint(1.0, this, -1.0, var, kEQ, 0.0); } /** * Adds a constraint that sets this variable smaller or equal to the given one. * * @param var variable that should have a larger or equal value * @return the new constraint */ Constraint* Variable::IsSmallerOrEqual(Variable* var) { if (!fIsValid) return NULL; return fLS->AddConstraint(1.0, this, -1.0, var, kLE, 0.0); } /** * Adds a constraint that sets this variable greater or equal to the given one. * * @param var variable that should have a smaller or equal value * @return the new constraint */ Constraint* Variable::IsGreaterOrEqual(Variable* var) { if (!fIsValid) return NULL; return fLS->AddConstraint(-1.0, var, 1.0, this, kGE, 0.0); } Constraint* Variable::IsEqual(Variable* var, double penaltyNeg, double penaltyPos) { if (!fIsValid) return NULL; return fLS->AddConstraint(1.0, this, -1.0, var, kEQ, 0.0, penaltyNeg, penaltyPos); } Constraint* Variable::IsSmallerOrEqual(Variable* var, double penaltyNeg, double penaltyPos) { if (!fIsValid) return NULL; return fLS->AddConstraint(1.0, this, -1.0, var, kLE, 0.0, penaltyNeg, penaltyPos); } Constraint* Variable::IsGreaterOrEqual(Variable* var, double penaltyNeg, double penaltyPos) { if (!fIsValid) return NULL; return fLS->AddConstraint(-1.0, var, 1.0, this, kGE, 0.0, penaltyNeg, penaltyPos); } bool Variable::IsValid() { return fIsValid; } void Variable::Invalidate() { STRACE(("Variable::Invalidate() on %s\n", BString(*this).String())); if (!fIsValid) return; fIsValid = false; fLS->RemoveVariable(this, false); } /** * Constructor. */ Variable::Variable(LinearSpec* ls) : fLS(ls), fValue(NAN), fMin(-20000), fMax(20000), fLabel(NULL), fIsValid(false), fReferenceCount(0) { } int32 Variable::AddReference() { fReferenceCount++; return fReferenceCount; } int32 Variable::RemoveReference() { fReferenceCount--; return fReferenceCount; } /** * Destructor. * Removes the variable from its specification. */ Variable::~Variable() { if (fLS) fLS->RemoveVariable(this, false); }