private boolean _solve(boolean least) throws IllegalActionException {
// initialize all variables
Object init = least ? _cpo.bottom() : _cpo.top();
if (init == null) {
throw new InvalidStateException(
"The underlying CPO is not a lattice because "
+ "the CPO has no " + (least ? "bottom" : "top")
+ ". The CPO was a " + _cpo.getClass().getName());
}
for (Enumeration e = _Clist.keys(); e.hasMoreElements();) {
InequalityTerm variable = (InequalityTerm) e.nextElement();
try {
variable.initialize(init);
} catch (IllegalActionException ex) {
throw new InvalidStateException(null, null, ex,
"Cannot initialize variable.");
}
}
// initialize _NS(not satisfied) list; set _inCvar and _inserted flags.
// Not Satisfied list. Each entry is an Integer storing index to
// _Ilist.
// Note: removal in jdk1.2 LinkedList is not an O(1) operation, but
// an O(n) operation, where n is the number of elements in list.
// If the size of _NS is large, writing our own linked list class
// with a Cell class might be better.
LinkedList _NS = new LinkedList();
for (int i = 0; i < _Ilist.size(); i++) {
Info info = (Info) _Ilist.get(i);
info._inCvar = least ? info._ineq.getGreaterTerm().isSettable()
: info._ineq.getLesserTerm().isSettable();
if (info._inCvar) {
if (info._ineq.isSatisfied(_cpo)) {
info._inserted = false;
} else { // insert to _NS
_NS.addLast(Integer.valueOf(i));
info._inserted = true;
}
}
}
// The outer loop is for handling the situation that some
// InequalityTerms do not report all the variables they depend on
// from the getVariables() call. This can happen, for example, in
// type resolution application involving structured types, where
// the type term for an element of a structured type does not have
// a reference to the term of its enclosing type.
boolean allSatisfied = false;
while (!allSatisfied) {
// solve the inequalities
while (_NS.size() > 0) {
int index = ((Integer) (_NS.removeFirst())).intValue();
Info info = (Info) (_Ilist.get(index));
info._inserted = false;
Object value = null;
InequalityTerm updateTerm = null;
if (least) {
updateTerm = info._ineq.getGreaterTerm();
value = _cpo.leastUpperBound(info._ineq.getLesserTerm()
.getValue(), updateTerm.getValue());
} else {
updateTerm = info._ineq.getLesserTerm();
value = _cpo.greatestLowerBound(updateTerm.getValue(),
info._ineq.getGreaterTerm().getValue());
}
if (value == null) {
throw new InvalidStateException("The CPO over which "
+ "the inequalities are defined is not a lattice.");
}
try {
updateTerm.setValue(value);
} catch (IllegalActionException ex) {
throw new InvalidStateException(null, null, ex,
"Can't update variable.\n");
}
// insert or drop the inequalities affected
ArrayList affected = (ArrayList) _Clist.get(updateTerm);