3 // Cassowary Incremental Constraint Solver
4 // Original Smalltalk Implementation by Alan Borning
5 // This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
6 // http://www.cs.washington.edu/homes/gjb
7 // (C) 1998, 1999 Greg J. Badros and Alan Borning
8 // See ../LICENSE for legal details regarding this software
17 #if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
18 #include <cassowary/config-inline.h>
19 #define CONFIG_INLINE_H_INCLUDED
22 #include "Cassowary.h"
23 #include "ClLinearExpression.h"
24 #include "ClVariable.h"
25 #include "ClTypedefs.h"
31 ostream &operator<<(ostream &xo, const ClTableau &clt);
33 ostream &operator<<(ostream &xo, const ClVarSet &varset);
35 ostream &operator<<(ostream &xo, const ClTableauColumnsMap &varmap);
37 ostream &operator<<(ostream &xo, const ClTableauRowsMap &rows);
39 ostream &operator<<(ostream &xo, const ClVarVector &varlist);
45 // No public constructor, since this does nothing but support
46 // an ADT for the ClSimplexSolver
48 // Variable v has been removed from an Expression. If the
49 // Expression is in a tableau the corresponding basic variable is
50 // subject (or if subject is nil then it's in the objective function).
51 // Update the column cross-indices.
52 void NoteRemovedVariable(ClVariable v, ClVariable subject)
55 Tracer TRACER(__FUNCTION__);
56 std::cerr << "(" << v << ", " << subject << ")" << std::endl;
58 ClVarSet &column = _columns[v];
59 ClVarSet::const_iterator it = column.find(subject);
60 assert(it != column.end());
62 #ifdef CL_TRACE_VERBOSE
63 std::cerr << "v = " << v << " and Columns[v].size() = "
64 << column.size() << std::endl;
66 if (column.size() == 0)
69 _externalRows.erase(v);
70 _externalParametricVars.erase(v);
74 // v has been added to the linear Expression for subject
75 // update column cross indices
76 void NoteAddedVariable(ClVariable v, ClVariable subject)
79 Tracer TRACER(__FUNCTION__);
80 std::cerr << "(" << v << ", " << subject << ")" << std::endl;
82 _columns[v].insert(subject);
83 if (v.IsExternal() && !FIsBasicVar(v))
85 _externalParametricVars.insert(v);
90 std::ostream &PrintOn(ostream &xo) const;
92 ostream &PrintInternalInfo(ostream &xo) const;
94 ostream &printExternalVariablesTo(ostream &xo) const;
98 // Check integrity of the tableau
99 // not complete, yet, but a start, at least
100 // Guard calls to AssertValid with CL_SOLVER_CHECK_INTEGRITY,
101 // since this is expensive
102 virtual void AssertValid() const {
104 // all external basic variables are in _externalRows
105 // and all external parametric variables are in _externalParametricVars
106 ClTableauRowsMap::const_iterator itRow = _rows.begin();
107 for (; itRow != _rows.end(); ++itRow)
109 const ClVariable clv = (*itRow).first;
110 if (clv.IsExternal())
112 if (_externalRows.find(clv) == _externalRows.end())
115 std::cerr << "External basic variable " << clv
116 << " is not in _externalRows" << std::endl;
120 const ClLinearExpression *pcle = RowExpression(clv);
122 ClVarToNumberMap::const_iterator it = pcle->Terms().begin();
123 for (; it != pcle->Terms().end(); ++it)
125 ClVariable clv = (*it).first;
126 if (clv.IsExternal())
128 if (_externalParametricVars.find(clv) == _externalParametricVars.end())
131 std::cerr << "External parametric variable " << clv
132 << " is not in _externalParametricVars" << std::endl;
143 // Constructor -- want to start with empty objects so not much to do
147 virtual ~ClTableau();
149 // Add v=expr to the tableau, update column cross indices
150 // v becomes a basic variable
151 // expr is now owned by ClTableau class,
152 // and ClTableauis responsible for deleting it
153 // (also, expr better be allocated on the heap!)
154 void addRow(ClVariable v, const ClLinearExpression &expr);
156 // Remove v from the tableau -- remove the column cross indices for v
157 // and remove v from every Expression in rows in which v occurs
158 // returns a pointer to the variable (since we often want to delete
160 ClVariable RemoveColumn(ClVariable v);
162 // Remove the basic variable v from the tableau row v=expr
163 // Then update column cross indices
164 // Probably want to call delete on the ClLinearExpression * returned
165 // unless you're adding that same Expression back into the
167 ClLinearExpression *RemoveRow(ClVariable v);
169 // Replace all occurrences of oldVar with expr, and update column cross indices
170 // oldVar should now be a basic variable
171 void SubstituteOut(ClVariable oldVar, const ClLinearExpression &expr);
173 ClTableauColumnsMap Columns()
176 ClTableauRowsMap Rows()
179 // return true iff the variable subject is in the Columns keys
180 bool ColumnsHasKey(ClVariable subject) const
182 ClTableauColumnsMap::const_iterator i = _columns.find(subject);
183 return (i != _columns.end());
186 const ClLinearExpression *RowExpression(ClVariable v) const
188 ClTableauRowsMap::const_iterator i = _rows.find(v);
189 if (i != _rows.end())
195 ClLinearExpression *RowExpression(ClVariable v)
197 const ClTableau *pthis = const_cast<const ClTableau *>(this);
198 return const_cast<ClLinearExpression *>(pthis->RowExpression(v));
202 bool FIsBasicVar(ClVariable v)
203 { return RowExpression(v) != 0; }
205 // private: FIXGJB: can I improve the encapsulation?
207 // _columns is a mapping from variables which occur in expressions to the
208 // set of basic variables whose expressions contain them
209 // i.e., it's a mapping from variables in expressions (a column) to the
210 // set of rows that contain them
211 ClTableauColumnsMap _columns;
213 // _rows maps basic variables to the expressions for that row in the tableau
214 ClTableauRowsMap _rows;
216 // the collection of basic variables that have infeasible rows
217 // (used when reoptimizing)
218 ClVarSet _infeasibleRows;
220 // the set of rows where the basic variable is external
221 // this was added to the C++ version to reduce time in SetExternalVariables()
222 ClVarSet _externalRows;
224 // the set of external variables which are parametric
225 // this was added to the C++ version to reduce time in SetExternalVariables()
226 ClVarSet _externalParametricVars;