SolveConstraints:
PUBLIC PROCEDURE [table: TableBase.RefTable] = {
Solve row constraints first
constraintSymTab ← SymTab.Create[101];
table.tableau ← LinearSolver.Init[];
IF table.rowConstraints #
NIL
THEN
EstablishConstraints[table, table.rowConstraints];
TableBase.EnumerateByRows[table, GenerateRowConstraints];
IF
NOT LinearSolver.Satisfiable[table.tableau]
THEN
ERROR TableBase.ImplementationError["Unsatisifiable row constraints"];
table.rowGridPositions ← NEW[TableBase.GridVector[table.rowGrids+1]];
FOR i: TableBase.GridNumber
IN [0..table.rowGrids]
DO
table.rowGridPositions.grid[i] ← TSTypes.Pt[LinearSolver.Solution[table.tableau, LookUpUnknown[table.tableau, Rope.Concat["gy", Convert.RopeFromInt[i]]]]];
ENDLOOP;
Determine the box positions
{
SetBoxY: TableBase.EnumeratedEntryProc ~ {
WITH entry
SELECT
FROM
box: TableBase.RefTableBox => {
boxNumber: ROPE ~ Convert.RopeFromInt[box.left*1000 + box.top];
box.y ← TSTypes.Pt[LinearSolver.Solution[table.tableau, LookUpUnknown[table.tableau, Rope.Concat["y", boxNumber]]]];
box.y ← box.y.SubDimn[box.yOffset];
};
ENDCASE;
};
TableBase.EnumerateByRows[table, SetBoxY];
};
Solve column constraints next
constraintSymTab ← SymTab.Create[101];
table.tableau ← LinearSolver.Init[];
IF table.colConstraints #
NIL
THEN
EstablishConstraints[table, table.colConstraints];
TableBase.EnumerateByRows[table, GenerateColumnConstraints];
IF
NOT LinearSolver.Satisfiable[table.tableau]
THEN
ERROR TableBase.ImplementationError["Unsatisifiable column constraints"];
table.colGridPositions ← NEW[TableBase.GridVector[table.columnGrids+1]];
FOR i: TableBase.GridNumber
IN [0..table.columnGrids]
DO
table.colGridPositions.grid[i] ← TSTypes.Pt[LinearSolver.Solution[table.tableau, LookUpUnknown[table.tableau, Rope.Concat["gx", Convert.RopeFromInt[i]]]]];
ENDLOOP;
Determine the box positions
{
SetBoxX: TableBase.EnumeratedEntryProc ~ {
WITH entry
SELECT
FROM
box: TableBase.RefTableBox => {
boxNumber: ROPE ~ Convert.RopeFromInt[box.left*1000 + box.top];
box.x ← TSTypes.Pt[LinearSolver.Solution[table.tableau, LookUpUnknown[table.tableau, Rope.Concat["x", boxNumber]]]];
box.x ← box.x.AddDimn[box.xOffset];
};
ENDCASE;
};
TableBase.EnumerateByRows[table, SetBoxX];
};
};
EstablishConstraints:
PROC [table: TableBase.RefTable, constraintList:
LIST
OF TableBase.RefConstraint] ~ {
FOR c:
LIST
OF TableBase.RefConstraint ← constraintList, c.rest
WHILE c #
NIL
DO
lsConstraint: LinearSolver.Constraint;
FOR l:
LIST
OF TableBase.Coefficient ← c.first.coefficients, l.rest
WHILE l #
NIL
DO
unknown: LinearSolver.Unknown ~ IF l.first.unknown.IsEmpty THEN table.tableau.unity ELSE LookUpUnknown[table.tableau, l.first.unknown];
lsConstraint ← CONS[NEW[LinearSolver.LinearMonomial ← [l.first.coefficient, unknown]], lsConstraint];
ENDLOOP;
IF lsConstraint = NIL THEN LOOP;
IF c.first.equality
THEN
LinearSolver.AssertZero[table.tableau, lsConstraint]
ELSE
LinearSolver.AssertGEZero[table.tableau, lsConstraint];
ENDLOOP;
};
LookUpUnknown:
PROCEDURE [tableau: LinearSolver.Tableau, name:
ROPE]
RETURNS [v: LinearSolver.Unknown] = {
found: BOOLEAN;
val: REF;
[found, val] ← SymTab.Fetch[constraintSymTab, name];
IF found
THEN
v ← NARROW[val, LinearSolver.Unknown]
ELSE {
v ← LinearSolver.NewUnknown[tableau, name];
LinearSolver.Restrict[tableau, v];
[] ← SymTab.Insert[constraintSymTab, name, v]
};
};