@ohtaman/washi 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +100 -107
- package/README.md +98 -105
- package/README.zh-CN.md +101 -108
- package/dist/browser/highs-worker.js +21 -3
- package/dist/browser/loader-CtaDHef_.js +273 -0
- package/dist/browser/solvers/glpk.js +433 -286
- package/dist/browser/solvers/glpk.min.js +1 -1
- package/dist/browser/solvers/z3.js +1002 -981
- package/dist/browser/solvers/z3.min.js +2 -2
- package/dist/browser/washi.js +2129 -676
- package/dist/browser/washi.min.js +4 -4
- package/dist/lib/highs-worker.js +21 -3
- package/dist/lib/loader-DmNC_UNk.js +279 -0
- package/dist/lib/registry-BEfvpZW3.js +951 -0
- package/dist/lib/solvers/glpk.js +201 -90
- package/dist/lib/solvers/z3.js +399 -259
- package/dist/lib/washi.js +1627 -988
- package/dist/types/index.d.ts +4 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/modeler/big-m.d.ts +75 -0
- package/dist/types/modeler/big-m.d.ts.map +1 -0
- package/dist/types/modeler/boolean-expr.d.ts +103 -14
- package/dist/types/modeler/boolean-expr.d.ts.map +1 -1
- package/dist/types/modeler/constraint.d.ts +36 -9
- package/dist/types/modeler/constraint.d.ts.map +1 -1
- package/dist/types/modeler/expression.d.ts +113 -28
- package/dist/types/modeler/expression.d.ts.map +1 -1
- package/dist/types/modeler/index.d.ts +10 -6
- package/dist/types/modeler/index.d.ts.map +1 -1
- package/dist/types/modeler/lp-writer.d.ts +27 -2
- package/dist/types/modeler/lp-writer.d.ts.map +1 -1
- package/dist/types/modeler/model.d.ts +478 -131
- package/dist/types/modeler/model.d.ts.map +1 -1
- package/dist/types/modeler/objective.d.ts +59 -0
- package/dist/types/modeler/objective.d.ts.map +1 -0
- package/dist/types/modeler/parser.d.ts +34 -10
- package/dist/types/modeler/parser.d.ts.map +1 -1
- package/dist/types/modeler/quad-expr.d.ts +26 -7
- package/dist/types/modeler/quad-expr.d.ts.map +1 -1
- package/dist/types/modeler/solution-validator.d.ts +93 -0
- package/dist/types/modeler/solution-validator.d.ts.map +1 -0
- package/dist/types/modeler/solvers/glpk/solver.d.ts +26 -2
- package/dist/types/modeler/solvers/glpk/solver.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/loader.d.ts +36 -11
- package/dist/types/modeler/solvers/highs/loader.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/solver.d.ts +11 -4
- package/dist/types/modeler/solvers/highs/solver.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/worker-client.d.ts.map +1 -1
- package/dist/types/modeler/solvers/mock.d.ts +14 -5
- package/dist/types/modeler/solvers/mock.d.ts.map +1 -1
- package/dist/types/modeler/solvers/types.d.ts +71 -11
- package/dist/types/modeler/solvers/types.d.ts.map +1 -1
- package/dist/types/modeler/solvers/z3/loader.d.ts +2 -3
- package/dist/types/modeler/solvers/z3/loader.d.ts.map +1 -1
- package/dist/types/modeler/solvers/z3/solver.d.ts +15 -5
- package/dist/types/modeler/solvers/z3/solver.d.ts.map +1 -1
- package/dist/types/modeler/types.d.ts +59 -1
- package/dist/types/modeler/types.d.ts.map +1 -1
- package/dist/types/modeler/validation.d.ts +56 -0
- package/dist/types/modeler/validation.d.ts.map +1 -0
- package/dist/types/modeler/variable.d.ts +48 -14
- package/dist/types/modeler/variable.d.ts.map +1 -1
- package/docs/examples/diet-sensitivity.md +90 -0
- package/docs/examples/ecommerce-coupons.md +106 -0
- package/docs/examples/index.md +53 -0
- package/docs/examples/knapsack.md +60 -0
- package/docs/examples/portfolio-qp.md +83 -0
- package/docs/examples/production.md +51 -0
- package/docs/examples/shift-scheduling.md +175 -0
- package/docs/examples/smt-security.md +74 -0
- package/docs/examples/transportation.md +90 -0
- package/docs/examples/unsat-core.md +64 -0
- package/docs/getting-started/ai-agents.md +267 -0
- package/docs/getting-started/cross-origin.md +87 -0
- package/docs/getting-started/index.md +116 -0
- package/docs/getting-started/runtimes.md +227 -0
- package/docs/guide/constraints.md +177 -0
- package/docs/guide/expressions.md +204 -0
- package/docs/guide/objectives.md +170 -0
- package/docs/guide/unsat-core.md +147 -0
- package/docs/guide/variables.md +188 -0
- package/docs/ja/getting-started/ai-agents.md +266 -0
- package/docs/solvers/custom-solver.md +525 -0
- package/docs/solvers/glpk.md +66 -0
- package/docs/solvers/highs.md +93 -0
- package/docs/solvers/index.md +42 -0
- package/docs/solvers/z3.md +78 -0
- package/docs/zh/getting-started/ai-agents.md +266 -0
- package/llms-full.txt +3249 -0
- package/llms.txt +197 -0
- package/package.json +18 -5
- package/skills/washi/SKILL.md +197 -0
- package/dist/browser/loader-CVt4CloI.js +0 -58
- package/dist/lib/async-mutex-Duo4jwzn.js +0 -195
- package/dist/lib/constraint-BRuB3ooC.js +0 -90
- package/dist/lib/loader-Dti0v9yC.js +0 -50
- package/dist/lib/registry-DksqCSjI.js +0 -32
package/dist/browser/washi.js
CHANGED
|
@@ -1,104 +1,184 @@
|
|
|
1
|
-
import { a as e,
|
|
1
|
+
import { a as e, i as t, n, o as r, r as i, t as a } from "./loader-CtaDHef_.js";
|
|
2
2
|
//#region src/modeler/types.ts
|
|
3
|
-
function
|
|
4
|
-
|
|
3
|
+
function o(e) {
|
|
4
|
+
if (e === void 0) return "Minimize";
|
|
5
|
+
if (typeof e == "string") {
|
|
6
|
+
let t = e.toLowerCase();
|
|
7
|
+
if (t === "maximize") return "Maximize";
|
|
8
|
+
if (t === "minimize") return "Minimize";
|
|
9
|
+
}
|
|
10
|
+
throw Error(`Invalid optimization sense "${String(e)}": expected "Maximize", "Minimize", "maximize", or "minimize".`);
|
|
5
11
|
}
|
|
6
12
|
//#endregion
|
|
7
13
|
//#region src/modeler/boolean-expr.ts
|
|
8
|
-
var
|
|
14
|
+
var s = 0;
|
|
15
|
+
function c(e, t) {
|
|
16
|
+
if (e instanceof l || e instanceof v) return e;
|
|
17
|
+
throw typeof e == "object" && e && ("terms" in e || "quadTerms" in e) ? Error(`Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical operator "${t}". Use a comparison constraint such as expr\`\${x} <= 10\` or a BoolVar/BoolExpr.`) : Error(`Invalid operand passed to logical operator "${t}": expected a BoolVar, BoolExpr, or Constraint.`);
|
|
18
|
+
}
|
|
19
|
+
var l = class {
|
|
9
20
|
and(e) {
|
|
10
|
-
return new
|
|
21
|
+
return new d("and", [this, c(e, "and")]);
|
|
11
22
|
}
|
|
12
23
|
or(e) {
|
|
13
|
-
return new
|
|
24
|
+
return new d("or", [this, c(e, "or")]);
|
|
14
25
|
}
|
|
15
26
|
implies(e) {
|
|
16
|
-
return new
|
|
27
|
+
return new d("implies", [this, c(e, "implies")]);
|
|
17
28
|
}
|
|
18
29
|
xor(e) {
|
|
19
|
-
return new
|
|
30
|
+
return new d("xor", [this, c(e, "xor")]);
|
|
20
31
|
}
|
|
21
32
|
not() {
|
|
22
|
-
return new
|
|
33
|
+
return new d("not", [this]);
|
|
23
34
|
}
|
|
24
|
-
},
|
|
35
|
+
}, u = class extends l {
|
|
25
36
|
id;
|
|
26
37
|
name;
|
|
27
38
|
value = null;
|
|
28
39
|
constructor(e) {
|
|
29
|
-
super(), this.id = ++
|
|
40
|
+
super(), this.id = ++s, this.name = e || `p_${this.id}`;
|
|
30
41
|
}
|
|
31
42
|
toString() {
|
|
32
43
|
return this.name;
|
|
33
44
|
}
|
|
34
|
-
},
|
|
45
|
+
}, d = class extends l {
|
|
35
46
|
op;
|
|
36
47
|
children;
|
|
37
48
|
constructor(e, t) {
|
|
38
|
-
super(), this.op = e, this.children = t;
|
|
49
|
+
super(), this.op = e, this.children = t.map((t) => c(t, e));
|
|
39
50
|
}
|
|
40
51
|
toString() {
|
|
41
52
|
return this.op === "not" ? `not(${this.children[0].toString()})` : `(${this.children.map((e) => e.toString()).join(` ${this.op} `)})`;
|
|
42
53
|
}
|
|
43
54
|
};
|
|
44
|
-
function
|
|
55
|
+
function f(...e) {
|
|
45
56
|
if (e.length === 0) throw Error("and() requires at least one expression");
|
|
46
|
-
return new
|
|
57
|
+
return new d("and", e);
|
|
47
58
|
}
|
|
48
|
-
function
|
|
59
|
+
function p(...e) {
|
|
49
60
|
if (e.length === 0) throw Error("or() requires at least one expression");
|
|
50
|
-
return new
|
|
61
|
+
return new d("or", e);
|
|
51
62
|
}
|
|
52
|
-
function
|
|
53
|
-
return new
|
|
63
|
+
function m(e) {
|
|
64
|
+
return new d("not", [e]);
|
|
54
65
|
}
|
|
55
|
-
function
|
|
56
|
-
return new
|
|
66
|
+
function h(e, t) {
|
|
67
|
+
return new d("implies", [e, t]);
|
|
57
68
|
}
|
|
58
|
-
function
|
|
69
|
+
function g(...e) {
|
|
59
70
|
if (e.length === 0) throw Error("xor() requires at least one expression");
|
|
60
|
-
return new
|
|
71
|
+
return new d("xor", e);
|
|
61
72
|
}
|
|
62
73
|
//#endregion
|
|
63
74
|
//#region src/modeler/constraint.ts
|
|
64
|
-
var
|
|
75
|
+
var _ = 0, v = class e {
|
|
76
|
+
kind = "constraint";
|
|
65
77
|
id;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
78
|
+
_lhs;
|
|
79
|
+
_sense;
|
|
80
|
+
_rhs;
|
|
81
|
+
_name;
|
|
82
|
+
hasExplicitName;
|
|
83
|
+
ownerModel = null;
|
|
70
84
|
slack = null;
|
|
71
85
|
dual = null;
|
|
72
86
|
constructor(e, t, n, r) {
|
|
73
|
-
this.id = ++
|
|
87
|
+
this.id = ++_, this._lhs = e, this._sense = t, this._rhs = n;
|
|
88
|
+
let i = typeof r == "string" ? r.trim() : void 0;
|
|
89
|
+
i && i.length > 0 ? (this._name = i, this.hasExplicitName = !0) : (this._name = `c_${this.id}`, this.hasExplicitName = !1);
|
|
90
|
+
}
|
|
91
|
+
get lhs() {
|
|
92
|
+
return this._lhs;
|
|
93
|
+
}
|
|
94
|
+
set lhs(e) {
|
|
95
|
+
this._lhs !== e && (this._lhs = e, this.ownerModel?.notifyMutation?.());
|
|
96
|
+
}
|
|
97
|
+
get sense() {
|
|
98
|
+
return this._sense;
|
|
99
|
+
}
|
|
100
|
+
set sense(e) {
|
|
101
|
+
this._sense !== e && (this._sense = e, this.ownerModel?.notifyMutation?.());
|
|
102
|
+
}
|
|
103
|
+
get rhs() {
|
|
104
|
+
return this._rhs;
|
|
105
|
+
}
|
|
106
|
+
set rhs(e) {
|
|
107
|
+
Object.is(this._rhs, e) || (this._rhs = e, this.ownerModel?.notifyMutation?.());
|
|
108
|
+
}
|
|
109
|
+
get name() {
|
|
110
|
+
return this._name;
|
|
111
|
+
}
|
|
112
|
+
set name(e) {
|
|
113
|
+
this._name !== e && (this._name = e, this.ownerModel?.notifyMutation?.()), this.hasExplicitName = !0;
|
|
114
|
+
}
|
|
115
|
+
_assignModelName(e, t) {
|
|
116
|
+
this._name = e, this.hasExplicitName = t;
|
|
74
117
|
}
|
|
75
118
|
and(e) {
|
|
76
|
-
return new
|
|
119
|
+
return new d("and", [this, e]);
|
|
77
120
|
}
|
|
78
121
|
or(e) {
|
|
79
|
-
return new
|
|
122
|
+
return new d("or", [this, e]);
|
|
80
123
|
}
|
|
81
124
|
implies(e) {
|
|
82
|
-
return new
|
|
125
|
+
return new d("implies", [this, e]);
|
|
83
126
|
}
|
|
84
127
|
xor(e) {
|
|
85
|
-
return new
|
|
128
|
+
return new d("xor", [this, e]);
|
|
86
129
|
}
|
|
87
130
|
not() {
|
|
88
|
-
return new
|
|
131
|
+
return new d("not", [this]);
|
|
132
|
+
}
|
|
133
|
+
add(e) {
|
|
134
|
+
throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
135
|
+
}
|
|
136
|
+
sub(e) {
|
|
137
|
+
throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
138
|
+
}
|
|
139
|
+
mul(e) {
|
|
140
|
+
throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
141
|
+
}
|
|
142
|
+
div(e) {
|
|
143
|
+
throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
144
|
+
}
|
|
145
|
+
neg() {
|
|
146
|
+
throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
147
|
+
}
|
|
148
|
+
le(e, t) {
|
|
149
|
+
throw Error("Cannot compare a Constraint in (<=): expected a number, Var, or LinExpr.");
|
|
150
|
+
}
|
|
151
|
+
ge(e, t) {
|
|
152
|
+
throw Error("Cannot compare a Constraint in (>=): expected a number, Var, or LinExpr.");
|
|
153
|
+
}
|
|
154
|
+
eq(e, t) {
|
|
155
|
+
throw Error("Cannot compare a Constraint in (==): expected a number, Var, or LinExpr.");
|
|
156
|
+
}
|
|
157
|
+
get value() {
|
|
158
|
+
throw Error("Cannot read numeric value of a Constraint: expected a Var, LinExpr, or QuadExpr.");
|
|
159
|
+
}
|
|
160
|
+
get constant() {
|
|
161
|
+
throw Error("Cannot read numeric constant of a Constraint: expected a LinExpr or QuadExpr.");
|
|
162
|
+
}
|
|
163
|
+
clone() {
|
|
164
|
+
return new e(this._lhs.clone(), this._sense, this._rhs, this.hasExplicitName ? this._name : void 0);
|
|
89
165
|
}
|
|
90
166
|
toString() {
|
|
91
167
|
let e = this.sense === "==" ? "=" : this.sense;
|
|
92
168
|
return `${this.name}: ${this.lhs.toString()} ${e} ${this.rhs}`;
|
|
93
169
|
}
|
|
94
170
|
};
|
|
171
|
+
function y(e) {
|
|
172
|
+
return e instanceof v || typeof e == "object" && !!e && "sense" in e && "lhs" in e && "rhs" in e;
|
|
173
|
+
}
|
|
95
174
|
//#endregion
|
|
96
175
|
//#region src/modeler/quad-expr.ts
|
|
97
|
-
function
|
|
176
|
+
function b(e, t) {
|
|
98
177
|
let n = e.id, r = t.id;
|
|
99
178
|
return n <= r ? `${n}:${r}` : `${r}:${n}`;
|
|
100
179
|
}
|
|
101
|
-
var
|
|
180
|
+
var x = class e {
|
|
181
|
+
kind = "quadratic";
|
|
102
182
|
linearTerms;
|
|
103
183
|
quadTerms;
|
|
104
184
|
constant;
|
|
@@ -111,84 +191,76 @@ var S = class e {
|
|
|
111
191
|
return new e(this.linearTerms, this.quadTerms, this.constant);
|
|
112
192
|
}
|
|
113
193
|
getQuadCoeff(e, t) {
|
|
114
|
-
let n =
|
|
194
|
+
let n = b(e, t), r = this.quadTerms.get(n);
|
|
115
195
|
return r ? r.coeff : 0;
|
|
116
196
|
}
|
|
117
197
|
add(t) {
|
|
198
|
+
if (y(t)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
118
199
|
let n = this.clone();
|
|
119
200
|
if (typeof t == "number") return n.constant += t, n;
|
|
120
201
|
if (t instanceof e) {
|
|
121
202
|
for (let [e, r] of t.quadTerms) {
|
|
122
203
|
let t = n.quadTerms.get(e), i = (t ? t.coeff : 0) + r.coeff;
|
|
123
|
-
|
|
204
|
+
i === 0 ? n.quadTerms.delete(e) : n.quadTerms.set(e, {
|
|
124
205
|
var1: r.var1,
|
|
125
206
|
var2: r.var2,
|
|
126
207
|
coeff: i
|
|
127
208
|
});
|
|
128
209
|
}
|
|
129
210
|
for (let [e, r] of t.linearTerms) {
|
|
130
|
-
let t = (n.linearTerms.get(e)
|
|
131
|
-
|
|
211
|
+
let t = (n.linearTerms.get(e) ?? 0) + r;
|
|
212
|
+
t === 0 ? n.linearTerms.delete(e) : n.linearTerms.set(e, t);
|
|
132
213
|
}
|
|
133
214
|
return n.constant += t.constant, n;
|
|
134
215
|
}
|
|
135
216
|
if ("terms" in t && t.terms instanceof Map) {
|
|
136
217
|
for (let [e, r] of t.terms) {
|
|
137
|
-
let t = (n.linearTerms.get(e)
|
|
138
|
-
|
|
218
|
+
let t = (n.linearTerms.get(e) ?? 0) + r;
|
|
219
|
+
t === 0 ? n.linearTerms.delete(e) : n.linearTerms.set(e, t);
|
|
139
220
|
}
|
|
140
221
|
return n.constant += t.constant, n;
|
|
141
222
|
}
|
|
142
|
-
let r = t, i = (n.linearTerms.get(r)
|
|
143
|
-
return
|
|
223
|
+
let r = t, i = (n.linearTerms.get(r) ?? 0) + 1;
|
|
224
|
+
return i === 0 ? n.linearTerms.delete(r) : n.linearTerms.set(r, i), n;
|
|
144
225
|
}
|
|
145
|
-
sub(
|
|
146
|
-
|
|
226
|
+
sub(e) {
|
|
227
|
+
if (y(e)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
228
|
+
return typeof e == "number" ? this.add(-e) : this.add(e.mul(-1));
|
|
147
229
|
}
|
|
148
230
|
mul(t) {
|
|
231
|
+
if (y(t)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
149
232
|
if (typeof t == "number") {
|
|
150
|
-
let n =
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
233
|
+
let n = this.linearTerms.size > 0 || this.quadTerms.size > 0, r = this.constant === 0 && n ? 0 : this.constant * t;
|
|
234
|
+
if (this.constant !== 0 && t !== 0 && r === 0) throw Error("Constant multiplication underflows to zero.");
|
|
235
|
+
let i = new e(/* @__PURE__ */ new Map(), /* @__PURE__ */ new Map(), r);
|
|
236
|
+
for (let [e, n] of this.linearTerms) {
|
|
237
|
+
let r = n * t;
|
|
238
|
+
if (n !== 0 && t !== 0 && r === 0) throw Error("Coefficient multiplication underflows to zero.");
|
|
239
|
+
r !== 0 && i.linearTerms.set(e, r);
|
|
154
240
|
}
|
|
155
|
-
for (let [e,
|
|
156
|
-
let
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
241
|
+
for (let [e, n] of this.quadTerms) {
|
|
242
|
+
let r = n.coeff * t;
|
|
243
|
+
if (n.coeff !== 0 && t !== 0 && r === 0) throw Error("Coefficient multiplication underflows to zero.");
|
|
244
|
+
r !== 0 && i.quadTerms.set(e, {
|
|
245
|
+
var1: n.var1,
|
|
246
|
+
var2: n.var2,
|
|
247
|
+
coeff: r
|
|
161
248
|
});
|
|
162
249
|
}
|
|
163
|
-
return
|
|
164
|
-
}
|
|
165
|
-
if ("id" in t && "name" in t && !("terms" in t) && !("quadTerms" in t)) {
|
|
166
|
-
if (this.quadTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
167
|
-
let n = new e();
|
|
168
|
-
Math.abs(this.constant) >= 1e-12 && n.linearTerms.set(t, this.constant);
|
|
169
|
-
for (let [r, i] of this.linearTerms) n = n.add(e.fromProduct(r, t, i));
|
|
170
|
-
return n;
|
|
250
|
+
return i;
|
|
171
251
|
}
|
|
172
|
-
let n = t, r = "quadTerms" in
|
|
252
|
+
let n = "id" in t && "name" in t && !("terms" in t) && !("quadTerms" in t), r = "quadTerms" in t ? t.quadTerms.size : 0, i = n ? /* @__PURE__ */ new Map([[t, 1]]) : "quadTerms" in t ? t.linearTerms : t.terms, a = n ? 0 : t.constant;
|
|
173
253
|
if (this.quadTerms.size > 0 && (r > 0 || i.size > 0) || r > 0 && this.linearTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
174
|
-
if (r === 0 && i.size === 0) return this.mul(
|
|
175
|
-
if (this.quadTerms.size === 0 && this.linearTerms.size === 0) {
|
|
176
|
-
let
|
|
177
|
-
|
|
178
|
-
let r = new e();
|
|
179
|
-
r.constant = t.constant;
|
|
180
|
-
for (let [e, n] of t.terms) r.linearTerms.set(e, n);
|
|
181
|
-
return r;
|
|
254
|
+
if (r === 0 && i.size === 0) return this.mul(a);
|
|
255
|
+
if (this.quadTerms.size === 0 && this.linearTerms.size === 0 && !n) {
|
|
256
|
+
let n = t.mul(this.constant);
|
|
257
|
+
return "quadTerms" in n ? n : new e(n.terms, /* @__PURE__ */ new Map(), n.constant);
|
|
182
258
|
}
|
|
183
|
-
|
|
184
|
-
if (a.constant = this.constant * n.constant, Math.abs(n.constant) >= 1e-12) for (let [e, t] of this.linearTerms) a.linearTerms.set(e, (a.linearTerms.get(e) || 0) + t * n.constant);
|
|
185
|
-
if (Math.abs(this.constant) >= 1e-12) for (let [e, t] of i) a.linearTerms.set(e, (a.linearTerms.get(e) || 0) + t * this.constant);
|
|
186
|
-
for (let [t, n] of this.linearTerms) for (let [r, o] of i) a = a.add(e.fromProduct(t, r, n * o));
|
|
187
|
-
return a;
|
|
259
|
+
return e.multiplyLinearTerms(this.constant, this.linearTerms, a, i);
|
|
188
260
|
}
|
|
189
|
-
div(
|
|
190
|
-
|
|
191
|
-
return this.mul(1 /
|
|
261
|
+
div(t) {
|
|
262
|
+
let n = e.extractScalarDivisor(t, "QuadExpr.div()");
|
|
263
|
+
return this.mul(1 / n);
|
|
192
264
|
}
|
|
193
265
|
neg() {
|
|
194
266
|
return this.mul(-1);
|
|
@@ -205,8 +277,34 @@ var S = class e {
|
|
|
205
277
|
}
|
|
206
278
|
return e;
|
|
207
279
|
}
|
|
208
|
-
|
|
209
|
-
return this.
|
|
280
|
+
le(e, t) {
|
|
281
|
+
return this.toConstraint("<=", e, t);
|
|
282
|
+
}
|
|
283
|
+
ge(e, t) {
|
|
284
|
+
return this.toConstraint(">=", e, t);
|
|
285
|
+
}
|
|
286
|
+
eq(e, t) {
|
|
287
|
+
return this.toConstraint("==", e, t);
|
|
288
|
+
}
|
|
289
|
+
toConstraint(e, t, n) {
|
|
290
|
+
if (this.quadTerms.size > 0) throw Error(`Quadratic expressions are not supported in linear constraints (${e}): quadratic terms are only allowed in objectives.`);
|
|
291
|
+
let r = new S(this.linearTerms, this.constant);
|
|
292
|
+
return e === "<=" ? r.le(t, n) : e === ">=" ? r.ge(t, n) : r.eq(t, n);
|
|
293
|
+
}
|
|
294
|
+
and(e) {
|
|
295
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'and': expected a BoolVar, Constraint, or BoolOp.");
|
|
296
|
+
}
|
|
297
|
+
or(e) {
|
|
298
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'or': expected a BoolVar, Constraint, or BoolOp.");
|
|
299
|
+
}
|
|
300
|
+
implies(e) {
|
|
301
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'implies': expected a BoolVar, Constraint, or BoolOp.");
|
|
302
|
+
}
|
|
303
|
+
xor(e) {
|
|
304
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'xor': expected a BoolVar, Constraint, or BoolOp.");
|
|
305
|
+
}
|
|
306
|
+
not() {
|
|
307
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'not': expected a BoolVar, Constraint, or BoolOp.");
|
|
210
308
|
}
|
|
211
309
|
toString() {
|
|
212
310
|
let e = [], t = !0;
|
|
@@ -225,14 +323,50 @@ var S = class e {
|
|
|
225
323
|
return e.join(" ") || "0";
|
|
226
324
|
}
|
|
227
325
|
static fromProduct(t, n, r = 1) {
|
|
228
|
-
let i = new e()
|
|
326
|
+
let i = new e();
|
|
327
|
+
if (r === 0) return i;
|
|
328
|
+
let a = b(t, n);
|
|
229
329
|
return i.quadTerms.set(a, {
|
|
230
330
|
var1: t.id <= n.id ? t : n,
|
|
231
331
|
var2: t.id <= n.id ? n : t,
|
|
232
332
|
coeff: r
|
|
233
333
|
}), i;
|
|
234
334
|
}
|
|
235
|
-
|
|
335
|
+
static multiplyLinearTerms(t, n, r, i) {
|
|
336
|
+
let a = n.size > 0 || i.size > 0, o = (t === 0 || r === 0) && a ? 0 : t * r;
|
|
337
|
+
if (t !== 0 && r !== 0 && o === 0) throw Error("Constant multiplication underflows to zero.");
|
|
338
|
+
let s = new e(/* @__PURE__ */ new Map(), /* @__PURE__ */ new Map(), o === 0 ? 0 : o);
|
|
339
|
+
if (r !== 0) for (let [e, t] of n) {
|
|
340
|
+
let n = t * r;
|
|
341
|
+
if (t !== 0 && n === 0) throw Error("Coefficient multiplication underflows to zero.");
|
|
342
|
+
n !== 0 && s.linearTerms.set(e, n);
|
|
343
|
+
}
|
|
344
|
+
if (t !== 0) for (let [e, n] of i) {
|
|
345
|
+
let r = s.linearTerms.get(e) ?? 0, i = n * t;
|
|
346
|
+
if (n !== 0 && i === 0) throw Error("Coefficient multiplication underflows to zero.");
|
|
347
|
+
let a = r + i;
|
|
348
|
+
a === 0 ? s.linearTerms.delete(e) : s.linearTerms.set(e, a);
|
|
349
|
+
}
|
|
350
|
+
for (let [t, r] of n) for (let [n, a] of i) {
|
|
351
|
+
let i = r * a;
|
|
352
|
+
if (r !== 0 && a !== 0 && i === 0) throw Error("Coefficient multiplication underflows to zero.");
|
|
353
|
+
s = s.add(e.fromProduct(t, n, i));
|
|
354
|
+
}
|
|
355
|
+
return s;
|
|
356
|
+
}
|
|
357
|
+
static extractScalarDivisor(e, t) {
|
|
358
|
+
if (y(e)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
359
|
+
if (typeof e == "number") {
|
|
360
|
+
if (e === 0) throw Error(`Division by zero in ${t}`);
|
|
361
|
+
return e;
|
|
362
|
+
}
|
|
363
|
+
let n = "quadTerms" in e ? e.linearTerms.size : e.terms.size, r = "quadTerms" in e ? e.quadTerms.size : 0;
|
|
364
|
+
if (n > 0 || r > 0) throw Error("Cannot divide by variable in expression");
|
|
365
|
+
if (e.constant === 0) throw Error(`Division by zero in ${t}`);
|
|
366
|
+
return e.constant;
|
|
367
|
+
}
|
|
368
|
+
}, S = class e {
|
|
369
|
+
kind = "linear";
|
|
236
370
|
terms;
|
|
237
371
|
constant;
|
|
238
372
|
constructor(e = /* @__PURE__ */ new Map(), t = 0) {
|
|
@@ -242,59 +376,44 @@ var S = class e {
|
|
|
242
376
|
return new e(this.terms, this.constant);
|
|
243
377
|
}
|
|
244
378
|
add(e) {
|
|
245
|
-
if (e
|
|
379
|
+
if (y(e)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
380
|
+
if (e instanceof x) return e.add(this);
|
|
246
381
|
let t = this.clone();
|
|
247
382
|
if (typeof e == "number") t.constant += e;
|
|
248
383
|
else if ("terms" in e) {
|
|
249
384
|
for (let [n, r] of e.terms) {
|
|
250
|
-
let e = (t.terms.get(n)
|
|
251
|
-
|
|
385
|
+
let e = (t.terms.get(n) ?? 0) + r;
|
|
386
|
+
e === 0 ? t.terms.delete(n) : t.terms.set(n, e);
|
|
252
387
|
}
|
|
253
388
|
t.constant += e.constant;
|
|
254
389
|
} else {
|
|
255
|
-
let n = (t.terms.get(e)
|
|
256
|
-
|
|
390
|
+
let n = (t.terms.get(e) ?? 0) + 1;
|
|
391
|
+
n === 0 ? t.terms.delete(e) : t.terms.set(e, n);
|
|
257
392
|
}
|
|
258
393
|
return t;
|
|
259
394
|
}
|
|
260
395
|
sub(e) {
|
|
261
|
-
|
|
396
|
+
if (y(e)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
397
|
+
return e instanceof x ? e.neg().add(this) : typeof e == "number" ? this.add(-e) : this.add(e.mul(-1));
|
|
262
398
|
}
|
|
263
399
|
mul(t) {
|
|
400
|
+
if (y(t)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
264
401
|
if (typeof t == "number") {
|
|
265
|
-
let n =
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
402
|
+
let n = this.constant === 0 && this.terms.size > 0 ? 0 : this.constant * t;
|
|
403
|
+
if (this.constant !== 0 && t !== 0 && n === 0) throw Error("Constant multiplication underflows to zero.");
|
|
404
|
+
let r = new e(/* @__PURE__ */ new Map(), n);
|
|
405
|
+
for (let [e, n] of this.terms) {
|
|
406
|
+
let i = n * t;
|
|
407
|
+
if (n !== 0 && t !== 0 && i === 0) throw Error("Coefficient multiplication underflows to zero.");
|
|
408
|
+
i !== 0 && r.terms.set(e, i);
|
|
269
409
|
}
|
|
270
|
-
return
|
|
271
|
-
}
|
|
272
|
-
if (t instanceof D || typeof t == "object" && t && "id" in t && !("terms" in t) && !("quadTerms" in t)) {
|
|
273
|
-
let e = t, n = new S();
|
|
274
|
-
Math.abs(this.constant) >= 1e-12 && n.linearTerms.set(e, this.constant);
|
|
275
|
-
for (let [t, r] of this.terms) n = n.add(S.fromProduct(t, e, r));
|
|
276
|
-
return n;
|
|
277
|
-
}
|
|
278
|
-
if (t instanceof S) {
|
|
279
|
-
if (t.quadTerms.size > 0 && this.terms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
280
|
-
if (this.terms.size === 0) return t.mul(this.constant);
|
|
281
|
-
let e = new S();
|
|
282
|
-
if (e.constant = this.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [n, r] of this.terms) e.linearTerms.set(n, (e.linearTerms.get(n) || 0) + r * t.constant);
|
|
283
|
-
if (Math.abs(this.constant) >= 1e-12) for (let [n, r] of t.linearTerms) e.linearTerms.set(n, (e.linearTerms.get(n) || 0) + r * this.constant);
|
|
284
|
-
for (let [n, r] of this.terms) for (let [i, a] of t.linearTerms) e = e.add(S.fromProduct(n, i, r * a));
|
|
285
|
-
return e;
|
|
410
|
+
return r;
|
|
286
411
|
}
|
|
287
|
-
|
|
288
|
-
if (t.terms.size === 0) return this.mul(t.constant);
|
|
289
|
-
let n = new S();
|
|
290
|
-
if (n.constant = this.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [e, r] of this.terms) n.linearTerms.set(e, (n.linearTerms.get(e) || 0) + r * t.constant);
|
|
291
|
-
if (Math.abs(this.constant) >= 1e-12) for (let [e, r] of t.terms) n.linearTerms.set(e, (n.linearTerms.get(e) || 0) + r * this.constant);
|
|
292
|
-
for (let [e, r] of this.terms) for (let [i, a] of t.terms) n = n.add(S.fromProduct(e, i, r * a));
|
|
293
|
-
return n;
|
|
412
|
+
return t instanceof N || typeof t == "object" && t && "id" in t && !("terms" in t) && !("quadTerms" in t) ? x.multiplyLinearTerms(this.constant, this.terms, 0, /* @__PURE__ */ new Map([[t, 1]])) : t instanceof x ? this.terms.size === 0 ? t.mul(this.constant) : new x(this.terms, /* @__PURE__ */ new Map(), this.constant).mul(t) : this.terms.size === 0 ? t.mul(this.constant) : t.terms.size === 0 ? this.mul(t.constant) : x.multiplyLinearTerms(this.constant, this.terms, t.constant, t.terms);
|
|
294
413
|
}
|
|
295
414
|
div(e) {
|
|
296
|
-
|
|
297
|
-
return this.mul(1 /
|
|
415
|
+
let t = x.extractScalarDivisor(e, "LinExpr.div()");
|
|
416
|
+
return this.mul(1 / t);
|
|
298
417
|
}
|
|
299
418
|
neg() {
|
|
300
419
|
return this.mul(-1);
|
|
@@ -307,32 +426,41 @@ var S = class e {
|
|
|
307
426
|
}
|
|
308
427
|
return e;
|
|
309
428
|
}
|
|
310
|
-
getValue() {
|
|
311
|
-
return this.value;
|
|
312
|
-
}
|
|
313
429
|
le(e, t) {
|
|
314
430
|
return this.toConstraint("<=", e, t);
|
|
315
431
|
}
|
|
316
|
-
lessThanOrEqual(e, t) {
|
|
317
|
-
return this.le(e, t);
|
|
318
|
-
}
|
|
319
432
|
ge(e, t) {
|
|
320
433
|
return this.toConstraint(">=", e, t);
|
|
321
434
|
}
|
|
322
|
-
greaterThanOrEqual(e, t) {
|
|
323
|
-
return this.ge(e, t);
|
|
324
|
-
}
|
|
325
435
|
eq(e, t) {
|
|
326
436
|
return this.toConstraint("==", e, t);
|
|
327
437
|
}
|
|
328
|
-
equalTo(e, t) {
|
|
329
|
-
return this.eq(e, t);
|
|
330
|
-
}
|
|
331
438
|
toConstraint(t, n, r) {
|
|
332
439
|
let i = this.clone(), a = 0;
|
|
333
|
-
typeof n == "number"
|
|
440
|
+
if (typeof n == "number") a = n;
|
|
441
|
+
else if (n instanceof v || typeof n == "object" && n && "sense" in n && "lhs" in n) throw Error(`Cannot compare against a Constraint in (${t}): expected a number, Var, or LinExpr.`);
|
|
442
|
+
else if (n instanceof x || typeof n == "object" && n && "quadTerms" in n) {
|
|
443
|
+
let r = n;
|
|
444
|
+
if (r.quadTerms.size > 0) throw Error(`Quadratic expressions are not supported in linear constraints (${t}): quadratic terms are only allowed in objectives.`);
|
|
445
|
+
i = i.sub(new e(r.linearTerms, 0)), a = r.constant;
|
|
446
|
+
} else "terms" in n ? (i = i.sub(new e(n.terms, 0)), a = n.constant) : i = i.sub(n);
|
|
334
447
|
let o = a - i.constant;
|
|
335
|
-
return i.constant = 0, new
|
|
448
|
+
return i.constant = 0, new v(i, t, o, r);
|
|
449
|
+
}
|
|
450
|
+
and(e) {
|
|
451
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'and': expected a BoolVar, Constraint, or BoolOp.");
|
|
452
|
+
}
|
|
453
|
+
or(e) {
|
|
454
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'or': expected a BoolVar, Constraint, or BoolOp.");
|
|
455
|
+
}
|
|
456
|
+
implies(e) {
|
|
457
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'implies': expected a BoolVar, Constraint, or BoolOp.");
|
|
458
|
+
}
|
|
459
|
+
xor(e) {
|
|
460
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'xor': expected a BoolVar, Constraint, or BoolOp.");
|
|
461
|
+
}
|
|
462
|
+
not() {
|
|
463
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'not': expected a BoolVar, Constraint, or BoolOp.");
|
|
336
464
|
}
|
|
337
465
|
toString() {
|
|
338
466
|
let e = [], t = !0;
|
|
@@ -347,22 +475,31 @@ var S = class e {
|
|
|
347
475
|
return e.join(" ") || "0";
|
|
348
476
|
}
|
|
349
477
|
};
|
|
350
|
-
function
|
|
478
|
+
function C(e, t) {
|
|
351
479
|
let n = /* @__PURE__ */ new Map(), r = 0;
|
|
352
480
|
function i(e) {
|
|
353
481
|
if (e != null) {
|
|
354
482
|
if (typeof e == "number") r += e;
|
|
355
|
-
else if (typeof e == "object" && "
|
|
483
|
+
else if (e instanceof v || typeof e == "object" && "sense" in e && "lhs" in e && "rhs" in e) throw Error("Cannot sum a constraint comparison (<=, >=, ==) in sum(): expected a number, Var, or LinExpr.");
|
|
484
|
+
else if (e instanceof x || typeof e == "object" && "quadTerms" in e && e.quadTerms instanceof Map) {
|
|
485
|
+
let t = e;
|
|
486
|
+
if (t.quadTerms.size > 0) throw Error("Quadratic expressions are not supported in sum(): sum() produces a linear expression (LinExpr).");
|
|
487
|
+
for (let [e, r] of t.linearTerms) {
|
|
488
|
+
let t = n.get(e) ?? 0;
|
|
489
|
+
n.set(e, t + r);
|
|
490
|
+
}
|
|
491
|
+
r += t.constant;
|
|
492
|
+
} else if (typeof e == "object" && "terms" in e) {
|
|
356
493
|
let t = e;
|
|
357
494
|
for (let [e, r] of t.terms) {
|
|
358
|
-
let t = n.get(e)
|
|
495
|
+
let t = n.get(e) ?? 0;
|
|
359
496
|
n.set(e, t + r);
|
|
360
497
|
}
|
|
361
498
|
r += t.constant;
|
|
362
|
-
} else {
|
|
363
|
-
let t = e, r = n.get(t)
|
|
499
|
+
} else if (typeof e == "object" && "id" in e && "name" in e && "lb" in e && "ub" in e) {
|
|
500
|
+
let t = e, r = n.get(t) ?? 0;
|
|
364
501
|
n.set(t, r + 1);
|
|
365
|
-
}
|
|
502
|
+
} else throw Error("Unsupported item in sum(): expected a number, Var, or LinExpr.");
|
|
366
503
|
}
|
|
367
504
|
}
|
|
368
505
|
if (typeof e == "number") {
|
|
@@ -372,41 +509,55 @@ function w(e, t) {
|
|
|
372
509
|
let n = 0;
|
|
373
510
|
for (let r of e) i(t ? t(r, n++) : r);
|
|
374
511
|
}
|
|
375
|
-
for (let [e, t] of n)
|
|
376
|
-
return new
|
|
512
|
+
for (let [e, t] of n) t === 0 && n.delete(e);
|
|
513
|
+
return new S(n, r);
|
|
377
514
|
}
|
|
378
|
-
function
|
|
515
|
+
function w(e, t) {
|
|
379
516
|
let n = /* @__PURE__ */ new Map(), r = 0;
|
|
380
517
|
function i(e) {
|
|
381
|
-
return typeof e == "object" && !!e && typeof e.id == "number" && typeof e.name == "string" && typeof e.mul == "function" && typeof e.le == "function";
|
|
518
|
+
return typeof e == "object" && !!e && !(e instanceof v) && typeof e.id == "number" && typeof e.name == "string" && typeof e.lb == "number" && typeof e.ub == "number" && typeof e.type == "string" && typeof e.mul == "function" && typeof e.le == "function";
|
|
382
519
|
}
|
|
383
520
|
function a(e) {
|
|
384
|
-
return i(e) || e instanceof
|
|
521
|
+
return i(e) || e instanceof S || e instanceof x;
|
|
385
522
|
}
|
|
386
|
-
function o(e, t) {
|
|
387
|
-
if (
|
|
388
|
-
|
|
523
|
+
function o(e, t, a) {
|
|
524
|
+
if (!Number.isFinite(e)) throw Error(`Invalid non-finite coefficient "${e}" in dot() at '${a || "root"}'.`);
|
|
525
|
+
if (t instanceof x) throw Error(`Quadratic expressions are not supported in dot() at '${a || "root"}': dot() produces a linear expression (LinExpr).`);
|
|
526
|
+
if (t instanceof S) {
|
|
527
|
+
if (!Number.isFinite(t.constant)) throw Error(`Invalid non-finite constant "${t.constant}" in dot() at '${a || "root"}'.`);
|
|
528
|
+
let i = e === 0 || t.constant === 0 ? 0 : e * t.constant;
|
|
529
|
+
if (e !== 0 && t.constant !== 0 && i === 0) throw Error("Constant multiplication underflows to zero.");
|
|
530
|
+
if (!Number.isFinite(i)) throw Error(`Coefficient multiplication overflows finite floating-point range in dot() at '${a || "root"}'.`);
|
|
531
|
+
let o = r + i;
|
|
532
|
+
if (!Number.isFinite(o)) throw Error(`Constant accumulation overflows finite floating-point range in dot() at '${a || "root"}'.`);
|
|
533
|
+
r = o;
|
|
389
534
|
for (let [r, i] of t.terms) {
|
|
390
|
-
|
|
391
|
-
|
|
535
|
+
if (!Number.isFinite(i)) throw Error(`Invalid non-finite coefficient "${i}" in dot() at '${a || "root"}'.`);
|
|
536
|
+
let t = e * i;
|
|
537
|
+
if (e !== 0 && i !== 0 && t === 0) throw Error("Coefficient multiplication underflows to zero.");
|
|
538
|
+
if (!Number.isFinite(t)) throw Error(`Coefficient multiplication overflows finite floating-point range in dot() at '${a || "root"}'.`);
|
|
539
|
+
let o = (n.get(r) ?? 0) + t;
|
|
540
|
+
if (!Number.isFinite(o)) throw Error(`Coefficient accumulation overflows finite floating-point range in dot() at '${a || "root"}'.`);
|
|
541
|
+
n.set(r, o);
|
|
392
542
|
}
|
|
393
|
-
r += e * t.constant;
|
|
394
543
|
} else if (i(t)) {
|
|
395
|
-
let r = t, i = n.get(r)
|
|
396
|
-
|
|
397
|
-
|
|
544
|
+
let r = t, i = (n.get(r) ?? 0) + e;
|
|
545
|
+
if (!Number.isFinite(i)) throw Error(`Coefficient accumulation overflows finite floating-point range in dot() at '${a || "root"}'.`);
|
|
546
|
+
n.set(r, i);
|
|
547
|
+
} else throw Error(`Cannot multiply number by non-variable/expression operand in dot() at '${a || "root"}'.`);
|
|
398
548
|
}
|
|
399
549
|
function s(e) {
|
|
400
|
-
return typeof e == "object" && !!e && !Array.isArray(e) && !a(e);
|
|
550
|
+
return typeof e == "object" && !!e && !Array.isArray(e) && !a(e) && !(e instanceof v) && e.kind !== "constraint";
|
|
401
551
|
}
|
|
402
552
|
function c(e, t, n = "") {
|
|
403
553
|
if (e === void 0 || t === void 0 || e === null || t === null) throw Error(`Nullish or undefined operand encountered in dot() at '${n || "root"}'.`);
|
|
554
|
+
if (typeof e == "number" && typeof t == "number") throw Error(`Cannot multiply two numbers in dot() at '${n || "root"}': expected one numeric coefficient and one Var or LinExpr.`);
|
|
404
555
|
if (typeof e == "number") {
|
|
405
|
-
o(e, t);
|
|
556
|
+
o(e, t, n);
|
|
406
557
|
return;
|
|
407
558
|
}
|
|
408
559
|
if (typeof t == "number") {
|
|
409
|
-
o(t, e);
|
|
560
|
+
o(t, e, n);
|
|
410
561
|
return;
|
|
411
562
|
}
|
|
412
563
|
if (Array.isArray(e) || Array.isArray(t)) {
|
|
@@ -417,21 +568,22 @@ function ee(e, t) {
|
|
|
417
568
|
}
|
|
418
569
|
let r = Array.isArray(e) ? e : t, i = Array.isArray(e) ? t : e;
|
|
419
570
|
if (s(i)) {
|
|
571
|
+
if (Object.getOwnPropertySymbols(i).length > 0) throw Error(`Symbol keys are not supported in dot() at '${n || "root"}'.`);
|
|
420
572
|
let a = Object.keys(i);
|
|
421
|
-
if (a.length
|
|
422
|
-
|
|
423
|
-
let
|
|
424
|
-
|
|
425
|
-
if (o.length > 0) throw Error(`Key mismatch in dot() at '${n || "root"}': missing indices [${o.join(", ")}] in numeric record.`);
|
|
573
|
+
if (a.length === r.length && a.every((e) => /^(?:0|[1-9]\d*)$/.test(e))) {
|
|
574
|
+
let a = [];
|
|
575
|
+
for (let e = 0; e < r.length; e++) Object.prototype.hasOwnProperty.call(i, e) || a.push(e);
|
|
576
|
+
if (a.length > 0) throw Error(`Key mismatch in dot() at '${n || "root"}': missing indices [${a.join(", ")}] in numeric record.`);
|
|
426
577
|
for (let i = 0; i < r.length; i++) c(e[i], t[i], n ? `${n}[${i}]` : `[${i}]`);
|
|
427
578
|
return;
|
|
428
579
|
}
|
|
429
|
-
throw Error(`Type mismatch in dot() at '${n || "root"}': one operand is an Array while the other is an Object with keys [${a.slice(0, 5).join(", ")}].`);
|
|
580
|
+
throw a.length > 0 && a.every((e) => /^(?:0|[1-9]\d*)$/.test(e)) ? Error(`Array length mismatch in dot() at '${n || "root"}': array has length ${r.length}, but object has ${a.length} indices.`) : Error(`Type mismatch in dot() at '${n || "root"}': one operand is an Array while the other is an Object with keys [${a.slice(0, 5).join(", ")}].`);
|
|
430
581
|
}
|
|
431
582
|
throw Error(`Type mismatch in dot() at '${n || "root"}': one operand is an Array while the other is not.`);
|
|
432
583
|
}
|
|
433
584
|
if (s(e) && s(t)) {
|
|
434
|
-
|
|
585
|
+
if (Object.getOwnPropertySymbols(e).length > 0 || Object.getOwnPropertySymbols(t).length > 0) throw Error(`Symbol keys are not supported in dot() at '${n || "root"}'.`);
|
|
586
|
+
let r = Object.keys(e), i = Object.keys(t), a = r.filter((e) => !Object.prototype.hasOwnProperty.call(t, e)), o = i.filter((t) => !Object.prototype.hasOwnProperty.call(e, t));
|
|
435
587
|
if (a.length > 0 || o.length > 0) {
|
|
436
588
|
let e = [];
|
|
437
589
|
throw a.length > 0 && e.push(`missing in second operand: [${a.join(", ")}]`), o.length > 0 && e.push(`missing in first operand: [${o.join(", ")}]`), Error(`Key mismatch in dot() at '${n || "root"}': ${e.join("; ")}.`);
|
|
@@ -442,160 +594,314 @@ function ee(e, t) {
|
|
|
442
594
|
throw Error(`Unsupported operand types in dot() at '${n || "root"}'.`);
|
|
443
595
|
}
|
|
444
596
|
c(e, t);
|
|
445
|
-
for (let [e, t] of n)
|
|
446
|
-
return new
|
|
597
|
+
for (let [e, t] of n) t === 0 && n.delete(e);
|
|
598
|
+
return new S(n, r);
|
|
599
|
+
}
|
|
600
|
+
//#endregion
|
|
601
|
+
//#region src/modeler/validation.ts
|
|
602
|
+
var T = /* @__PURE__ */ new WeakMap(), E = /* @__PURE__ */ new WeakMap(), D = /* @__PURE__ */ new WeakMap();
|
|
603
|
+
function O(e, t, n) {
|
|
604
|
+
if (e instanceof d) for (let r of e.children) O(r, t, n);
|
|
605
|
+
else if (e instanceof v) {
|
|
606
|
+
let r = e.ownerModel, i = E.get(e);
|
|
607
|
+
(r !== t || i !== t) && (n && n.push(() => {
|
|
608
|
+
e.ownerModel = r, i ? E.set(e, i) : E.delete(e);
|
|
609
|
+
}), e.ownerModel = t, E.set(e, t));
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
function k(e, t) {
|
|
613
|
+
let n = T.get(e);
|
|
614
|
+
if (n && n !== t) throw Error(`Variable "${e.name}" already belongs to model "${n.name}" and cannot be added to model "${t.name}".`);
|
|
615
|
+
T.set(e, t);
|
|
616
|
+
}
|
|
617
|
+
function ee(e, t) {
|
|
618
|
+
let n = D.get(e);
|
|
619
|
+
if (n) throw Error(n === t ? `Constraint "${e.name}" is already registered in model "${t.name}".` : `Constraint "${e.name}" already belongs to model "${n.name}" and cannot be added to model "${t.name}".`);
|
|
620
|
+
let r = E.get(e);
|
|
621
|
+
if (r && r !== t) throw Error(`Constraint "${e.name}" already belongs to model "${r.name}" and cannot be added to model "${t.name}".`);
|
|
622
|
+
return D.set(e, t), E.set(e, t), r;
|
|
623
|
+
}
|
|
624
|
+
function te(e, t) {
|
|
625
|
+
T.get(e) === t && T.delete(e);
|
|
626
|
+
}
|
|
627
|
+
function ne(e, t, n) {
|
|
628
|
+
D.get(e) === t && D.delete(e), E.get(e) === t && (n ? E.set(e, n) : E.delete(e));
|
|
629
|
+
}
|
|
630
|
+
var re = 1e-6;
|
|
631
|
+
function A(e) {
|
|
632
|
+
if (typeof e.lb != "number" || Number.isNaN(e.lb)) throw Error(`Variable "${e.name}" has invalid lower bound: ${e.lb} (NaN or non-numeric bound is not allowed).`);
|
|
633
|
+
if (e.lb === Infinity) throw Error(`Variable "${e.name}" has invalid lower bound: +Infinity is not allowed as a lower bound.`);
|
|
634
|
+
if (typeof e.ub != "number" || Number.isNaN(e.ub)) throw Error(`Variable "${e.name}" has invalid upper bound: ${e.ub} (NaN or non-numeric bound is not allowed).`);
|
|
635
|
+
if (e.ub === -Infinity) throw Error(`Variable "${e.name}" has invalid upper bound: -Infinity is not allowed as an upper bound.`);
|
|
636
|
+
if (e.lb > e.ub) throw Error(`Variable "${e.name}" has invalid bounds: lower bound (${e.lb}) is strictly greater than upper bound (${e.ub}).`);
|
|
637
|
+
if (e.initialValue !== void 0) {
|
|
638
|
+
if (typeof e.initialValue != "number" || !Number.isFinite(e.initialValue)) throw Error(`Variable "${e.name}" has invalid initialValue: ${String(e.initialValue)} (initialValue must be a finite number).`);
|
|
639
|
+
let t = e.type === "Binary" ? Math.max(0, e.lb) : e.lb, n = e.type === "Binary" ? Math.min(1, e.ub) : e.ub;
|
|
640
|
+
if (e.initialValue < t - 1e-6 || e.initialValue > n + 1e-6) throw Error(`Variable "${e.name}" has initialValue (${e.initialValue}) outside its bounds [${t}, ${n}] (tolerance ${re}).`);
|
|
641
|
+
if (e.type === "Integer" || e.type === "Binary") {
|
|
642
|
+
let r = Math.round(e.initialValue);
|
|
643
|
+
if (Math.abs(e.initialValue - r) > 1e-6 || r < t || r > n) throw Error(`Variable "${e.name}" of type "${e.type}" has non-integral or out-of-domain initialValue: ${e.initialValue} (must be within ${re} of an integer in [${t}, ${n}]).`);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
function ie(e) {
|
|
648
|
+
if (e.initialValue === void 0) return;
|
|
649
|
+
if (A(e), e.type === "Integer" || e.type === "Binary") {
|
|
650
|
+
let t = Math.round(e.initialValue);
|
|
651
|
+
return Object.is(t, -0) ? 0 : t;
|
|
652
|
+
}
|
|
653
|
+
let t = Math.min(e.ub, Math.max(e.lb, e.initialValue));
|
|
654
|
+
return Object.is(t, -0) ? 0 : t;
|
|
655
|
+
}
|
|
656
|
+
function ae(e, t, n) {
|
|
657
|
+
if (e instanceof x) {
|
|
658
|
+
if (!Number.isFinite(e.constant)) throw Error(`Objective function has invalid constant: ${e.constant}. Constant must be a finite number.`);
|
|
659
|
+
for (let [r, i] of e.linearTerms) {
|
|
660
|
+
if (!n(r)) throw Error(`Variable "${r.name}" in objective function does not belong to model "${t}". All variables must belong to the model by object identity.`);
|
|
661
|
+
if (!Number.isFinite(i)) throw Error(`Variable "${r.name}" in objective function has invalid coefficient: ${i}. Coefficients must be finite numbers.`);
|
|
662
|
+
}
|
|
663
|
+
for (let [, r] of e.quadTerms) {
|
|
664
|
+
if (!n(r.var1)) throw Error(`Variable "${r.var1.name}" in quadratic objective function does not belong to model "${t}". All variables must belong to the model by object identity.`);
|
|
665
|
+
if (!n(r.var2)) throw Error(`Variable "${r.var2.name}" in quadratic objective function does not belong to model "${t}". All variables must belong to the model by object identity.`);
|
|
666
|
+
if (!Number.isFinite(r.coeff) || !Number.isFinite(r.coeff * 2)) throw Error(`Quadratic term (${r.var1.name} * ${r.var2.name}) in objective function has invalid coefficient: ${r.coeff}.`);
|
|
667
|
+
}
|
|
668
|
+
} else if ("terms" in e) {
|
|
669
|
+
if (!Number.isFinite(e.constant)) throw Error(`Objective function has invalid constant: ${e.constant}. Constant must be a finite number.`);
|
|
670
|
+
for (let [r, i] of e.terms) {
|
|
671
|
+
if (!n(r)) throw Error(`Variable "${r.name}" in objective function does not belong to model "${t}". All variables must belong to the model by object identity.`);
|
|
672
|
+
if (!Number.isFinite(i)) throw Error(`Variable "${r.name}" in objective function has invalid coefficient: ${i}. Coefficients must be finite numbers.`);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
function j(e, t, n, r = e.name) {
|
|
677
|
+
if (!Number.isFinite(e.rhs)) throw Error(`Constraint "${r}" has invalid right-hand side (RHS): ${e.rhs}. RHS must be a finite number.`);
|
|
678
|
+
if (e.lhs.constant !== void 0 && !Number.isFinite(e.lhs.constant)) throw Error(`Constraint "${r}" has invalid LHS constant: ${e.lhs.constant}. Constant must be a finite number.`);
|
|
679
|
+
for (let [i, a] of e.lhs.terms) {
|
|
680
|
+
if (!n(i)) throw Error(`Variable "${i.name}" in constraint "${r}" does not belong to model "${t}". All variables must belong to the model by object identity.`);
|
|
681
|
+
if (!Number.isFinite(a)) throw Error(`Variable "${i.name}" in constraint "${r}" has invalid coefficient: ${a}. Coefficients must be finite numbers.`);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
function M(e, t, n, r, i, a) {
|
|
685
|
+
if (e instanceof u) {
|
|
686
|
+
if (!i(e)) throw Error(`Boolean variable "${e.name}" in logical constraint "${t}" does not belong to model "${n}".`);
|
|
687
|
+
} else if (e instanceof d) for (let o of e.children) M(o, t, n, r, i, a);
|
|
688
|
+
else if (e instanceof v) {
|
|
689
|
+
if (a) {
|
|
690
|
+
let r = E.get(e) ?? e.ownerModel ?? void 0;
|
|
691
|
+
if (r && r !== a) throw Error(`Constraint "${e.name}" embedded in logical constraint "${t}" already belongs to model "${r.name ?? "another model"}" and cannot be added to model "${n}".`);
|
|
692
|
+
}
|
|
693
|
+
if (!Number.isFinite(e.rhs)) throw Error(`Constraint "${e.name}" embedded in logical constraint "${t}" has invalid RHS: ${e.rhs}.`);
|
|
694
|
+
if (e.lhs.constant !== void 0 && !Number.isFinite(e.lhs.constant)) throw Error(`Constraint "${e.name}" embedded in logical constraint "${t}" has invalid LHS constant: ${e.lhs.constant}.`);
|
|
695
|
+
for (let [i, a] of e.lhs.terms) {
|
|
696
|
+
if (!r(i)) throw Error(`Variable "${i.name}" embedded in logical constraint "${t}" does not belong to model "${n}".`);
|
|
697
|
+
if (!Number.isFinite(a)) throw Error(`Variable "${i.name}" embedded in logical constraint "${t}" has invalid coefficient: ${a}.`);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
function oe(e) {
|
|
702
|
+
let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set();
|
|
703
|
+
for (let r of e.variables) {
|
|
704
|
+
A(r);
|
|
705
|
+
let i = T.get(r);
|
|
706
|
+
if (i && i !== e || t.has(r.name) || e.getVarByName(r.name) !== r) throw Error(`Variable "${r.name}" is duplicated or not canonically registered in model "${e.name}".`);
|
|
707
|
+
t.add(r.name), n.add(r);
|
|
708
|
+
}
|
|
709
|
+
let r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set();
|
|
710
|
+
for (let t of e.boolVars) {
|
|
711
|
+
if (r.has(t.name) || e.getBoolVarByName(t.name) !== t) throw Error(`Boolean variable "${t.name}" is duplicated or not canonically registered in model "${e.name}".`);
|
|
712
|
+
r.add(t.name), i.add(t);
|
|
713
|
+
}
|
|
714
|
+
let a = /* @__PURE__ */ new Set();
|
|
715
|
+
for (let t of e.constraints) {
|
|
716
|
+
if (r.has(t.name)) throw Error(`Constraint name "${t.name}" conflicts with Boolean variable "${t.name}" in model "${e.name}".`);
|
|
717
|
+
if (a.has(t.name)) throw Error(`Duplicate constraint name "${t.name}" in model "${e.name}".`);
|
|
718
|
+
a.add(t.name);
|
|
719
|
+
}
|
|
720
|
+
for (let t of e.logicalConstraints) {
|
|
721
|
+
if (r.has(t.name)) throw Error(`Logical constraint name "${t.name}" conflicts with Boolean variable "${t.name}" in model "${e.name}".`);
|
|
722
|
+
if (a.has(t.name)) throw Error(`Conflicting constraint name "${t.name}" across arithmetic and logical constraints in model "${e.name}".`);
|
|
723
|
+
a.add(t.name);
|
|
724
|
+
}
|
|
725
|
+
for (let t of e.constraints) {
|
|
726
|
+
let n = E.get(t);
|
|
727
|
+
if (n && n !== e || e.getConstraintByName(t.name) !== t) throw Error(`Constraint "${t.name}" is duplicated or not canonically registered in model "${e.name}".`);
|
|
728
|
+
}
|
|
729
|
+
for (let t of e.logicalConstraints) if (e.getLogicalConstraintByName(t.name) !== t) throw Error(`Logical constraint "${t.name}" is duplicated or not canonically registered in model "${e.name}".`);
|
|
730
|
+
e.objectiveExpr && ae(e.objectiveExpr, e.name, (e) => n.has(e));
|
|
731
|
+
for (let t of e.constraints) j(t, e.name, (e) => n.has(e));
|
|
732
|
+
for (let t of e.logicalConstraints) M(t.expr, t.name, e.name, (e) => n.has(e), (e) => i.has(e), e);
|
|
447
733
|
}
|
|
448
734
|
//#endregion
|
|
449
735
|
//#region src/modeler/variable.ts
|
|
450
|
-
var
|
|
451
|
-
function
|
|
452
|
-
if (
|
|
453
|
-
|
|
454
|
-
|
|
736
|
+
var se = 0;
|
|
737
|
+
function ce(e) {
|
|
738
|
+
if (e === void 0) return "Continuous";
|
|
739
|
+
if (typeof e == "string") {
|
|
740
|
+
let t = e.toLowerCase();
|
|
741
|
+
if (t === "binary" || t === "bin") return "Binary";
|
|
742
|
+
if (t === "integer" || t === "int") return "Integer";
|
|
743
|
+
if (t === "continuous" || t === "cont") return "Continuous";
|
|
744
|
+
}
|
|
745
|
+
throw Error(`Invalid variable type "${String(e)}": expected "Continuous", "Integer", or "Binary".`);
|
|
455
746
|
}
|
|
456
|
-
var
|
|
747
|
+
var N = class {
|
|
457
748
|
id;
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
749
|
+
_name;
|
|
750
|
+
prefix;
|
|
751
|
+
hasExplicitName;
|
|
752
|
+
ownerModel = null;
|
|
753
|
+
_type;
|
|
754
|
+
_lb;
|
|
755
|
+
_ub;
|
|
756
|
+
_initialValue;
|
|
462
757
|
value = null;
|
|
463
758
|
reducedCost = null;
|
|
464
759
|
constructor(e = {}) {
|
|
465
|
-
this.id = ++
|
|
760
|
+
this.id = ++se;
|
|
761
|
+
let t = typeof e.name == "string" ? e.name.trim() : "", n = typeof e.prefix == "string" ? e.prefix.trim() : "";
|
|
762
|
+
this.prefix = n.length > 0 ? n : "x", this.hasExplicitName = t.length > 0, this._name = this.hasExplicitName ? t : `${this.prefix}_${this.id}`, this._type = ce(e.type), this._type === "Binary" ? (this._lb = 0, this._ub = 1) : (this._lb = e.lb === void 0 ? 0 : e.lb, this._ub = e.ub === void 0 ? Infinity : e.ub), this._initialValue = e.initialValue === void 0 ? void 0 : Object.is(e.initialValue, -0) ? 0 : e.initialValue, this._initialValue !== void 0 && A(this);
|
|
466
763
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
764
|
+
get name() {
|
|
765
|
+
return this._name;
|
|
766
|
+
}
|
|
767
|
+
get type() {
|
|
768
|
+
return this._type;
|
|
769
|
+
}
|
|
770
|
+
set type(e) {
|
|
771
|
+
let t = ce(e);
|
|
772
|
+
this._type !== t && (this._type = t, this.ownerModel?.notifyMutation?.());
|
|
773
|
+
}
|
|
774
|
+
get lb() {
|
|
775
|
+
return this._lb;
|
|
776
|
+
}
|
|
777
|
+
set lb(e) {
|
|
778
|
+
Object.is(this._lb, e) || (this._lb = e, this.ownerModel?.notifyMutation?.());
|
|
779
|
+
}
|
|
780
|
+
get ub() {
|
|
781
|
+
return this._ub;
|
|
782
|
+
}
|
|
783
|
+
set ub(e) {
|
|
784
|
+
Object.is(this._ub, e) || (this._ub = e, this.ownerModel?.notifyMutation?.());
|
|
785
|
+
}
|
|
786
|
+
get initialValue() {
|
|
787
|
+
return this._initialValue;
|
|
788
|
+
}
|
|
789
|
+
set initialValue(e) {
|
|
790
|
+
let t = e !== void 0 && Object.is(e, -0) ? 0 : e;
|
|
791
|
+
Object.is(this._initialValue, t) || (this._initialValue = t, this.ownerModel?.notifyMutation?.());
|
|
792
|
+
}
|
|
793
|
+
_assignModelName(e) {
|
|
794
|
+
this._name = e;
|
|
795
|
+
}
|
|
796
|
+
mul(e) {
|
|
797
|
+
return typeof e == "number" ? new S(/* @__PURE__ */ new Map([[this, 1]]), 0).mul(e) : new x(/* @__PURE__ */ new Map([[this, 1]]), /* @__PURE__ */ new Map(), 0).mul(e);
|
|
484
798
|
}
|
|
485
799
|
add(e) {
|
|
486
|
-
return e instanceof
|
|
800
|
+
return e instanceof x ? e.add(this) : new S(/* @__PURE__ */ new Map([[this, 1]]), 0).add(e);
|
|
487
801
|
}
|
|
488
802
|
sub(e) {
|
|
489
|
-
return e instanceof
|
|
803
|
+
return e instanceof x ? e.neg().add(this) : new S(/* @__PURE__ */ new Map([[this, 1]]), 0).sub(e);
|
|
490
804
|
}
|
|
491
805
|
neg() {
|
|
492
806
|
return this.mul(-1);
|
|
493
807
|
}
|
|
494
808
|
le(e, t) {
|
|
495
|
-
return new
|
|
496
|
-
}
|
|
497
|
-
lessThanOrEqual(e, t) {
|
|
498
|
-
return this.le(e, t);
|
|
809
|
+
return new S(/* @__PURE__ */ new Map([[this, 1]]), 0).le(e, t);
|
|
499
810
|
}
|
|
500
811
|
ge(e, t) {
|
|
501
|
-
return new
|
|
502
|
-
}
|
|
503
|
-
greaterThanOrEqual(e, t) {
|
|
504
|
-
return this.ge(e, t);
|
|
812
|
+
return new S(/* @__PURE__ */ new Map([[this, 1]]), 0).ge(e, t);
|
|
505
813
|
}
|
|
506
814
|
eq(e, t) {
|
|
507
|
-
return new
|
|
508
|
-
}
|
|
509
|
-
equalTo(e, t) {
|
|
510
|
-
return this.eq(e, t);
|
|
815
|
+
return new S(/* @__PURE__ */ new Map([[this, 1]]), 0).eq(e, t);
|
|
511
816
|
}
|
|
512
817
|
toString() {
|
|
513
818
|
return this.name;
|
|
514
819
|
}
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
if (/\s/.test(i)) {
|
|
523
|
-
n++;
|
|
820
|
+
}, le = /^(?:[0-9]+(?:\.[0-9]+)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;
|
|
821
|
+
function ue(e, t) {
|
|
822
|
+
let n = [], r = 0, i = e.length;
|
|
823
|
+
for (; r < i;) {
|
|
824
|
+
let a = e[r];
|
|
825
|
+
if (/\s/.test(a)) {
|
|
826
|
+
r++;
|
|
524
827
|
continue;
|
|
525
828
|
}
|
|
526
|
-
if (
|
|
829
|
+
if (a === "+") n.push({
|
|
527
830
|
type: "PLUS",
|
|
528
831
|
value: "+"
|
|
529
|
-
}),
|
|
530
|
-
else if (
|
|
832
|
+
}), r++;
|
|
833
|
+
else if (a === "-") n.push({
|
|
531
834
|
type: "MINUS",
|
|
532
835
|
value: "-"
|
|
533
|
-
}),
|
|
534
|
-
else if (
|
|
836
|
+
}), r++;
|
|
837
|
+
else if (a === "*") r + 1 < i && e[r + 1] === "*" ? (n.push({
|
|
535
838
|
type: "CARET",
|
|
536
839
|
value: "**"
|
|
537
|
-
}),
|
|
840
|
+
}), r += 2) : (n.push({
|
|
538
841
|
type: "STAR",
|
|
539
842
|
value: "*"
|
|
540
|
-
}),
|
|
541
|
-
else if (
|
|
843
|
+
}), r++);
|
|
844
|
+
else if (a === "^") n.push({
|
|
542
845
|
type: "CARET",
|
|
543
846
|
value: "^"
|
|
544
|
-
}),
|
|
545
|
-
else if (
|
|
847
|
+
}), r++;
|
|
848
|
+
else if (a === "/") n.push({
|
|
546
849
|
type: "SLASH",
|
|
547
850
|
value: "/"
|
|
548
|
-
}),
|
|
549
|
-
else if (
|
|
851
|
+
}), r++;
|
|
852
|
+
else if (a === "(") n.push({
|
|
550
853
|
type: "LPAREN",
|
|
551
854
|
value: "("
|
|
552
|
-
}),
|
|
553
|
-
else if (
|
|
855
|
+
}), r++;
|
|
856
|
+
else if (a === ")") n.push({
|
|
554
857
|
type: "RPAREN",
|
|
555
858
|
value: ")"
|
|
556
|
-
}),
|
|
557
|
-
else if (
|
|
558
|
-
let
|
|
559
|
-
|
|
859
|
+
}), r++;
|
|
860
|
+
else if (a === "<" || a === ">" || a === "=") {
|
|
861
|
+
let t = a;
|
|
862
|
+
r + 1 < i && (e[r + 1] === "=" || e[r + 1] === "<" || e[r + 1] === ">") ? (t += e[r + 1], r += 2) : r++, n.push({
|
|
560
863
|
type: "COMP",
|
|
561
|
-
value:
|
|
864
|
+
value: t
|
|
562
865
|
});
|
|
563
|
-
} else if (/[0-9.]/.test(
|
|
564
|
-
let
|
|
565
|
-
for (;
|
|
566
|
-
|
|
866
|
+
} else if (/[0-9.]/.test(a)) {
|
|
867
|
+
let t = r, a = "";
|
|
868
|
+
for (; r < i && /[0-9]/.test(e[r]);) a += e[r++];
|
|
869
|
+
if (r < i && e[r] === ".") for (a += e[r++]; r < i && /[0-9]/.test(e[r]);) a += e[r++];
|
|
870
|
+
if (r < i && (e[r] === "e" || e[r] === "E")) {
|
|
871
|
+
let t = r + 1 < i ? e[r + 1] : "";
|
|
872
|
+
if (!/[a-zA-Z_]/.test(t)) {
|
|
873
|
+
for (a += e[r++], r < i && (e[r] === "+" || e[r] === "-") && (a += e[r++]); r < i && /[0-9]/.test(e[r]);) a += e[r++];
|
|
874
|
+
for (; r < i && (e[r] === "." || e[r] === "e" || e[r] === "E" || /[0-9]/.test(e[r]));) a += e[r++];
|
|
875
|
+
}
|
|
876
|
+
} else for (; r < i && (e[r] === "." || /[0-9]/.test(e[r]));) a += e[r++];
|
|
877
|
+
if (!le.test(a)) throw Error(`Invalid numeric literal '${a}' at position ${t} in: "${e}"`);
|
|
878
|
+
let o = Number(a);
|
|
879
|
+
if (!Number.isFinite(o)) throw Error(`Numeric literal '${a}' overflows finite floating-point range in: "${e}"`);
|
|
880
|
+
if (o === 0 && !/^[0.]+(?:[eE][+-]?\d+)?$/.test(a)) throw Error(`Numeric literal '${a}' underflows to zero at position ${t} in: "${e}"`);
|
|
881
|
+
n.push({
|
|
567
882
|
type: "NUMBER",
|
|
568
|
-
value:
|
|
883
|
+
value: a,
|
|
884
|
+
numericValue: o
|
|
569
885
|
});
|
|
570
|
-
} else if (/[a-zA-Z_]/.test(
|
|
571
|
-
let
|
|
572
|
-
for (;
|
|
573
|
-
t.
|
|
886
|
+
} else if (/[a-zA-Z_]/.test(a)) {
|
|
887
|
+
let a = "";
|
|
888
|
+
for (; r < i && /[a-zA-Z0-9_]/.test(e[r]);) a += e[r], r++;
|
|
889
|
+
if (t && t.has(a)) {
|
|
890
|
+
let e = t.get(a);
|
|
891
|
+
n.push({
|
|
892
|
+
type: "NUMBER",
|
|
893
|
+
value: String(e),
|
|
894
|
+
numericValue: e
|
|
895
|
+
});
|
|
896
|
+
} else n.push({
|
|
574
897
|
type: "IDENT",
|
|
575
|
-
value:
|
|
898
|
+
value: a
|
|
576
899
|
});
|
|
577
|
-
} else throw Error(`Unexpected character '${
|
|
900
|
+
} else throw Error(`Unexpected character '${a}' at position ${r} in: "${e}"`);
|
|
578
901
|
}
|
|
579
|
-
return
|
|
580
|
-
}
|
|
581
|
-
function k(e, t) {
|
|
582
|
-
return e instanceof S ? e.add(t) : t instanceof S ? t.add(e) : e.add(t);
|
|
902
|
+
return n;
|
|
583
903
|
}
|
|
584
|
-
|
|
585
|
-
return e instanceof S ? e.sub(t) : t instanceof S ? t.neg().add(e) : e.sub(t);
|
|
586
|
-
}
|
|
587
|
-
function A(e, t) {
|
|
588
|
-
let n = e instanceof S ? e.quadTerms : /* @__PURE__ */ new Map(), r = t instanceof S ? t.quadTerms : /* @__PURE__ */ new Map(), i = e instanceof S ? e.linearTerms : e.terms, a = t instanceof S ? t.linearTerms : t.terms;
|
|
589
|
-
if (n.size > 0 && (r.size > 0 || a.size > 0) || r.size > 0 && (n.size > 0 || i.size > 0)) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
590
|
-
if (n.size === 0 && i.size === 0) return t.mul(e.constant);
|
|
591
|
-
if (r.size === 0 && a.size === 0) return e.mul(t.constant);
|
|
592
|
-
let o = new S();
|
|
593
|
-
if (o.constant = e.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [e, n] of i) o.linearTerms.set(e, (o.linearTerms.get(e) || 0) + n * t.constant);
|
|
594
|
-
if (Math.abs(e.constant) >= 1e-12) for (let [t, n] of a) o.linearTerms.set(t, (o.linearTerms.get(t) || 0) + n * e.constant);
|
|
595
|
-
for (let [e, t] of i) for (let [n, r] of a) o = o.add(S.fromProduct(e, n, t * r));
|
|
596
|
-
return o;
|
|
597
|
-
}
|
|
598
|
-
var j = class {
|
|
904
|
+
var de = class {
|
|
599
905
|
tokens;
|
|
600
906
|
pos = 0;
|
|
601
907
|
resolver;
|
|
@@ -616,28 +922,20 @@ var j = class {
|
|
|
616
922
|
for (; this.pos < this.tokens.length;) {
|
|
617
923
|
let t = this.peek();
|
|
618
924
|
if (!t) break;
|
|
619
|
-
if (t.type === "PLUS") this.consume(), e =
|
|
620
|
-
else if (t.type === "MINUS") this.consume(), e =
|
|
925
|
+
if (t.type === "PLUS") this.consume(), e = e.add(this.parseTerm());
|
|
926
|
+
else if (t.type === "MINUS") this.consume(), e = e.sub(this.parseTerm());
|
|
621
927
|
else break;
|
|
622
928
|
}
|
|
623
|
-
return e instanceof
|
|
929
|
+
return e instanceof x && e.quadTerms.size === 0 ? new S(e.linearTerms, e.constant) : e;
|
|
624
930
|
}
|
|
625
931
|
parseTerm() {
|
|
626
932
|
let e = this.parseFactor();
|
|
627
933
|
for (; this.pos < this.tokens.length;) {
|
|
628
934
|
let t = this.peek();
|
|
629
935
|
if (!t) break;
|
|
630
|
-
if (t.type === "STAR")
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
e = A(e, t);
|
|
634
|
-
} else if (t.type === "SLASH") {
|
|
635
|
-
this.consume();
|
|
636
|
-
let t = this.parseFactor(), n = t instanceof S ? t.linearTerms : t.terms, r = t instanceof S ? t.quadTerms.size : 0;
|
|
637
|
-
if (n.size > 0 || r > 0) throw Error("Cannot divide by variable in expression");
|
|
638
|
-
if (Math.abs(t.constant) < 1e-12) throw Error("Division by zero in expression");
|
|
639
|
-
e = e.div(t.constant);
|
|
640
|
-
} else break;
|
|
936
|
+
if (t.type === "STAR") this.consume(), e = e.mul(this.parseFactor());
|
|
937
|
+
else if (t.type === "SLASH") this.consume(), e = e.div(this.parseFactor());
|
|
938
|
+
else break;
|
|
641
939
|
}
|
|
642
940
|
return e;
|
|
643
941
|
}
|
|
@@ -649,20 +947,20 @@ var j = class {
|
|
|
649
947
|
let t;
|
|
650
948
|
if (e.type === "NUMBER") {
|
|
651
949
|
this.consume();
|
|
652
|
-
let n =
|
|
950
|
+
let n = e.numericValue ?? Number(e.value);
|
|
653
951
|
if (this.peek()?.type === "IDENT" || this.peek()?.type === "LPAREN") {
|
|
654
952
|
let e;
|
|
655
953
|
if (this.peek()?.type === "IDENT") {
|
|
656
954
|
let t = this.consume(), n = this.resolve(t.value);
|
|
657
|
-
e = n instanceof
|
|
955
|
+
e = n instanceof N || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new S(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
|
|
658
956
|
} else this.consume("LPAREN"), e = this.parseExpression(), this.consume("RPAREN");
|
|
659
957
|
return this.applyPower(e).mul(n);
|
|
660
958
|
}
|
|
661
|
-
t = new
|
|
959
|
+
t = new S(/* @__PURE__ */ new Map(), n);
|
|
662
960
|
} else if (e.type === "IDENT") {
|
|
663
961
|
this.consume();
|
|
664
962
|
let n = this.resolve(e.value);
|
|
665
|
-
t = n instanceof
|
|
963
|
+
t = n instanceof N || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new S(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
|
|
666
964
|
} else if (e.type === "LPAREN") this.consume("LPAREN"), t = this.parseExpression(), this.consume("RPAREN");
|
|
667
965
|
else throw Error(`Unexpected token '${e.value}' in expression`);
|
|
668
966
|
return this.applyPower(t);
|
|
@@ -672,24 +970,27 @@ var j = class {
|
|
|
672
970
|
let t = [];
|
|
673
971
|
for (; this.peek()?.type === "CARET";) {
|
|
674
972
|
this.consume();
|
|
675
|
-
let e = this.
|
|
676
|
-
|
|
677
|
-
this.
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
973
|
+
let e = this.tokens[this.pos]?.type === "LPAREN" && this.tokens[this.pos + 1]?.type === "NUMBER" && this.tokens[this.pos + 2]?.type === "RPAREN";
|
|
974
|
+
e && this.consume("LPAREN");
|
|
975
|
+
let n = this.peek();
|
|
976
|
+
if (!n || n.type !== "NUMBER") throw Error("Exponent must be a non-negative integer number");
|
|
977
|
+
this.consume(), e && this.consume("RPAREN");
|
|
978
|
+
let r = n.numericValue ?? Number(n.value);
|
|
979
|
+
if (!Number.isInteger(r) || r < 0) throw Error("Exponent must be a non-negative integer");
|
|
980
|
+
t.push(r);
|
|
681
981
|
}
|
|
682
982
|
let n = t[t.length - 1];
|
|
683
983
|
for (let e = t.length - 2; e >= 0; e--) n = t[e] ** +n;
|
|
684
984
|
if (!Number.isFinite(n) || n < 0) throw Error("Exponent creates an invalid or out-of-range power");
|
|
685
|
-
let r = e instanceof
|
|
985
|
+
let r = e instanceof x, i = r ? e.quadTerms.size : 0, a = r ? e.linearTerms.size : e.terms.size;
|
|
686
986
|
if (i === 0 && a === 0) {
|
|
687
987
|
let t = e.constant ** +n;
|
|
688
|
-
|
|
988
|
+
if (e.constant !== 0 && n > 0 && t === 0) throw Error("Constant exponentiation underflows to zero.");
|
|
989
|
+
return new S(/* @__PURE__ */ new Map(), t);
|
|
689
990
|
}
|
|
690
|
-
if (n === 0) return new
|
|
991
|
+
if (n === 0) return new S(/* @__PURE__ */ new Map(), 1);
|
|
691
992
|
if (n === 1) return e;
|
|
692
|
-
if (n === 2) return
|
|
993
|
+
if (n === 2) return e.mul(e);
|
|
693
994
|
throw Error(`Exponent ${n} creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)`);
|
|
694
995
|
}
|
|
695
996
|
getRemainingToken() {
|
|
@@ -701,158 +1002,220 @@ var j = class {
|
|
|
701
1002
|
return t;
|
|
702
1003
|
}
|
|
703
1004
|
};
|
|
704
|
-
function
|
|
705
|
-
let
|
|
706
|
-
if (
|
|
707
|
-
return
|
|
708
|
-
}
|
|
709
|
-
function
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
if (
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
1005
|
+
function P(e, t, n) {
|
|
1006
|
+
let r = new de(ue(e, n), t), i = r.parseExpression(), a = r.getRemainingToken();
|
|
1007
|
+
if (a) throw Error(`Unexpected token '${a.value}' after expression in "${e}"`);
|
|
1008
|
+
return F(i), i;
|
|
1009
|
+
}
|
|
1010
|
+
function fe(e, t) {
|
|
1011
|
+
return P(e, t);
|
|
1012
|
+
}
|
|
1013
|
+
function pe(e, t, n, r) {
|
|
1014
|
+
let i = e.match(/(<=|>=|==|=<|=>|=)/);
|
|
1015
|
+
if (!i) throw Error(`Constraint must contain a comparison operator (<=, >=, ==, =): "${e}"`);
|
|
1016
|
+
let a = i[0], o = i.index, s = e.substring(0, o).trim(), c = e.substring(o + a.length).trim(), l;
|
|
1017
|
+
if (a === "<=" || a === "=<") l = "<=";
|
|
1018
|
+
else if (a === ">=" || a === "=>") l = ">=";
|
|
1019
|
+
else if (a === "==" || a === "=") l = "==";
|
|
1020
|
+
else throw Error(`Unsupported operator "${a}"`);
|
|
1021
|
+
let u = P(s, t, r), d = P(c, t, r);
|
|
1022
|
+
if (u instanceof x && u.quadTerms.size > 0 || d instanceof x && d.quadTerms.size > 0) throw Error("Quadratic constraints are not supported (only linear constraints are allowed in MILP/LP/QP)");
|
|
1023
|
+
let f = u instanceof x ? new S(u.linearTerms, u.constant) : u, p = d instanceof x ? new S(d.linearTerms, d.constant) : d, m;
|
|
1024
|
+
if (m = l === "<=" ? f.le(p, n) : l === ">=" ? f.ge(p, n) : f.eq(p, n), F(m.lhs), !Number.isFinite(m.rhs)) throw Error(`Invalid non-finite right-hand side "${m.rhs}" in constraint.`);
|
|
1025
|
+
return m;
|
|
1026
|
+
}
|
|
1027
|
+
function me(e, t, n) {
|
|
1028
|
+
return pe(e, t, n);
|
|
1029
|
+
}
|
|
1030
|
+
function he(e) {
|
|
1031
|
+
return e instanceof N || e instanceof S || e instanceof x ? !0 : typeof e != "object" || !e ? !1 : "terms" in e && e.terms instanceof Map || "quadTerms" in e && e.quadTerms instanceof Map || "id" in e && "name" in e && "lb" in e && "ub" in e && "type" in e && typeof e.mul == "function";
|
|
1032
|
+
}
|
|
1033
|
+
function F(e) {
|
|
1034
|
+
if ("constant" in e && !Number.isFinite(e.constant)) throw Error(`Invalid non-finite constant "${e.constant}" in expression.`);
|
|
1035
|
+
if ("terms" in e && e.terms instanceof Map) {
|
|
1036
|
+
for (let [, t] of e.terms) if (!Number.isFinite(t)) throw Error(`Invalid non-finite coefficient "${t}" in expression.`);
|
|
1037
|
+
}
|
|
1038
|
+
if ("linearTerms" in e && e.linearTerms instanceof Map) {
|
|
1039
|
+
for (let [, t] of e.linearTerms) if (!Number.isFinite(t)) throw Error(`Invalid non-finite coefficient "${t}" in expression.`);
|
|
1040
|
+
}
|
|
1041
|
+
if ("quadTerms" in e && e.quadTerms instanceof Map) {
|
|
1042
|
+
for (let [, t] of e.quadTerms) if (!Number.isFinite(t.coeff)) throw Error(`Invalid non-finite quadratic coefficient "${t.coeff}" in expression.`);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
function ge(e) {
|
|
1046
|
+
return e instanceof v || typeof e == "object" && !!e && "sense" in e && "lhs" in e && "rhs" in e;
|
|
1047
|
+
}
|
|
1048
|
+
function _e(e, t) {
|
|
1049
|
+
let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), i = e.join(""), a = "__washi_";
|
|
1050
|
+
for (; i.includes(a);) a += "_";
|
|
1051
|
+
let o = "";
|
|
1052
|
+
for (let i = 0; i < e.length; i++) if (o += e[i], i < t.length) {
|
|
725
1053
|
let e = t[i];
|
|
726
|
-
if (typeof e == "number")
|
|
727
|
-
|
|
728
|
-
let t =
|
|
729
|
-
|
|
730
|
-
}
|
|
1054
|
+
if (typeof e == "number") {
|
|
1055
|
+
if (!Number.isFinite(e)) throw Error(`Invalid numeric value "${e}" in template expression: interpolated numbers must be finite.`);
|
|
1056
|
+
let t = `${a}num_${i}__`;
|
|
1057
|
+
r.set(t, e), o += `(${t})`;
|
|
1058
|
+
} else if (ge(e)) throw Error("Cannot interpolate a constraint comparison (<=, >=, ==) inside a template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
1059
|
+
else if (he(e)) {
|
|
1060
|
+
F(e);
|
|
1061
|
+
let t = `${a}ph_${i}__`;
|
|
1062
|
+
n.set(t, e), o += ` ${t} `;
|
|
1063
|
+
} else throw Error("Unsupported interpolation value in template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
731
1064
|
}
|
|
732
1065
|
return {
|
|
733
|
-
fullText:
|
|
734
|
-
resolver: (e) => n.get(e)
|
|
1066
|
+
fullText: o,
|
|
1067
|
+
resolver: (e) => n.get(e),
|
|
1068
|
+
numberMap: r
|
|
735
1069
|
};
|
|
736
1070
|
}
|
|
737
|
-
function
|
|
738
|
-
let { fullText: n, resolver: r } =
|
|
739
|
-
return
|
|
740
|
-
}
|
|
741
|
-
function I(e, ...t) {
|
|
742
|
-
let { fullText: n, resolver: r } = P(e, t);
|
|
743
|
-
return /(<=|>=|==|=<|=>|=)/.test(n) ? N(n, r) : M(n, r);
|
|
1071
|
+
function ve(e, ...t) {
|
|
1072
|
+
let { fullText: n, resolver: r, numberMap: i } = _e(e, t);
|
|
1073
|
+
return /(<=|>=|==|=<|=>|=)/.test(n) ? pe(n, r, void 0, i) : P(n, r, i);
|
|
744
1074
|
}
|
|
745
1075
|
//#endregion
|
|
746
1076
|
//#region src/modeler/lp-writer.ts
|
|
747
|
-
function
|
|
1077
|
+
function I(e) {
|
|
1078
|
+
return typeof e == "object" && !!e && typeof e.lpString == "string" && e.nameToVar instanceof Map && e.nameToConstraint instanceof Map;
|
|
1079
|
+
}
|
|
1080
|
+
function L(e, t = "x", n = 0) {
|
|
748
1081
|
let r = e.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
749
1082
|
return /^[0-9]/.test(r) && (r = `${t}_${r}`), (!r || r.length === 0) && (r = `${t}_${n}`), r;
|
|
750
1083
|
}
|
|
751
|
-
function
|
|
752
|
-
let
|
|
753
|
-
for (let e
|
|
754
|
-
let
|
|
755
|
-
|
|
756
|
-
|
|
1084
|
+
function ye(e) {
|
|
1085
|
+
let t = e.variables || [], n = e.constraints || [], r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
|
|
1086
|
+
for (let e = 0; e < t.length; e++) {
|
|
1087
|
+
let n = t[e];
|
|
1088
|
+
s.set(n, e);
|
|
1089
|
+
let a = L(n.name, "x", e), o = a, l = 1;
|
|
1090
|
+
for (; c.has(o);) o = `${a}_${l++}`;
|
|
1091
|
+
c.add(o), i.set(n, o), r.set(o, n);
|
|
1092
|
+
}
|
|
1093
|
+
let l = /* @__PURE__ */ new Set();
|
|
1094
|
+
for (let e = 0; e < n.length; e++) {
|
|
1095
|
+
let t = n[e], r = L(t.name, "c", e + 1), i = r, s = 1;
|
|
1096
|
+
for (; l.has(i);) i = `${r}_${s++}`;
|
|
1097
|
+
l.add(i), o.set(t, i), a.set(i, t);
|
|
757
1098
|
}
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
let e =
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
1099
|
+
return {
|
|
1100
|
+
nameToVar: r,
|
|
1101
|
+
varToName: i,
|
|
1102
|
+
nameToConstraint: a,
|
|
1103
|
+
constraintToName: o,
|
|
1104
|
+
constrToName: o,
|
|
1105
|
+
varOrder: s
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1108
|
+
function R(e) {
|
|
1109
|
+
let { sense: t, objective: n, constraints: r, variables: i } = e, { nameToVar: a, varToName: o, nameToConstraint: s, constrToName: c, varOrder: l } = ye(e), u = [];
|
|
1110
|
+
u.push(t && t.toLowerCase() === "maximize" ? "Maximize" : "Minimize");
|
|
1111
|
+
let d = [], f = !0, p = n instanceof x ? n.linearTerms : n.terms;
|
|
1112
|
+
if (p) for (let [e, t] of p) {
|
|
1113
|
+
if (t === 0) continue;
|
|
1114
|
+
let n = o.get(e), r = t >= 0 ? f ? "" : "+ " : "- ", i = Math.abs(t), a = i === 1 ? "" : `${i} `;
|
|
1115
|
+
d.push(`${r}${a}${n}`), f = !1;
|
|
1116
|
+
}
|
|
1117
|
+
if (n instanceof x && n.quadTerms.size > 0) {
|
|
1118
|
+
let e = [], t = !0, r = Array.from(n.quadTerms.values()).filter((e) => e.coeff !== 0).map((e) => {
|
|
1119
|
+
let t = l.get(e.var1) ?? e.var1.id, n = l.get(e.var2) ?? e.var2.id, [r, i, a, o] = t <= n ? [
|
|
1120
|
+
e.var1,
|
|
1121
|
+
e.var2,
|
|
1122
|
+
t,
|
|
1123
|
+
n
|
|
1124
|
+
] : [
|
|
1125
|
+
e.var2,
|
|
1126
|
+
e.var1,
|
|
1127
|
+
n,
|
|
1128
|
+
t
|
|
1129
|
+
];
|
|
1130
|
+
return {
|
|
1131
|
+
firstVar: r,
|
|
1132
|
+
secondVar: i,
|
|
1133
|
+
firstIdx: a,
|
|
1134
|
+
secondIdx: o,
|
|
1135
|
+
coeff: e.coeff
|
|
1136
|
+
};
|
|
1137
|
+
}).sort((e, t) => e.firstIdx - t.firstIdx || e.secondIdx - t.secondIdx);
|
|
1138
|
+
for (let n of r) {
|
|
1139
|
+
let r = 2 * n.coeff, i = r >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(r), s = a === 1 ? "" : `${a} `, c = o.get(n.firstVar), l = o.get(n.secondVar);
|
|
1140
|
+
n.firstVar === n.secondVar ? e.push(`${i}${s}${c} ^ 2`) : e.push(`${i}${s}${c} * ${l}`), t = !1;
|
|
778
1141
|
}
|
|
779
1142
|
if (e.length > 0) {
|
|
780
1143
|
let t = `[ ${e.join(" ")} ] / 2`;
|
|
781
|
-
|
|
1144
|
+
d.length > 0 ? d.push("+", t) : d.push(t);
|
|
782
1145
|
}
|
|
783
1146
|
}
|
|
784
|
-
let
|
|
785
|
-
|
|
1147
|
+
let m = d.length > 0 ? d.join(" ") : "0";
|
|
1148
|
+
u.push(` obj: ${m}`), u.push("Subject To");
|
|
786
1149
|
for (let e of r) {
|
|
787
|
-
let t =
|
|
1150
|
+
let t = c.get(e), n = [], r = !0;
|
|
788
1151
|
for (let [t, i] of e.lhs.terms) {
|
|
789
|
-
if (
|
|
1152
|
+
if (i === 0) continue;
|
|
790
1153
|
let e = o.get(t), a = i >= 0 ? r ? "" : "+ " : "- ", s = Math.abs(i), c = s === 1 ? "" : `${s} `;
|
|
791
1154
|
n.push(`${a}${c}${e}`), r = !1;
|
|
792
1155
|
}
|
|
793
1156
|
let i = n.length > 0 ? n.join(" ") : "0", a = e.sense === "==" ? "=" : e.sense;
|
|
794
|
-
|
|
1157
|
+
u.push(` ${t}: ${i} ${a} ${e.rhs}`);
|
|
795
1158
|
}
|
|
796
|
-
|
|
797
|
-
let
|
|
1159
|
+
u.push("Bounds");
|
|
1160
|
+
let h = [], g = [];
|
|
798
1161
|
for (let e of i) {
|
|
799
1162
|
let t = o.get(e);
|
|
800
1163
|
if (e.type === "Binary") {
|
|
801
|
-
|
|
1164
|
+
g.push(t);
|
|
802
1165
|
continue;
|
|
803
1166
|
}
|
|
804
|
-
e.type === "Integer" &&
|
|
1167
|
+
e.type === "Integer" && h.push(t);
|
|
805
1168
|
let n = e.lb === -Infinity, r = e.ub === Infinity;
|
|
806
|
-
n && r ?
|
|
1169
|
+
n && r ? u.push(` ${t} free`) : n && !r ? u.push(` -infinity <= ${t} <= ${e.ub}`) : !n && r ? (e.lb !== 0 || e.initialValue !== void 0) && u.push(` ${t} >= ${e.lb}`) : u.push(` ${e.lb} <= ${t} <= ${e.ub}`);
|
|
807
1170
|
}
|
|
808
|
-
if (
|
|
809
|
-
|
|
810
|
-
for (let e = 0; e <
|
|
1171
|
+
if (h.length > 0) {
|
|
1172
|
+
u.push("Generals");
|
|
1173
|
+
for (let e = 0; e < h.length; e += 10) u.push(" " + h.slice(e, e + 10).join(" "));
|
|
811
1174
|
}
|
|
812
|
-
if (
|
|
813
|
-
|
|
814
|
-
for (let e = 0; e <
|
|
1175
|
+
if (g.length > 0) {
|
|
1176
|
+
u.push("Binary");
|
|
1177
|
+
for (let e = 0; e < g.length; e += 10) u.push(" " + g.slice(e, e + 10).join(" "));
|
|
815
1178
|
}
|
|
816
|
-
return
|
|
817
|
-
lpString:
|
|
1179
|
+
return u.push("End"), {
|
|
1180
|
+
lpString: u.join("\n") + "\n",
|
|
818
1181
|
nameToVar: a,
|
|
819
1182
|
nameToConstraint: s
|
|
820
1183
|
};
|
|
821
1184
|
}
|
|
822
1185
|
//#endregion
|
|
823
1186
|
//#region src/modeler/solvers/registry.ts
|
|
824
|
-
var
|
|
825
|
-
|
|
826
|
-
var
|
|
827
|
-
function
|
|
828
|
-
|
|
1187
|
+
var be = Symbol.for("washi.solverRegistry"), xe = Symbol.for("washi.defaultSolverFactory"), z = globalThis;
|
|
1188
|
+
z[be] || (z[be] = /* @__PURE__ */ new Map());
|
|
1189
|
+
var B = z[be];
|
|
1190
|
+
function V(e, t) {
|
|
1191
|
+
B.set(e.toLowerCase(), t);
|
|
829
1192
|
}
|
|
830
|
-
function
|
|
1193
|
+
function Se(e) {
|
|
831
1194
|
if (typeof e == "string") {
|
|
832
|
-
let t =
|
|
1195
|
+
let t = B.get(e.toLowerCase());
|
|
833
1196
|
if (!t) throw Error(`Solver '${e}' is not registered.`);
|
|
834
|
-
|
|
835
|
-
} else
|
|
1197
|
+
z[xe] = t;
|
|
1198
|
+
} else z[xe] = typeof e == "function" ? e : () => e;
|
|
836
1199
|
}
|
|
837
|
-
function
|
|
1200
|
+
function H(e, t) {
|
|
838
1201
|
if (!e) {
|
|
839
|
-
let e =
|
|
840
|
-
if (!e) throw Error(`No default solver available. Available solvers: ${
|
|
1202
|
+
let e = z[xe] || B.get("highs");
|
|
1203
|
+
if (!e) throw Error(`No default solver available. Available solvers: ${U().join(", ")}`);
|
|
841
1204
|
return e(t);
|
|
842
1205
|
}
|
|
843
1206
|
if (typeof e == "string") {
|
|
844
|
-
let n = e.toLowerCase(), r =
|
|
845
|
-
if (!r) throw Error(n === "glpk" ? `Solver 'glpk' not found. Available solvers: ${
|
|
1207
|
+
let n = e.toLowerCase(), r = B.get(n);
|
|
1208
|
+
if (!r) throw Error(n === "glpk" ? `Solver 'glpk' not found. Available solvers: ${U().join(", ")}. Please import '@ohtaman/washi/solvers/glpk' before selecting this solver.` : n === "z3" ? `Solver 'z3' not found. Available solvers: ${U().join(", ")}. Please import '@ohtaman/washi/solvers/z3' before selecting this solver.` : `Solver '${e}' not found. Available solvers: ${U().join(", ")}`);
|
|
846
1209
|
return r(t);
|
|
847
1210
|
}
|
|
848
1211
|
return e;
|
|
849
1212
|
}
|
|
850
|
-
function
|
|
851
|
-
return Array.from(
|
|
1213
|
+
function U() {
|
|
1214
|
+
return Array.from(B.keys());
|
|
852
1215
|
}
|
|
853
1216
|
//#endregion
|
|
854
1217
|
//#region \0washi-browser-worker-factory
|
|
855
|
-
function
|
|
1218
|
+
function Ce() {
|
|
856
1219
|
let e = r("highs-worker.js");
|
|
857
1220
|
if (new URL(e).origin === window.location.origin) return new Worker(e, { type: "module" });
|
|
858
1221
|
let t = URL.createObjectURL(new Blob(["import " + JSON.stringify(e) + ";"], { type: "text/javascript" }));
|
|
@@ -865,73 +1228,198 @@ function q() {
|
|
|
865
1228
|
}
|
|
866
1229
|
//#endregion
|
|
867
1230
|
//#region src/modeler/solvers/highs/worker-client.ts
|
|
868
|
-
var
|
|
869
|
-
function
|
|
1231
|
+
var W = null, we = 0, G = /* @__PURE__ */ new Map();
|
|
1232
|
+
function K(e, t) {
|
|
1233
|
+
return e ? {
|
|
1234
|
+
Status: "Interrupted",
|
|
1235
|
+
StatusCode: 17,
|
|
1236
|
+
HasPrimalSolution: !0,
|
|
1237
|
+
IsMip: !0,
|
|
1238
|
+
ObjectiveValue: e.objectiveValue,
|
|
1239
|
+
ObjectiveOffsetApplied: !0,
|
|
1240
|
+
...t?.objectiveBound === void 0 ? e.mipDualBound === void 0 ? {} : { MipDualBound: e.mipDualBound } : { MipDualBound: t.objectiveBound },
|
|
1241
|
+
...t?.relGap === void 0 ? e.mipGap === void 0 ? {} : { MipGap: e.mipGap } : { MipGap: t.relGap },
|
|
1242
|
+
Columns: e.columns,
|
|
1243
|
+
Rows: []
|
|
1244
|
+
} : {
|
|
1245
|
+
Status: "Interrupted",
|
|
1246
|
+
StatusCode: 17,
|
|
1247
|
+
HasPrimalSolution: !1,
|
|
1248
|
+
ObjectiveValue: NaN,
|
|
1249
|
+
ObjectiveOffsetApplied: !0,
|
|
1250
|
+
...t?.objectiveBound === void 0 ? {} : { MipDualBound: t.objectiveBound },
|
|
1251
|
+
...t?.relGap === void 0 ? {} : { MipGap: t.relGap },
|
|
1252
|
+
Columns: {},
|
|
1253
|
+
Rows: []
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
1256
|
+
function q(e) {
|
|
1257
|
+
let t = G.values().next().value;
|
|
1258
|
+
if (t && !t.dispatched) {
|
|
1259
|
+
t.dispatched = !0;
|
|
1260
|
+
try {
|
|
1261
|
+
e.postMessage({
|
|
1262
|
+
type: "SOLVE",
|
|
1263
|
+
id: t.id,
|
|
1264
|
+
lpString: t.lpString,
|
|
1265
|
+
options: t.workerOptions,
|
|
1266
|
+
...t.reportProgress ? { reportProgress: !0 } : {}
|
|
1267
|
+
});
|
|
1268
|
+
} catch (n) {
|
|
1269
|
+
G.delete(t.id), t.cleanupAbort?.(), t.reject(n), q(e);
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
function Te() {
|
|
1274
|
+
let e = W;
|
|
1275
|
+
e && (W = null, e.terminate());
|
|
1276
|
+
for (let e of G.values()) e.dispatched = !1;
|
|
1277
|
+
if (G.size > 0) {
|
|
1278
|
+
let e = Ee();
|
|
1279
|
+
if (e) q(e);
|
|
1280
|
+
else {
|
|
1281
|
+
let e = /* @__PURE__ */ Error("[WaSHI] Failed to recreate HiGHS Worker after interruption.");
|
|
1282
|
+
for (let t of Array.from(G.values())) G.delete(t.id), t.cleanupAbort?.(), t.reject(e);
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
function Ee() {
|
|
870
1287
|
if (typeof window > "u" || typeof Worker > "u") return null;
|
|
871
|
-
if (!
|
|
872
|
-
|
|
873
|
-
let e =
|
|
874
|
-
|
|
875
|
-
let { type:
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
1288
|
+
if (!W) try {
|
|
1289
|
+
W = Ce();
|
|
1290
|
+
let e = W;
|
|
1291
|
+
W.onmessage = (t) => {
|
|
1292
|
+
let { type: n, id: r, result: i, runTime: a, error: o, progress: s, incumbent: c } = t.data, l = G.get(r);
|
|
1293
|
+
if (l) {
|
|
1294
|
+
if (n === "SOLVE_PROGRESS") {
|
|
1295
|
+
if (s) {
|
|
1296
|
+
l.lastProgress = s;
|
|
1297
|
+
try {
|
|
1298
|
+
l.onProgress?.(s);
|
|
1299
|
+
} catch (e) {
|
|
1300
|
+
let t = G.get(r);
|
|
1301
|
+
if (t) {
|
|
1302
|
+
let n = G.keys().next().value;
|
|
1303
|
+
G.delete(r), t.cleanupAbort?.(), n === r && Te(), t.reject(e);
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
return;
|
|
1308
|
+
}
|
|
1309
|
+
if (n === "SOLVE_INCUMBENT") {
|
|
1310
|
+
c && (l.lastIncumbent = c);
|
|
1311
|
+
return;
|
|
1312
|
+
}
|
|
1313
|
+
G.delete(r), l.cleanupAbort?.(), n === "SOLVE_SUCCESS" ? l.resolve({
|
|
1314
|
+
result: i,
|
|
1315
|
+
runTime: a
|
|
1316
|
+
}) : l.reject(Error(o || "Worker solve failed")), W === e && q(e);
|
|
1317
|
+
}
|
|
880
1318
|
};
|
|
881
1319
|
let t = (t) => {
|
|
882
|
-
if (
|
|
883
|
-
|
|
884
|
-
for (let e of
|
|
885
|
-
|
|
1320
|
+
if (W === e) {
|
|
1321
|
+
W = null, e.terminate();
|
|
1322
|
+
for (let e of G.values()) e.cleanupAbort?.(), e.reject(t);
|
|
1323
|
+
G.clear();
|
|
886
1324
|
}
|
|
887
1325
|
};
|
|
888
|
-
|
|
1326
|
+
W.onerror = (e) => t(/* @__PURE__ */ Error(`[WaSHI] HiGHS Worker failed to load or execute. Check Worker assets, CORS and CSP. ${e?.message || ""}`)), W.onmessageerror = () => t(/* @__PURE__ */ Error("[WaSHI] Could not deserialize the HiGHS Worker response."));
|
|
889
1327
|
} catch {
|
|
890
|
-
|
|
891
|
-
}
|
|
892
|
-
return
|
|
893
|
-
}
|
|
894
|
-
async function
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
1328
|
+
W = null;
|
|
1329
|
+
}
|
|
1330
|
+
return W;
|
|
1331
|
+
}
|
|
1332
|
+
async function De(t, n = {}) {
|
|
1333
|
+
if (n.signal?.aborted) return {
|
|
1334
|
+
result: K(),
|
|
1335
|
+
runTime: 0
|
|
1336
|
+
};
|
|
1337
|
+
let r = await i(n.wasmUrl);
|
|
1338
|
+
if (n.signal?.aborted) return {
|
|
1339
|
+
result: K(),
|
|
1340
|
+
runTime: 0
|
|
1341
|
+
};
|
|
1342
|
+
let a = n.useWorker ?? typeof window < "u" ? Ee() : null;
|
|
1343
|
+
if (!a) return e(t, n);
|
|
1344
|
+
let { signal: o, onProgress: s, ...c } = n, l = {};
|
|
1345
|
+
for (let [e, t] of Object.entries(c)) typeof t != "function" && (l[e] = t);
|
|
1346
|
+
l.wasmUrl = r;
|
|
1347
|
+
let u = !!(s || o), d = `req_${++we}`, f = performance.now();
|
|
1348
|
+
return new Promise((e, n) => {
|
|
1349
|
+
let r = {
|
|
1350
|
+
id: d,
|
|
1351
|
+
lpString: t,
|
|
1352
|
+
workerOptions: l,
|
|
1353
|
+
reportProgress: u,
|
|
1354
|
+
startTime: f,
|
|
1355
|
+
onProgress: s,
|
|
1356
|
+
resolve: e,
|
|
904
1357
|
reject: n
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
1358
|
+
};
|
|
1359
|
+
if (o) {
|
|
1360
|
+
let e = () => {
|
|
1361
|
+
let e = G.get(d);
|
|
1362
|
+
if (!e) return;
|
|
1363
|
+
let t = G.keys().next().value;
|
|
1364
|
+
G.delete(d), e.cleanupAbort?.(), t === d && Te();
|
|
1365
|
+
let n = (performance.now() - e.startTime) / 1e3;
|
|
1366
|
+
e.resolve({
|
|
1367
|
+
result: K(e.lastIncumbent, e.lastProgress),
|
|
1368
|
+
runTime: n
|
|
1369
|
+
});
|
|
1370
|
+
};
|
|
1371
|
+
o.addEventListener("abort", e, { once: !0 }), r.cleanupAbort = () => o.removeEventListener("abort", e);
|
|
915
1372
|
}
|
|
1373
|
+
G.set(d, r), q(a);
|
|
916
1374
|
});
|
|
917
1375
|
}
|
|
918
1376
|
//#endregion
|
|
919
1377
|
//#region src/modeler/solvers/highs/solver.ts
|
|
920
|
-
function
|
|
1378
|
+
function Oe(e, t) {
|
|
1379
|
+
if (typeof t == "number") switch (t) {
|
|
1380
|
+
case 0: return "NotSolved";
|
|
1381
|
+
case 1:
|
|
1382
|
+
case 2:
|
|
1383
|
+
case 3:
|
|
1384
|
+
case 4:
|
|
1385
|
+
case 5: return "Error";
|
|
1386
|
+
case 6: return "Unknown";
|
|
1387
|
+
case 7: return "Optimal";
|
|
1388
|
+
case 8: return "Infeasible";
|
|
1389
|
+
case 9: return "InfeasibleOrUnbounded";
|
|
1390
|
+
case 10: return "Unbounded";
|
|
1391
|
+
case 11: return "ObjectiveBound";
|
|
1392
|
+
case 12: return "ObjectiveTarget";
|
|
1393
|
+
case 13: return "TimeLimit";
|
|
1394
|
+
case 14: return "IterationLimit";
|
|
1395
|
+
case 15: return "Unknown";
|
|
1396
|
+
case 16: return "SolutionLimit";
|
|
1397
|
+
case 17: return "Interrupted";
|
|
1398
|
+
case 18: return "MemoryLimit";
|
|
1399
|
+
}
|
|
921
1400
|
if (typeof e != "string") return "Unknown";
|
|
922
|
-
let
|
|
923
|
-
if (!
|
|
924
|
-
switch (
|
|
1401
|
+
let n = e.trim();
|
|
1402
|
+
if (!n) return "Unknown";
|
|
1403
|
+
switch (n) {
|
|
925
1404
|
case "Optimal": return "Optimal";
|
|
926
1405
|
case "Infeasible": return "Infeasible";
|
|
927
1406
|
case "Unbounded": return "Unbounded";
|
|
928
|
-
case "Primal infeasible or unbounded":
|
|
1407
|
+
case "Primal infeasible or unbounded":
|
|
1408
|
+
case "InfeasibleOrUnbounded": return "InfeasibleOrUnbounded";
|
|
929
1409
|
case "Time limit reached":
|
|
930
1410
|
case "TimeLimit": return "TimeLimit";
|
|
931
1411
|
case "Iteration limit reached":
|
|
932
1412
|
case "IterationLimit": return "IterationLimit";
|
|
1413
|
+
case "Solution limit reached":
|
|
1414
|
+
case "SolutionLimit": return "SolutionLimit";
|
|
1415
|
+
case "Memory limit reached":
|
|
1416
|
+
case "MemoryLimit": return "MemoryLimit";
|
|
933
1417
|
case "Bound on objective reached":
|
|
1418
|
+
case "ObjectiveBound": return "ObjectiveBound";
|
|
934
1419
|
case "Target for objective reached":
|
|
1420
|
+
case "ObjectiveTarget": return "ObjectiveTarget";
|
|
1421
|
+
case "Interrupted":
|
|
1422
|
+
case "User interrupt": return "Interrupted";
|
|
935
1423
|
case "Feasible": return "Feasible";
|
|
936
1424
|
case "Not Set": return "NotSolved";
|
|
937
1425
|
case "Load error":
|
|
@@ -943,13 +1431,32 @@ function re(e) {
|
|
|
943
1431
|
case "Empty":
|
|
944
1432
|
case "Unknown": return "Unknown";
|
|
945
1433
|
}
|
|
946
|
-
let
|
|
947
|
-
return
|
|
1434
|
+
let r = n.toLowerCase();
|
|
1435
|
+
return r.includes("infeasible") && r.includes("unbounded") ? "InfeasibleOrUnbounded" : r.includes("infeasible") ? "Infeasible" : r.includes("unbounded") ? "Unbounded" : r.includes("time limit") || r.includes("timelimit") ? "TimeLimit" : r.includes("iteration limit") || r.includes("iterationlimit") ? "IterationLimit" : r.includes("solution limit") || r.includes("solutionlimit") ? "SolutionLimit" : r.includes("memory limit") || r.includes("memorylimit") ? "MemoryLimit" : r.includes("bound on objective") ? "ObjectiveBound" : r.includes("target for objective") ? "ObjectiveTarget" : r.includes("interrupt") ? "Interrupted" : r.includes("error") ? "Error" : r === "optimal" ? "Optimal" : "Unknown";
|
|
1436
|
+
}
|
|
1437
|
+
function ke(e, t, n) {
|
|
1438
|
+
switch (Oe(e, t)) {
|
|
1439
|
+
case "Optimal": return "Optimal";
|
|
1440
|
+
case "Infeasible": return "Infeasible";
|
|
1441
|
+
case "Unbounded": return "Unbounded";
|
|
1442
|
+
case "TimeLimit": return "TimeLimit";
|
|
1443
|
+
case "IterationLimit": return "IterationLimit";
|
|
1444
|
+
case "Feasible": return "Feasible";
|
|
1445
|
+
case "ObjectiveBound":
|
|
1446
|
+
case "ObjectiveTarget":
|
|
1447
|
+
case "SolutionLimit": return n === !1 ? "Unknown" : "Feasible";
|
|
1448
|
+
case "MemoryLimit":
|
|
1449
|
+
case "Interrupted": return n ? "Feasible" : "Unknown";
|
|
1450
|
+
case "NotSolved": return "NotSolved";
|
|
1451
|
+
case "Error": return "Error";
|
|
1452
|
+
default: return "Unknown";
|
|
1453
|
+
}
|
|
948
1454
|
}
|
|
949
|
-
var
|
|
1455
|
+
var J = class e {
|
|
950
1456
|
static capabilities = {
|
|
951
1457
|
supportsMIP: !0,
|
|
952
|
-
supportsQP: !0
|
|
1458
|
+
supportsQP: !0,
|
|
1459
|
+
supportsWarmStart: !0
|
|
953
1460
|
};
|
|
954
1461
|
name = "HiGHS";
|
|
955
1462
|
version = "1.15.3";
|
|
@@ -958,121 +1465,750 @@ var Q = class e {
|
|
|
958
1465
|
constructor(e = {}) {
|
|
959
1466
|
this.options = e;
|
|
960
1467
|
}
|
|
961
|
-
async solve(e, t, n = {}) {
|
|
962
|
-
let r = {
|
|
1468
|
+
async solve(e, t = {}, n = {}) {
|
|
1469
|
+
let r = I(t), i = r ? n : t, a = {
|
|
963
1470
|
...this.options,
|
|
964
|
-
...
|
|
965
|
-
},
|
|
966
|
-
|
|
967
|
-
|
|
1471
|
+
...i
|
|
1472
|
+
}, o = e.objective.constant || 0;
|
|
1473
|
+
for (let t of e.variables) A(t);
|
|
1474
|
+
let { lpString: s, nameToVar: c, nameToConstraint: l } = r ? t : R(e), u = Object.create(null), d = !1, f = /* @__PURE__ */ new Set();
|
|
1475
|
+
for (let [e, t] of c.entries()) {
|
|
1476
|
+
f.add(t);
|
|
1477
|
+
let n = ie(t);
|
|
1478
|
+
n !== void 0 && (u[e] = n, d = !0);
|
|
1479
|
+
}
|
|
1480
|
+
for (let t = 0; t < e.variables.length; t++) {
|
|
1481
|
+
let n = e.variables[t];
|
|
1482
|
+
if (!f.has(n)) {
|
|
1483
|
+
let e = ie(n);
|
|
1484
|
+
if (e !== void 0) {
|
|
1485
|
+
let r = L(n.name, "x", t);
|
|
1486
|
+
Object.prototype.hasOwnProperty.call(u, r) || (u[r] = e, d = !0);
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
let p = a;
|
|
1491
|
+
(o !== 0 || d || p.initialValues !== void 0) && (p = {
|
|
1492
|
+
...p,
|
|
1493
|
+
...o === 0 ? {} : { objectiveOffset: o },
|
|
1494
|
+
initialValues: d ? u : void 0
|
|
1495
|
+
});
|
|
1496
|
+
let { result: m, runTime: h } = await De(s, p), g = m?.ObjectiveOffsetApplied ? 0 : o, _ = Oe(m?.Status, m?.StatusCode), v = typeof m?.IsMip == "boolean" ? m.IsMip : e.variables.some((e) => e.type === "Integer" || e.type === "Binary"), y;
|
|
1497
|
+
if (typeof m?.HasPrimalSolution == "boolean") y = m.HasPrimalSolution;
|
|
1498
|
+
else {
|
|
1499
|
+
let e = m?.Columns ? Object.values(m.Columns) : [], t = e.length > 0 && e.some((e) => typeof e?.Primal == "number" && Number.isFinite(e.Primal)), n = typeof m?.ObjectiveValue == "number" && Number.isFinite(m.ObjectiveValue);
|
|
1500
|
+
y = _ === "Infeasible" || _ === "Unbounded" || _ === "InfeasibleOrUnbounded" || _ === "Error" || _ === "NotSolved" ? !1 : _ === "Optimal" || _ === "Feasible" ? n || t : n && (e.length === 0 || t);
|
|
1501
|
+
}
|
|
1502
|
+
let b = ke(m?.Status, m?.StatusCode, y), x = null;
|
|
1503
|
+
y && typeof m?.ObjectiveValue == "number" && Number.isFinite(m.ObjectiveValue) && (x = m.ObjectiveValue + g);
|
|
1504
|
+
let S, C, w;
|
|
1505
|
+
if (typeof m?.MipDualBound == "number" && Number.isFinite(m.MipDualBound) ? S = m.MipDualBound + g : !v && _ === "Optimal" && x !== null && (S = x), x !== null && S !== void 0 && Number.isFinite(S) && (w = Math.abs(x - S)), g !== 0 && v && x !== null && S !== void 0 && w !== void 0) {
|
|
1506
|
+
if (w === 0) C = 0;
|
|
1507
|
+
else if (Math.abs(x) > 0) {
|
|
1508
|
+
let e = w / Math.abs(x);
|
|
1509
|
+
C = Number.isFinite(e) ? e : void 0;
|
|
1510
|
+
} else C = void 0;
|
|
1511
|
+
} else typeof m?.MipGap == "number" && Number.isFinite(m.MipGap) ? C = m.MipGap : v && _ === "Optimal" && y && (w === void 0 || w === 0) && (C = 0);
|
|
1512
|
+
if (!y) return {
|
|
1513
|
+
status: b,
|
|
1514
|
+
terminationStatus: _,
|
|
1515
|
+
hasPrimalSolution: !1,
|
|
968
1516
|
objectiveValue: null,
|
|
1517
|
+
...S === void 0 ? {} : { objectiveBound: S },
|
|
1518
|
+
...C === void 0 ? {} : {
|
|
1519
|
+
relGap: C,
|
|
1520
|
+
mipGap: C
|
|
1521
|
+
},
|
|
1522
|
+
...w === void 0 ? {} : { absGap: w },
|
|
969
1523
|
values: {},
|
|
970
1524
|
reducedCosts: {},
|
|
971
1525
|
duals: {},
|
|
972
1526
|
slacks: {},
|
|
973
|
-
runTime:
|
|
974
|
-
raw:
|
|
1527
|
+
runTime: h,
|
|
1528
|
+
raw: m
|
|
975
1529
|
};
|
|
976
|
-
let
|
|
977
|
-
|
|
978
|
-
|
|
1530
|
+
let T = (e, t, n) => {
|
|
1531
|
+
Object.defineProperty(e, t, {
|
|
1532
|
+
value: n,
|
|
1533
|
+
enumerable: !0,
|
|
1534
|
+
writable: !0,
|
|
1535
|
+
configurable: !0
|
|
1536
|
+
});
|
|
1537
|
+
}, E = {}, D = {}, O = {}, k = {};
|
|
1538
|
+
if (m.Columns) for (let [e, t] of Object.entries(m.Columns)) {
|
|
1539
|
+
let n = c.get(e);
|
|
979
1540
|
if (n) {
|
|
980
|
-
|
|
981
|
-
|
|
1541
|
+
if (typeof t.Primal == "number" && Number.isFinite(t.Primal)) {
|
|
1542
|
+
let e = Math.abs(t.Primal) < 1e-9 ? 0 : t.Primal;
|
|
1543
|
+
T(E, n.name, e);
|
|
1544
|
+
}
|
|
1545
|
+
typeof t.Dual == "number" && Number.isFinite(t.Dual) && T(O, n.name, Math.abs(t.Dual) < 1e-9 ? 0 : t.Dual);
|
|
982
1546
|
}
|
|
983
1547
|
}
|
|
984
|
-
if (
|
|
985
|
-
let e = Array.isArray(
|
|
1548
|
+
if (m.Rows) {
|
|
1549
|
+
let e = Array.isArray(m.Rows) ? m.Rows : Object.values(m.Rows);
|
|
986
1550
|
for (let t of e) {
|
|
987
|
-
let e = t.Name, n =
|
|
988
|
-
if (n && (t.Dual
|
|
1551
|
+
let e = t.Name, n = e ? l.get(e) : void 0;
|
|
1552
|
+
if (n && (typeof t.Dual == "number" && Number.isFinite(t.Dual) && T(D, n.name, Math.abs(t.Dual) < 1e-9 ? 0 : t.Dual), typeof t.Primal == "number" && Number.isFinite(t.Primal))) {
|
|
989
1553
|
let e = n.rhs - t.Primal;
|
|
990
|
-
|
|
1554
|
+
T(k, n.name, Math.abs(e) < 1e-9 ? 0 : e);
|
|
991
1555
|
}
|
|
992
1556
|
}
|
|
993
1557
|
}
|
|
994
1558
|
return {
|
|
995
|
-
status:
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1559
|
+
status: b,
|
|
1560
|
+
terminationStatus: _,
|
|
1561
|
+
hasPrimalSolution: !0,
|
|
1562
|
+
objectiveValue: x,
|
|
1563
|
+
...S === void 0 ? {} : { objectiveBound: S },
|
|
1564
|
+
...C === void 0 ? {} : {
|
|
1565
|
+
relGap: C,
|
|
1566
|
+
mipGap: C
|
|
1567
|
+
},
|
|
1568
|
+
...w === void 0 ? {} : { absGap: w },
|
|
1569
|
+
values: E,
|
|
1570
|
+
reducedCosts: O,
|
|
1571
|
+
duals: D,
|
|
1572
|
+
slacks: k,
|
|
1573
|
+
runTime: h,
|
|
1574
|
+
raw: m
|
|
1003
1575
|
};
|
|
1004
1576
|
}
|
|
1005
|
-
},
|
|
1006
|
-
function
|
|
1007
|
-
|
|
1577
|
+
}, Ae = J;
|
|
1578
|
+
function je() {
|
|
1579
|
+
V("highs", (e) => new J(e)), Se((e) => new J(e));
|
|
1008
1580
|
}
|
|
1009
|
-
|
|
1581
|
+
je();
|
|
1010
1582
|
//#endregion
|
|
1011
1583
|
//#region src/modeler/solvers/mock.ts
|
|
1012
|
-
var
|
|
1584
|
+
var Me = class {
|
|
1013
1585
|
name;
|
|
1014
1586
|
capabilities;
|
|
1015
1587
|
options;
|
|
1016
1588
|
constructor(e = {}) {
|
|
1017
1589
|
this.name = e.name || "MockSolver", this.capabilities = e.capabilities || {
|
|
1018
1590
|
supportsMIP: !0,
|
|
1019
|
-
supportsQP: !0
|
|
1591
|
+
supportsQP: !0,
|
|
1592
|
+
supportsWarmStart: !0
|
|
1020
1593
|
}, this.options = e;
|
|
1021
1594
|
}
|
|
1022
|
-
async solve(e, t, n = {}) {
|
|
1023
|
-
let r = {
|
|
1595
|
+
async solve(e, t = {}, n = {}) {
|
|
1596
|
+
let r = I(t) ? n : t, i = {
|
|
1024
1597
|
...this.options,
|
|
1025
|
-
...
|
|
1598
|
+
...r
|
|
1599
|
+
}, a = !!(i.values && Object.keys(i.values).length > 0 || i.boolValues && Object.keys(i.boolValues).length > 0);
|
|
1600
|
+
if (i.signal?.aborted) return {
|
|
1601
|
+
status: "Unknown",
|
|
1602
|
+
terminationStatus: "Interrupted",
|
|
1603
|
+
hasPrimalSolution: !1,
|
|
1604
|
+
objectiveValue: null,
|
|
1605
|
+
values: {},
|
|
1606
|
+
runTime: 0,
|
|
1607
|
+
raw: { mock: !0 }
|
|
1026
1608
|
};
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1609
|
+
if (i.delayMs && i.delayMs > 0 && (await new Promise((e) => {
|
|
1610
|
+
let t = setTimeout(() => {
|
|
1611
|
+
i.signal?.removeEventListener("abort", n), e();
|
|
1612
|
+
}, i.delayMs), n = () => {
|
|
1613
|
+
clearTimeout(t), e();
|
|
1614
|
+
};
|
|
1615
|
+
i.signal?.addEventListener("abort", n, { once: !0 });
|
|
1616
|
+
}), i.signal?.aborted)) {
|
|
1617
|
+
let e = !!(i.hasPrimalSolution ?? a);
|
|
1618
|
+
return {
|
|
1619
|
+
status: e ? "Feasible" : "Unknown",
|
|
1620
|
+
terminationStatus: "Interrupted",
|
|
1621
|
+
hasPrimalSolution: e,
|
|
1622
|
+
objectiveValue: e ? i.objectiveValue ?? 0 : null,
|
|
1623
|
+
...i.objectiveBound === void 0 ? {} : { objectiveBound: i.objectiveBound },
|
|
1624
|
+
...i.relGap === void 0 ? i.mipGap === void 0 ? {} : {
|
|
1625
|
+
relGap: i.mipGap,
|
|
1626
|
+
mipGap: i.mipGap
|
|
1627
|
+
} : {
|
|
1628
|
+
relGap: i.relGap,
|
|
1629
|
+
mipGap: i.relGap
|
|
1630
|
+
},
|
|
1631
|
+
...i.absGap === void 0 ? {} : { absGap: i.absGap },
|
|
1632
|
+
values: e && i.values || {},
|
|
1633
|
+
...e && i.boolValues !== void 0 ? { boolValues: i.boolValues } : {},
|
|
1634
|
+
runTime: .001,
|
|
1635
|
+
raw: { mock: !0 }
|
|
1636
|
+
};
|
|
1637
|
+
}
|
|
1638
|
+
if (i.onProgress && Array.isArray(i.progressEvents)) for (let e of i.progressEvents) {
|
|
1639
|
+
if (i.signal?.aborted) break;
|
|
1640
|
+
i.onProgress(e);
|
|
1641
|
+
}
|
|
1642
|
+
let o = i.status || "Optimal", s = i.terminationStatus ?? o, c = i.hasPrimalSolution === void 0 ? o === "Optimal" || o === "Feasible" || o === "Sat" || (o === "TimeLimit" || o === "IterationLimit" || s === "Interrupted") && a : i.hasPrimalSolution;
|
|
1643
|
+
if (i.onProgress && !Array.isArray(i.progressEvents) && !i.signal?.aborted) {
|
|
1644
|
+
let e = c ? i.objectiveValue ?? 0 : void 0;
|
|
1645
|
+
i.onProgress({
|
|
1646
|
+
elapsedTime: .001,
|
|
1647
|
+
elapsedSeconds: .001,
|
|
1648
|
+
...typeof e == "number" && Number.isFinite(e) ? { objectiveValue: e } : {},
|
|
1649
|
+
...i.objectiveBound === void 0 ? {} : { objectiveBound: i.objectiveBound },
|
|
1650
|
+
...i.relGap === void 0 ? i.mipGap === void 0 ? {} : {
|
|
1651
|
+
relGap: i.mipGap,
|
|
1652
|
+
mipGap: i.mipGap
|
|
1653
|
+
} : {
|
|
1654
|
+
relGap: i.relGap,
|
|
1655
|
+
mipGap: i.relGap
|
|
1656
|
+
},
|
|
1657
|
+
...i.absGap === void 0 ? {} : { absGap: i.absGap }
|
|
1658
|
+
});
|
|
1659
|
+
}
|
|
1660
|
+
return i.signal?.aborted && (s = "Interrupted", c = i.hasPrimalSolution === void 0 ? a : i.hasPrimalSolution, o = c ? "Feasible" : "Unknown"), {
|
|
1661
|
+
status: o,
|
|
1662
|
+
terminationStatus: s,
|
|
1663
|
+
hasPrimalSolution: c,
|
|
1664
|
+
objectiveValue: c ? i.objectiveValue ?? 0 : null,
|
|
1665
|
+
...i.objectiveBound === void 0 ? {} : { objectiveBound: i.objectiveBound },
|
|
1666
|
+
...i.relGap === void 0 ? i.mipGap === void 0 ? {} : {
|
|
1667
|
+
relGap: i.mipGap,
|
|
1668
|
+
mipGap: i.mipGap
|
|
1669
|
+
} : {
|
|
1670
|
+
relGap: i.relGap,
|
|
1671
|
+
mipGap: i.relGap
|
|
1672
|
+
},
|
|
1673
|
+
...i.absGap === void 0 ? {} : { absGap: i.absGap },
|
|
1674
|
+
values: c && i.values || {},
|
|
1675
|
+
...c && i.boolValues !== void 0 ? { boolValues: i.boolValues } : {},
|
|
1676
|
+
reducedCosts: i.reducedCosts,
|
|
1677
|
+
duals: i.duals,
|
|
1678
|
+
slacks: i.slacks,
|
|
1034
1679
|
runTime: .001,
|
|
1035
1680
|
raw: { mock: !0 }
|
|
1036
1681
|
};
|
|
1037
1682
|
}
|
|
1038
1683
|
};
|
|
1039
|
-
function
|
|
1040
|
-
|
|
1684
|
+
function Ne() {
|
|
1685
|
+
V("mock", (e) => new Me(e));
|
|
1686
|
+
}
|
|
1687
|
+
Ne();
|
|
1688
|
+
//#endregion
|
|
1689
|
+
//#region src/modeler/solution-validator.ts
|
|
1690
|
+
function Pe(e, t) {
|
|
1691
|
+
if (e === void 0) return 1e-6;
|
|
1692
|
+
if (typeof e != "number" || !Number.isFinite(e) || e < 0) throw Error(`Invalid ${t}: expected a finite non-negative number, received ${String(e)}.`);
|
|
1693
|
+
return e;
|
|
1694
|
+
}
|
|
1695
|
+
function Fe(e, t = {}) {
|
|
1696
|
+
let n = Pe(t.feasibilityTolerance, "feasibilityTolerance"), r = Pe(t.integralityTolerance, "integralityTolerance"), i = t.evaluateLogicalConstraints === void 0 || !!t.evaluateLogicalConstraints, a = t.values !== void 0 && t.values !== null;
|
|
1697
|
+
if (t.values !== void 0 && (typeof t.values != "object" || t.values === null || Array.isArray(t.values))) throw Error("Invalid values option: expected a plain object mapping variable names to values.");
|
|
1698
|
+
let o = t.values, s = [], c = Object.create(null), l = [], f = [], p = 0, m = (e) => {
|
|
1699
|
+
typeof e == "number" && !Number.isNaN(e) && e > p && (p = e);
|
|
1700
|
+
}, h = (e) => {
|
|
1701
|
+
s.push(e), Object.prototype.hasOwnProperty.call(c, e.name) || (c[e.name] = []), c[e.name].push(e), e.type !== "missing_value" && e.type !== "unchecked_constraint" && m(e.violation);
|
|
1702
|
+
}, g = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Map(), y = 0, b = 0, x = 0, S = 0;
|
|
1703
|
+
for (let t of e.variables) {
|
|
1704
|
+
let e = a ? Object.prototype.hasOwnProperty.call(o, t.name) ? o[t.name] : void 0 : t.value;
|
|
1705
|
+
if (e == null) {
|
|
1706
|
+
f.push(t.name), h({
|
|
1707
|
+
type: "missing_value",
|
|
1708
|
+
target: "variable",
|
|
1709
|
+
name: t.name,
|
|
1710
|
+
actual: e ?? null,
|
|
1711
|
+
violation: Infinity,
|
|
1712
|
+
message: `Variable "${t.name}" has no assigned solution value.`
|
|
1713
|
+
});
|
|
1714
|
+
continue;
|
|
1715
|
+
}
|
|
1716
|
+
if (typeof e != "number" || !Number.isFinite(e)) {
|
|
1717
|
+
h({
|
|
1718
|
+
type: "non_finite_value",
|
|
1719
|
+
target: "variable",
|
|
1720
|
+
name: t.name,
|
|
1721
|
+
actual: e,
|
|
1722
|
+
violation: Infinity,
|
|
1723
|
+
message: `Variable "${t.name}" has non-finite or non-numeric value: ${String(e)}.`
|
|
1724
|
+
});
|
|
1725
|
+
continue;
|
|
1726
|
+
}
|
|
1727
|
+
g.set(t, e), y++;
|
|
1728
|
+
let i = t.type === "Binary" || t.type === "BINARY", s = i || t.type === "Integer" || t.type === "INTEGER", c = i ? Math.max(0, t.lb) : t.lb, l = i ? Math.min(1, t.ub) : t.ub, u = typeof t.lb == "number" && !Number.isNaN(t.lb) && t.lb !== Infinity, d = typeof t.ub == "number" && !Number.isNaN(t.ub) && t.ub !== -Infinity;
|
|
1729
|
+
if (!u) h({
|
|
1730
|
+
type: "lower_bound",
|
|
1731
|
+
target: "variable",
|
|
1732
|
+
name: t.name,
|
|
1733
|
+
actual: e,
|
|
1734
|
+
limit: t.lb,
|
|
1735
|
+
violation: Infinity,
|
|
1736
|
+
message: `Variable "${t.name}" has invalid lower bound (${String(t.lb)}).`
|
|
1737
|
+
});
|
|
1738
|
+
else if (c !== -Infinity) {
|
|
1739
|
+
let r = e - c, i = Math.max(0, c - e);
|
|
1740
|
+
m(i), i > n && h({
|
|
1741
|
+
type: "lower_bound",
|
|
1742
|
+
target: "variable",
|
|
1743
|
+
name: t.name,
|
|
1744
|
+
actual: e,
|
|
1745
|
+
limit: c,
|
|
1746
|
+
violation: i,
|
|
1747
|
+
signedViolation: r,
|
|
1748
|
+
message: `Variable "${t.name}" value (${e}) violates lower bound (${c}) by ${i}.`
|
|
1749
|
+
});
|
|
1750
|
+
}
|
|
1751
|
+
if (!d) h({
|
|
1752
|
+
type: "upper_bound",
|
|
1753
|
+
target: "variable",
|
|
1754
|
+
name: t.name,
|
|
1755
|
+
actual: e,
|
|
1756
|
+
limit: t.ub,
|
|
1757
|
+
violation: Infinity,
|
|
1758
|
+
message: `Variable "${t.name}" has invalid upper bound (${String(t.ub)}).`
|
|
1759
|
+
});
|
|
1760
|
+
else if (l !== Infinity) {
|
|
1761
|
+
let r = e - l, i = Math.max(0, e - l);
|
|
1762
|
+
m(i), i > n && h({
|
|
1763
|
+
type: "upper_bound",
|
|
1764
|
+
target: "variable",
|
|
1765
|
+
name: t.name,
|
|
1766
|
+
actual: e,
|
|
1767
|
+
limit: l,
|
|
1768
|
+
violation: i,
|
|
1769
|
+
signedViolation: r,
|
|
1770
|
+
message: `Variable "${t.name}" value (${e}) violates upper bound (${l}) by ${i}.`
|
|
1771
|
+
});
|
|
1772
|
+
}
|
|
1773
|
+
if (u && d && c > l && c - e <= n && e - l <= n) {
|
|
1774
|
+
let n = c - l;
|
|
1775
|
+
h({
|
|
1776
|
+
type: "lower_bound",
|
|
1777
|
+
target: "variable",
|
|
1778
|
+
name: t.name,
|
|
1779
|
+
actual: e,
|
|
1780
|
+
limit: c,
|
|
1781
|
+
violation: n,
|
|
1782
|
+
signedViolation: e - c,
|
|
1783
|
+
message: `Variable "${t.name}" has inverted bounds [${c}, ${l}].`
|
|
1784
|
+
});
|
|
1785
|
+
}
|
|
1786
|
+
if (s) {
|
|
1787
|
+
let n = Math.round(e), a = e - n, o = Math.abs(a);
|
|
1788
|
+
m(o), o > r && h({
|
|
1789
|
+
type: "integrality",
|
|
1790
|
+
target: "variable",
|
|
1791
|
+
name: t.name,
|
|
1792
|
+
varType: i ? "Binary" : "Integer",
|
|
1793
|
+
actual: e,
|
|
1794
|
+
nearestInteger: n,
|
|
1795
|
+
violation: o,
|
|
1796
|
+
signedViolation: a,
|
|
1797
|
+
message: `${i ? "Binary" : "Integer"} variable "${t.name}" value (${e}) violates integrality by ${o} (nearest integer: ${n}).`
|
|
1798
|
+
});
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
for (let t of e.boolVars) {
|
|
1802
|
+
let e = a ? Object.prototype.hasOwnProperty.call(o, t.name) ? o[t.name] : void 0 : t.value;
|
|
1803
|
+
if (e == null) {
|
|
1804
|
+
f.push(t.name), h({
|
|
1805
|
+
type: "missing_value",
|
|
1806
|
+
target: "bool_variable",
|
|
1807
|
+
name: t.name,
|
|
1808
|
+
actual: e ?? null,
|
|
1809
|
+
violation: Infinity,
|
|
1810
|
+
message: `Boolean variable "${t.name}" has no assigned solution value.`
|
|
1811
|
+
});
|
|
1812
|
+
continue;
|
|
1813
|
+
}
|
|
1814
|
+
if (typeof e != "boolean") {
|
|
1815
|
+
h({
|
|
1816
|
+
type: "invalid_boolean_value",
|
|
1817
|
+
target: "bool_variable",
|
|
1818
|
+
name: t.name,
|
|
1819
|
+
actual: e,
|
|
1820
|
+
violation: Infinity,
|
|
1821
|
+
message: `Boolean variable "${t.name}" has non-boolean value: ${String(e)}.`
|
|
1822
|
+
});
|
|
1823
|
+
continue;
|
|
1824
|
+
}
|
|
1825
|
+
_.set(t, e), b++;
|
|
1826
|
+
}
|
|
1827
|
+
let C = (e) => {
|
|
1828
|
+
let t = e.constant === void 0 ? 0 : e.constant;
|
|
1829
|
+
if (typeof t != "number" || !Number.isFinite(t)) return {
|
|
1830
|
+
ok: !1,
|
|
1831
|
+
reason: `non-finite constant (${String(t)})`
|
|
1832
|
+
};
|
|
1833
|
+
let n = t;
|
|
1834
|
+
for (let [t, r] of e.terms) {
|
|
1835
|
+
if (typeof r != "number" || !Number.isFinite(r)) return {
|
|
1836
|
+
ok: !1,
|
|
1837
|
+
reason: `non-finite coefficient (${String(r)}) for variable "${t.name}"`
|
|
1838
|
+
};
|
|
1839
|
+
if (r !== 0) {
|
|
1840
|
+
if (!g.has(t)) return {
|
|
1841
|
+
ok: !1,
|
|
1842
|
+
reason: `missing or invalid value for variable "${t.name}"`
|
|
1843
|
+
};
|
|
1844
|
+
if (n += r * g.get(t), !Number.isFinite(n)) return {
|
|
1845
|
+
ok: !1,
|
|
1846
|
+
reason: "linear expression evaluation overflowed finite range"
|
|
1847
|
+
};
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
return {
|
|
1851
|
+
ok: !0,
|
|
1852
|
+
value: n
|
|
1853
|
+
};
|
|
1854
|
+
}, w = (e, t = n) => {
|
|
1855
|
+
if (typeof e.rhs != "number" || !Number.isFinite(e.rhs)) return {
|
|
1856
|
+
status: "unchecked",
|
|
1857
|
+
reason: `non-finite right-hand side (${String(e.rhs)})`
|
|
1858
|
+
};
|
|
1859
|
+
let r = C(e.lhs);
|
|
1860
|
+
if (!r.ok) return {
|
|
1861
|
+
status: "unchecked",
|
|
1862
|
+
reason: r.reason
|
|
1863
|
+
};
|
|
1864
|
+
let i = r.value, a = i - e.rhs;
|
|
1865
|
+
if (!Number.isFinite(a)) return {
|
|
1866
|
+
status: "unchecked",
|
|
1867
|
+
reason: "constraint residual overflowed finite range"
|
|
1868
|
+
};
|
|
1869
|
+
let o = e.sense === "<=" ? Math.max(0, a) : e.sense === ">=" ? Math.max(0, -a) : Math.abs(a);
|
|
1870
|
+
return o > t ? {
|
|
1871
|
+
status: "violated",
|
|
1872
|
+
lhsVal: i,
|
|
1873
|
+
signed: a,
|
|
1874
|
+
violation: o,
|
|
1875
|
+
message: `Constraint "${e.name}" (${i} ${e.sense} ${e.rhs}) violated by ${o}.`
|
|
1876
|
+
} : {
|
|
1877
|
+
status: "satisfied",
|
|
1878
|
+
lhsVal: i,
|
|
1879
|
+
signed: a,
|
|
1880
|
+
violation: o
|
|
1881
|
+
};
|
|
1882
|
+
};
|
|
1883
|
+
for (let t of e.constraints) {
|
|
1884
|
+
let e = w(t);
|
|
1885
|
+
e.status === "unchecked" ? (l.push(t.name), h({
|
|
1886
|
+
type: "unchecked_constraint",
|
|
1887
|
+
target: "constraint",
|
|
1888
|
+
name: t.name,
|
|
1889
|
+
sense: t.sense,
|
|
1890
|
+
limit: t.rhs,
|
|
1891
|
+
rhs: t.rhs,
|
|
1892
|
+
violation: Infinity,
|
|
1893
|
+
message: `Constraint "${t.name}" could not be evaluated: ${e.reason}.`
|
|
1894
|
+
})) : e.status === "violated" ? (x++, h({
|
|
1895
|
+
type: "linear_constraint",
|
|
1896
|
+
target: "constraint",
|
|
1897
|
+
name: t.name,
|
|
1898
|
+
sense: t.sense,
|
|
1899
|
+
actual: e.lhsVal,
|
|
1900
|
+
limit: t.rhs,
|
|
1901
|
+
rhs: t.rhs,
|
|
1902
|
+
violation: e.violation,
|
|
1903
|
+
signedViolation: e.signed,
|
|
1904
|
+
message: e.message
|
|
1905
|
+
})) : (x++, m(e.violation));
|
|
1906
|
+
}
|
|
1907
|
+
let T = (e) => {
|
|
1908
|
+
if (e instanceof u) return _.has(e) ? {
|
|
1909
|
+
ok: !0,
|
|
1910
|
+
value: _.get(e),
|
|
1911
|
+
violation: 0
|
|
1912
|
+
} : {
|
|
1913
|
+
ok: !1,
|
|
1914
|
+
reason: `missing or invalid value for Boolean variable "${e.name}"`
|
|
1915
|
+
};
|
|
1916
|
+
if (e instanceof v) {
|
|
1917
|
+
let t = w(e, 0);
|
|
1918
|
+
if (t.status === "unchecked") return {
|
|
1919
|
+
ok: !1,
|
|
1920
|
+
reason: t.reason
|
|
1921
|
+
};
|
|
1922
|
+
if (n > 0) {
|
|
1923
|
+
let r = Math.abs(t.lhsVal - e.rhs);
|
|
1924
|
+
if (r > 0 && r <= n) return {
|
|
1925
|
+
ok: !1,
|
|
1926
|
+
reason: `numeric comparison "${e.name}" lies within feasibilityTolerance (${n}) of boundary (${t.lhsVal} vs ${e.rhs})`
|
|
1927
|
+
};
|
|
1928
|
+
}
|
|
1929
|
+
return {
|
|
1930
|
+
ok: !0,
|
|
1931
|
+
value: t.status === "satisfied",
|
|
1932
|
+
violation: 0
|
|
1933
|
+
};
|
|
1934
|
+
}
|
|
1935
|
+
if (e instanceof d) switch (e.op) {
|
|
1936
|
+
case "not": {
|
|
1937
|
+
let t = T(e.children[0]);
|
|
1938
|
+
return t.ok ? {
|
|
1939
|
+
ok: !0,
|
|
1940
|
+
value: !t.value,
|
|
1941
|
+
violation: 0
|
|
1942
|
+
} : t;
|
|
1943
|
+
}
|
|
1944
|
+
case "and": {
|
|
1945
|
+
let t = 0;
|
|
1946
|
+
for (let n of e.children) {
|
|
1947
|
+
let e = T(n);
|
|
1948
|
+
if (!e.ok) return e;
|
|
1949
|
+
if (!e.value) return {
|
|
1950
|
+
ok: !0,
|
|
1951
|
+
value: !1,
|
|
1952
|
+
violation: 0
|
|
1953
|
+
};
|
|
1954
|
+
e.violation > t && (t = e.violation);
|
|
1955
|
+
}
|
|
1956
|
+
return {
|
|
1957
|
+
ok: !0,
|
|
1958
|
+
value: !0,
|
|
1959
|
+
violation: t
|
|
1960
|
+
};
|
|
1961
|
+
}
|
|
1962
|
+
case "or": {
|
|
1963
|
+
let t = !1, n = Infinity;
|
|
1964
|
+
for (let r of e.children) {
|
|
1965
|
+
let e = T(r);
|
|
1966
|
+
if (!e.ok) return e;
|
|
1967
|
+
e.value && (t = !0, e.violation < n && (n = e.violation));
|
|
1968
|
+
}
|
|
1969
|
+
return {
|
|
1970
|
+
ok: !0,
|
|
1971
|
+
value: t,
|
|
1972
|
+
violation: t ? n : 0
|
|
1973
|
+
};
|
|
1974
|
+
}
|
|
1975
|
+
case "implies": {
|
|
1976
|
+
let t = T(e.children[0]);
|
|
1977
|
+
if (!t.ok) return t;
|
|
1978
|
+
if (!t.value) return {
|
|
1979
|
+
ok: !0,
|
|
1980
|
+
value: !0,
|
|
1981
|
+
violation: 0
|
|
1982
|
+
};
|
|
1983
|
+
let n = T(e.children[1]);
|
|
1984
|
+
return n.ok ? {
|
|
1985
|
+
ok: !0,
|
|
1986
|
+
value: n.value,
|
|
1987
|
+
violation: n.value ? n.violation : 0
|
|
1988
|
+
} : n;
|
|
1989
|
+
}
|
|
1990
|
+
case "xor": {
|
|
1991
|
+
let t = !1, n = 0;
|
|
1992
|
+
for (let r of e.children) {
|
|
1993
|
+
let e = T(r);
|
|
1994
|
+
if (!e.ok) return e;
|
|
1995
|
+
e.value && (t = !t, e.violation > n && (n = e.violation));
|
|
1996
|
+
}
|
|
1997
|
+
return {
|
|
1998
|
+
ok: !0,
|
|
1999
|
+
value: t,
|
|
2000
|
+
violation: t ? n : 0
|
|
2001
|
+
};
|
|
2002
|
+
}
|
|
2003
|
+
default: return {
|
|
2004
|
+
ok: !1,
|
|
2005
|
+
reason: `unsupported logical operator "${String(e.op)}"`
|
|
2006
|
+
};
|
|
2007
|
+
}
|
|
2008
|
+
return {
|
|
2009
|
+
ok: !1,
|
|
2010
|
+
reason: "unsupported logical expression node"
|
|
2011
|
+
};
|
|
2012
|
+
};
|
|
2013
|
+
for (let t = 0; t < e.logicalConstraints.length; t++) {
|
|
2014
|
+
let n = e.logicalConstraints[t], r = n.name || `lc_${t + 1}`;
|
|
2015
|
+
if (!i) {
|
|
2016
|
+
l.push(r), h({
|
|
2017
|
+
type: "unchecked_constraint",
|
|
2018
|
+
target: "logical_constraint",
|
|
2019
|
+
name: r,
|
|
2020
|
+
violation: Infinity,
|
|
2021
|
+
message: `Logical constraint "${r}" was not evaluated because evaluateLogicalConstraints is false.`
|
|
2022
|
+
});
|
|
2023
|
+
continue;
|
|
2024
|
+
}
|
|
2025
|
+
let a = T(n.expr);
|
|
2026
|
+
if (!a.ok) {
|
|
2027
|
+
l.push(r), h({
|
|
2028
|
+
type: "unchecked_constraint",
|
|
2029
|
+
target: "logical_constraint",
|
|
2030
|
+
name: r,
|
|
2031
|
+
violation: Infinity,
|
|
2032
|
+
message: `Logical constraint "${r}" could not be evaluated: ${a.reason}.`
|
|
2033
|
+
});
|
|
2034
|
+
continue;
|
|
2035
|
+
}
|
|
2036
|
+
S++, a.value ? m(a.violation) : h({
|
|
2037
|
+
type: "logical_constraint",
|
|
2038
|
+
target: "logical_constraint",
|
|
2039
|
+
name: r,
|
|
2040
|
+
actual: !1,
|
|
2041
|
+
limit: !0,
|
|
2042
|
+
violation: 1,
|
|
2043
|
+
signedViolation: -1,
|
|
2044
|
+
message: `Logical constraint "${r}" evaluated to false.`
|
|
2045
|
+
});
|
|
2046
|
+
}
|
|
2047
|
+
let E = y === e.variables.length && b === e.boolVars.length && x === e.constraints.length && S === e.logicalConstraints.length && l.length === 0 && f.length === 0;
|
|
2048
|
+
return {
|
|
2049
|
+
valid: E && s.length === 0,
|
|
2050
|
+
complete: E,
|
|
2051
|
+
violations: s,
|
|
2052
|
+
violationsByName: c,
|
|
2053
|
+
uncheckedConstraints: l,
|
|
2054
|
+
missingVariables: f,
|
|
2055
|
+
maxViolation: p,
|
|
2056
|
+
summary: {
|
|
2057
|
+
checkedVariables: y,
|
|
2058
|
+
totalVariables: e.variables.length,
|
|
2059
|
+
checkedBoolVariables: b,
|
|
2060
|
+
totalBoolVariables: e.boolVars.length,
|
|
2061
|
+
checkedLinearConstraints: x,
|
|
2062
|
+
totalLinearConstraints: e.constraints.length,
|
|
2063
|
+
checkedLogicalConstraints: S,
|
|
2064
|
+
totalLogicalConstraints: e.logicalConstraints.length
|
|
2065
|
+
}
|
|
2066
|
+
};
|
|
2067
|
+
}
|
|
2068
|
+
//#endregion
|
|
2069
|
+
//#region src/modeler/big-m.ts
|
|
2070
|
+
function Ie(e, t) {
|
|
2071
|
+
if (typeof e != "number" || !Number.isFinite(e) || e <= 0) throw Error(`Invalid Big-M value for indicator constraint "${t}": expected a finite positive number, received ${e}.`);
|
|
2072
|
+
}
|
|
2073
|
+
function Y(e, t, n) {
|
|
2074
|
+
let r = e.constant === void 0 ? 0 : e.constant;
|
|
2075
|
+
if (!Number.isFinite(t) || !Number.isFinite(r)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": constraint contains non-finite constant (${r}) or right-hand side (${t}).`);
|
|
2076
|
+
let i = t - r;
|
|
2077
|
+
if (!Number.isFinite(i)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": effective right-hand side (${t} - ${r}) overflows finite floating-point range. Please rescale coefficients/constants.`);
|
|
2078
|
+
for (let [t, r] of e.terms) {
|
|
2079
|
+
if (!Number.isFinite(r)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" has non-finite coefficient (${r}).`);
|
|
2080
|
+
if (Number.isNaN(t.lb) || Number.isNaN(t.ub) || t.lb === Infinity || t.ub === -Infinity || t.lb > t.ub) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" has invalid bounds [${t.lb}, ${t.ub}].`);
|
|
2081
|
+
}
|
|
2082
|
+
return i;
|
|
2083
|
+
}
|
|
2084
|
+
function Le(e, t, n) {
|
|
2085
|
+
let r = Y(e, t, n), i = 0;
|
|
2086
|
+
for (let [t, r] of e.terms) {
|
|
2087
|
+
if (r === 0) continue;
|
|
2088
|
+
let e;
|
|
2089
|
+
if (r > 0) {
|
|
2090
|
+
if (!Number.isFinite(t.ub)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite upper bound (required because coefficient ${r} is positive in <= constraint). Please set an explicit finite upper bound on the variable or specify { M } explicitly in indicator options.`);
|
|
2091
|
+
e = t.ub;
|
|
2092
|
+
} else {
|
|
2093
|
+
if (!Number.isFinite(t.lb)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite lower bound (required because coefficient ${r} is negative in <= constraint). Please set an explicit finite lower bound on the variable or specify { M } explicitly in indicator options.`);
|
|
2094
|
+
e = t.lb;
|
|
2095
|
+
}
|
|
2096
|
+
let a = r * e;
|
|
2097
|
+
if (i += a, !Number.isFinite(a) || !Number.isFinite(i)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while bounding contribution of variable "${t.name}". Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
2098
|
+
}
|
|
2099
|
+
let a = i - r;
|
|
2100
|
+
if (!Number.isFinite(a)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while computing Big-M (${i} - ${r}). Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
2101
|
+
let o = Math.max(0, a);
|
|
2102
|
+
if (!Number.isFinite(o) || !Number.isFinite(r + o)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": derived Big-M (${o}) or shifted right-hand side overflows finite floating-point range. Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
2103
|
+
return o;
|
|
2104
|
+
}
|
|
2105
|
+
function Re(e, t, n) {
|
|
2106
|
+
let r = Y(e, t, n), i = 0;
|
|
2107
|
+
for (let [t, r] of e.terms) {
|
|
2108
|
+
if (r === 0) continue;
|
|
2109
|
+
let e;
|
|
2110
|
+
if (r > 0) {
|
|
2111
|
+
if (!Number.isFinite(t.lb)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite lower bound (required because coefficient ${r} is positive in >= constraint). Please set an explicit finite lower bound on the variable or specify { M } explicitly in indicator options.`);
|
|
2112
|
+
e = t.lb;
|
|
2113
|
+
} else {
|
|
2114
|
+
if (!Number.isFinite(t.ub)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite upper bound (required because coefficient ${r} is negative in >= constraint). Please set an explicit finite upper bound on the variable or specify { M } explicitly in indicator options.`);
|
|
2115
|
+
e = t.ub;
|
|
2116
|
+
}
|
|
2117
|
+
let a = r * e;
|
|
2118
|
+
if (i += a, !Number.isFinite(a) || !Number.isFinite(i)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while bounding contribution of variable "${t.name}". Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
2119
|
+
}
|
|
2120
|
+
let a = r - i;
|
|
2121
|
+
if (!Number.isFinite(a)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while computing Big-M (${r} - ${i}). Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
2122
|
+
let o = Math.max(0, a);
|
|
2123
|
+
if (!Number.isFinite(o) || !Number.isFinite(r - o)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": derived Big-M (${o}) or shifted right-hand side overflows finite floating-point range. Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
2124
|
+
return o;
|
|
2125
|
+
}
|
|
2126
|
+
function X(e, t, n, r, i, a, o) {
|
|
2127
|
+
if (!(e instanceof N && (e.type === "Binary" || e.type === "Integer" && e.lb === 0 && e.ub === 1))) throw Error(`Indicator variable "${e?.name ?? String(e)}" must be a Binary variable (or Integer variable with bounds [0, 1]), received "${e?.type ?? typeof e}" with bounds [${e?.lb}, ${e?.ub}].`);
|
|
2128
|
+
if (!Number.isFinite(e.lb) || !Number.isFinite(e.ub) || e.lb < 0 || e.ub > 1 || e.lb > e.ub) throw Error(`Binary indicator variable "${e.name}" has invalid bounds [${e.lb}, ${e.ub}]. Binary variables must stay within [0, 1] with lb <= ub.`);
|
|
2129
|
+
let s = Y(t, r, o);
|
|
2130
|
+
if (i !== 0 && i !== 1) throw Error(`Invalid activeValue: ${i}. Indicator activation value must be 0 or 1.`);
|
|
2131
|
+
if (n !== "<=" && n !== ">=") throw Error(`Invalid indicator sense for "${o}": expected "<=" or ">=", received "${String(n)}".`);
|
|
2132
|
+
if (!Number.isFinite(a) || a < 0) throw Error(`Invalid Big-M value for indicator constraint "${o}": expected a finite non-negative number, received ${a}.`);
|
|
2133
|
+
let c = t.terms.get(e);
|
|
2134
|
+
if (c !== void 0 && c !== 0) throw Error(`Indicator constraint "${o}" cannot include its own binary activation variable "${e.name}" in the linear expression.`);
|
|
2135
|
+
let l, u;
|
|
2136
|
+
if (i === 1 ? n === "<=" ? (l = a, u = s + a) : (l = -a, u = s - a) : n === "<=" ? (l = -a, u = s) : (l = a, u = s), !Number.isFinite(u)) throw Error(`Cannot construct finite indicator constraint "${o}": shifted right-hand side overflows finite floating-point range. Please rescale coefficients/bounds or specify a smaller finite { M }.`);
|
|
2137
|
+
let d = /* @__PURE__ */ new Map();
|
|
2138
|
+
for (let [e, n] of t.terms) n !== 0 && d.set(e, n);
|
|
2139
|
+
return l !== 0 && d.set(e, l), {
|
|
2140
|
+
lhs: new S(d, 0),
|
|
2141
|
+
rhs: u
|
|
2142
|
+
};
|
|
1041
2143
|
}
|
|
1042
|
-
oe();
|
|
1043
2144
|
//#endregion
|
|
1044
2145
|
//#region src/modeler/model.ts
|
|
1045
|
-
|
|
2146
|
+
function Z(e) {
|
|
2147
|
+
return Array.isArray(e) || typeof e == "object" && !!e && !(e instanceof String) && typeof e[Symbol.iterator] == "function";
|
|
2148
|
+
}
|
|
2149
|
+
function Q(e) {
|
|
2150
|
+
return typeof e == "object" && !!e && !Array.isArray(e) && !(e instanceof String) && typeof e[Symbol.iterator] != "function";
|
|
2151
|
+
}
|
|
2152
|
+
function $(e, t) {
|
|
2153
|
+
if (!Number.isInteger(e) || e < 0) throw Error(`Invalid count (${e}) for ${t} variable creation: count must be a non-negative integer.`);
|
|
2154
|
+
}
|
|
2155
|
+
var ze = class {
|
|
1046
2156
|
name;
|
|
1047
|
-
|
|
1048
|
-
|
|
2157
|
+
_sense;
|
|
2158
|
+
_objectiveExpr;
|
|
1049
2159
|
variables = [];
|
|
1050
2160
|
constraints = [];
|
|
1051
2161
|
boolVars = [];
|
|
1052
2162
|
logicalConstraints = [];
|
|
1053
|
-
unsatCore =
|
|
2163
|
+
unsatCore = void 0;
|
|
1054
2164
|
values = /* @__PURE__ */ new Map();
|
|
1055
2165
|
varMapByName = /* @__PURE__ */ new Map();
|
|
2166
|
+
varPrefixCounters = /* @__PURE__ */ new Map();
|
|
1056
2167
|
boolVarMapByName = /* @__PURE__ */ new Map();
|
|
1057
2168
|
boolVarPrefixCounters = /* @__PURE__ */ new Map();
|
|
1058
2169
|
constrMapByName = /* @__PURE__ */ new Map();
|
|
2170
|
+
constrPrefixCounters = /* @__PURE__ */ new Map();
|
|
2171
|
+
logicalConstrMapByName = /* @__PURE__ */ new Map();
|
|
2172
|
+
logicalConstrCounter = 0;
|
|
1059
2173
|
status = "NotSolved";
|
|
2174
|
+
terminationStatus = "NotSolved";
|
|
2175
|
+
hasPrimalSolution = !1;
|
|
1060
2176
|
objectiveValue = null;
|
|
2177
|
+
objectiveBound = void 0;
|
|
2178
|
+
relGap = void 0;
|
|
2179
|
+
mipGap = void 0;
|
|
2180
|
+
absGap = void 0;
|
|
1061
2181
|
runTime = 0;
|
|
1062
2182
|
solution = null;
|
|
1063
2183
|
solver = null;
|
|
2184
|
+
hasSolutionState = !1;
|
|
2185
|
+
modelRevision = 0;
|
|
2186
|
+
activeOperationId = 0;
|
|
2187
|
+
batchDepth = 0;
|
|
2188
|
+
batchMutated = !1;
|
|
2189
|
+
batchUndoActions = [];
|
|
1064
2190
|
constructor(e = {}, t) {
|
|
1065
2191
|
let n;
|
|
1066
2192
|
n = typeof e == "string" ? {
|
|
1067
2193
|
...t,
|
|
1068
2194
|
name: e
|
|
1069
|
-
} : e, this.name = n.name || "OptimizationModel", this.
|
|
2195
|
+
} : e, this.name = n.name || "OptimizationModel", this._sense = o(n.sense), this._objectiveExpr = new S(), n.solver && (this.solver = H(n.solver));
|
|
2196
|
+
}
|
|
2197
|
+
get sense() {
|
|
2198
|
+
return this._sense;
|
|
2199
|
+
}
|
|
2200
|
+
set sense(e) {
|
|
2201
|
+
let t = o(e);
|
|
2202
|
+
this._sense !== t && (this._sense = t, this.recordModelMutation());
|
|
2203
|
+
}
|
|
2204
|
+
get objectiveExpr() {
|
|
2205
|
+
return this._objectiveExpr.clone();
|
|
1070
2206
|
}
|
|
1071
|
-
|
|
1072
|
-
|
|
2207
|
+
set objectiveExpr(e) {
|
|
2208
|
+
this.applyObjective(e);
|
|
1073
2209
|
}
|
|
1074
|
-
get
|
|
1075
|
-
return this.
|
|
2210
|
+
get conflicts() {
|
|
2211
|
+
return this.unsatCore;
|
|
1076
2212
|
}
|
|
1077
2213
|
get numVars() {
|
|
1078
2214
|
return this.variables.length;
|
|
@@ -1080,50 +2216,123 @@ var se = class {
|
|
|
1080
2216
|
get numConstrs() {
|
|
1081
2217
|
return this.constraints.length;
|
|
1082
2218
|
}
|
|
1083
|
-
|
|
1084
|
-
if (
|
|
1085
|
-
|
|
1086
|
-
for (let
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
2219
|
+
clearSolutionFields() {
|
|
2220
|
+
if (this.hasSolutionState || this.status !== "NotSolved" || this.terminationStatus !== "NotSolved" || this.hasPrimalSolution || this.solution !== null || this.unsatCore !== void 0) {
|
|
2221
|
+
this.hasSolutionState = !1, this.status = "NotSolved", this.terminationStatus = "NotSolved", this.hasPrimalSolution = !1, this.objectiveValue = null, this.objectiveBound = void 0, this.relGap = void 0, this.mipGap = void 0, this.absGap = void 0, this.solution = null, this.runTime = 0, this.unsatCore = void 0, this.values.clear();
|
|
2222
|
+
for (let e of this.variables) e.value = null, e.reducedCost = null;
|
|
2223
|
+
for (let e of this.boolVars) e.value = null;
|
|
2224
|
+
for (let e of this.constraints) e.dual = null, e.slack = null;
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
recordModelMutation() {
|
|
2228
|
+
if (this.batchDepth > 0) {
|
|
2229
|
+
this.batchMutated = !0;
|
|
2230
|
+
return;
|
|
2231
|
+
}
|
|
2232
|
+
this.modelRevision++, this.clearSolutionFields();
|
|
2233
|
+
}
|
|
2234
|
+
notifyMutation() {
|
|
2235
|
+
this.recordModelMutation();
|
|
2236
|
+
}
|
|
2237
|
+
resetSolutionState() {
|
|
2238
|
+
this.recordModelMutation();
|
|
2239
|
+
}
|
|
2240
|
+
runTransactionalBatch(e) {
|
|
2241
|
+
if (this.batchDepth > 0) return e();
|
|
2242
|
+
let t = this.variables.length, n = this.boolVars.length, r = this.constraints.length, i = this.logicalConstraints.length, a = new Map(this.varPrefixCounters), o = new Map(this.boolVarPrefixCounters), s = new Map(this.constrPrefixCounters), c = this.logicalConstrCounter;
|
|
2243
|
+
this.batchDepth = 1, this.batchMutated = !1, this.batchUndoActions = [];
|
|
2244
|
+
try {
|
|
2245
|
+
let t = e();
|
|
2246
|
+
this.batchDepth = 0;
|
|
2247
|
+
let n = this.batchMutated;
|
|
2248
|
+
return this.batchMutated = !1, this.batchUndoActions = [], n && this.recordModelMutation(), t;
|
|
2249
|
+
} catch (e) {
|
|
2250
|
+
this.batchDepth = 0, this.batchMutated = !1;
|
|
2251
|
+
for (let e = t; e < this.variables.length; e++) {
|
|
2252
|
+
let t = this.variables[e];
|
|
2253
|
+
this.varMapByName.delete(t.name), t.ownerModel = null, te(t, this);
|
|
2254
|
+
}
|
|
2255
|
+
this.variables.length = t;
|
|
2256
|
+
for (let e = n; e < this.boolVars.length; e++) {
|
|
2257
|
+
let t = this.boolVars[e];
|
|
2258
|
+
this.boolVarMapByName.delete(t.name);
|
|
2259
|
+
}
|
|
2260
|
+
this.boolVars.length = n;
|
|
2261
|
+
for (let e = r; e < this.constraints.length; e++) {
|
|
2262
|
+
let t = this.constraints[e];
|
|
2263
|
+
this.constrMapByName.delete(t.name);
|
|
1093
2264
|
}
|
|
1094
|
-
|
|
2265
|
+
this.constraints.length = r;
|
|
2266
|
+
for (let e = i; e < this.logicalConstraints.length; e++) {
|
|
2267
|
+
let t = this.logicalConstraints[e];
|
|
2268
|
+
this.logicalConstrMapByName.delete(t.name);
|
|
2269
|
+
}
|
|
2270
|
+
this.logicalConstraints.length = i;
|
|
2271
|
+
for (let e = this.batchUndoActions.length - 1; e >= 0; e--) this.batchUndoActions[e]();
|
|
2272
|
+
throw this.batchUndoActions = [], this.varPrefixCounters = a, this.boolVarPrefixCounters = o, this.constrPrefixCounters = s, this.logicalConstrCounter = c, e;
|
|
1095
2273
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
2274
|
+
}
|
|
2275
|
+
createDomainVars(e, t, n, r) {
|
|
2276
|
+
let i = e.toLowerCase(), a = typeof t == "number", o = typeof n == "number", s = Z(t), c = Z(n);
|
|
2277
|
+
if (o || c) {
|
|
2278
|
+
if (a && $(t, i), o && $(n, i), !a && !s || r !== void 0 && !Q(r)) throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
2279
|
+
let c = a ? Array.from({ length: t }, (e, t) => t) : Array.from(t), l = o ? Array.from({ length: n }, (e, t) => t) : n === t ? c : Array.from(n), u = r || {}, d = u.prefix || u.name || "x";
|
|
2280
|
+
return this.runTransactionalBatch(() => {
|
|
2281
|
+
let t = a ? [] : {};
|
|
2282
|
+
for (let n of c) {
|
|
2283
|
+
let r = o ? [] : {};
|
|
2284
|
+
for (let t of l) r[t] = this.addVar({
|
|
2285
|
+
...u,
|
|
2286
|
+
type: e,
|
|
2287
|
+
name: `${d}_${n}_${t}`
|
|
2288
|
+
});
|
|
2289
|
+
t[n] = r;
|
|
2290
|
+
}
|
|
2291
|
+
return t;
|
|
2292
|
+
});
|
|
2293
|
+
}
|
|
2294
|
+
if (typeof t == "string" || t === void 0) {
|
|
2295
|
+
if (n !== void 0 && !Q(n)) throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
2296
|
+
let r = n || {}, a = typeof t == "string" ? t : r.name;
|
|
1098
2297
|
return this.addVar({
|
|
1099
2298
|
...r,
|
|
1100
2299
|
type: e,
|
|
1101
|
-
name:
|
|
2300
|
+
name: a
|
|
1102
2301
|
});
|
|
1103
2302
|
}
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
let
|
|
1107
|
-
|
|
1108
|
-
...
|
|
2303
|
+
if (Q(t)) {
|
|
2304
|
+
if (n !== void 0) throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
2305
|
+
let r = t;
|
|
2306
|
+
return this.addVar({
|
|
2307
|
+
...r,
|
|
2308
|
+
type: e
|
|
2309
|
+
});
|
|
2310
|
+
}
|
|
2311
|
+
if (n !== void 0 && !Q(n)) throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
2312
|
+
let l = n || {}, u = l.prefix || l.name;
|
|
2313
|
+
if (typeof t == "number") return $(t, i), this.runTransactionalBatch(() => {
|
|
2314
|
+
let n = [], r = u || "x";
|
|
2315
|
+
for (let i = 0; i < t; i++) n.push(this.addVar({
|
|
2316
|
+
...l,
|
|
1109
2317
|
type: e,
|
|
1110
|
-
name:
|
|
2318
|
+
name: void 0,
|
|
2319
|
+
prefix: r
|
|
1111
2320
|
}));
|
|
1112
2321
|
return n;
|
|
1113
|
-
}
|
|
1114
|
-
if (
|
|
2322
|
+
});
|
|
2323
|
+
if (Z(t)) return this.runTransactionalBatch(() => {
|
|
1115
2324
|
let n = {};
|
|
1116
2325
|
for (let r of t) {
|
|
1117
|
-
let t =
|
|
2326
|
+
let t = u ? `${u}_${r}` : `${r}`;
|
|
1118
2327
|
n[r] = this.addVar({
|
|
1119
|
-
...
|
|
2328
|
+
...l,
|
|
1120
2329
|
type: e,
|
|
1121
2330
|
name: t
|
|
1122
2331
|
});
|
|
1123
2332
|
}
|
|
1124
2333
|
return n;
|
|
1125
|
-
}
|
|
1126
|
-
throw Error(`Invalid arguments provided for ${
|
|
2334
|
+
});
|
|
2335
|
+
throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
1127
2336
|
}
|
|
1128
2337
|
binary(e, t, n) {
|
|
1129
2338
|
return this.createDomainVars("Binary", e, t, n);
|
|
@@ -1135,52 +2344,96 @@ var se = class {
|
|
|
1135
2344
|
return this.createDomainVars("Continuous", e, t, n);
|
|
1136
2345
|
}
|
|
1137
2346
|
bool(e, t, n) {
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
2347
|
+
let r = typeof e == "number", i = typeof t == "number", a = Z(e), o = Z(t);
|
|
2348
|
+
if (i || o) {
|
|
2349
|
+
if (r && $(e, "boolean"), i && $(t, "boolean"), !r && !a || n !== void 0 && !Q(n)) throw Error("Invalid arguments provided for boolean variable creation");
|
|
2350
|
+
let o = r ? Array.from({ length: e }, (e, t) => t) : Array.from(e), s = i ? Array.from({ length: t }, (e, t) => t) : t === e ? o : Array.from(t), c = n || {}, l = c.prefix || c.name || "p";
|
|
2351
|
+
return this.runTransactionalBatch(() => {
|
|
2352
|
+
let e = r ? [] : {};
|
|
2353
|
+
for (let t of o) {
|
|
2354
|
+
let n = i ? [] : {};
|
|
2355
|
+
for (let e of s) n[e] = this.createBoolVar(`${l}_${t}_${e}`);
|
|
2356
|
+
e[t] = n;
|
|
2357
|
+
}
|
|
2358
|
+
return e;
|
|
2359
|
+
});
|
|
1145
2360
|
}
|
|
1146
|
-
if (typeof e == "string" || e === void 0)
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
for (let r = 0; r < e; r++) t.push(this.createBoolVar(this.getNextBoolVarName(n)));
|
|
1151
|
-
return t;
|
|
2361
|
+
if (typeof e == "string" || e === void 0) {
|
|
2362
|
+
if (t !== void 0 && !Q(t)) throw Error("Invalid arguments provided for boolean variable creation");
|
|
2363
|
+
let n = t || {}, r = typeof e == "string" ? e : n.name;
|
|
2364
|
+
return this.createBoolVar(r, n.prefix);
|
|
1152
2365
|
}
|
|
1153
|
-
if (
|
|
2366
|
+
if (Q(e)) {
|
|
2367
|
+
if (t !== void 0) throw Error("Invalid arguments provided for boolean variable creation");
|
|
2368
|
+
let n = e;
|
|
2369
|
+
return this.createBoolVar(n.name, n.prefix);
|
|
2370
|
+
}
|
|
2371
|
+
if (t !== void 0 && !Q(t)) throw Error("Invalid arguments provided for boolean variable creation");
|
|
2372
|
+
let s = t || {}, c = s.prefix || s.name;
|
|
2373
|
+
if (typeof e == "number") return $(e, "boolean"), this.runTransactionalBatch(() => {
|
|
2374
|
+
let t = [], n = c || "p";
|
|
2375
|
+
for (let r = 0; r < e; r++) t.push(this.createBoolVar(void 0, n));
|
|
2376
|
+
return t;
|
|
2377
|
+
});
|
|
2378
|
+
if (Z(e)) return this.runTransactionalBatch(() => {
|
|
1154
2379
|
let t = {};
|
|
1155
2380
|
for (let n of e) {
|
|
1156
|
-
let e =
|
|
2381
|
+
let e = c ? `${c}_${n}` : `${n}`;
|
|
1157
2382
|
t[n] = this.createBoolVar(e);
|
|
1158
2383
|
}
|
|
1159
2384
|
return t;
|
|
1160
|
-
}
|
|
2385
|
+
});
|
|
1161
2386
|
throw Error("Invalid arguments provided for boolean variable creation");
|
|
1162
2387
|
}
|
|
1163
2388
|
hasVarName(e) {
|
|
1164
2389
|
return this.varMapByName.has(e) || this.boolVarMapByName.has(e);
|
|
1165
2390
|
}
|
|
2391
|
+
getNextVarName(e) {
|
|
2392
|
+
let t = this.varPrefixCounters.get(e) ?? 0, n = `${e}_${t}`;
|
|
2393
|
+
for (; this.hasVarName(n);) t++, n = `${e}_${t}`;
|
|
2394
|
+
return this.varPrefixCounters.set(e, t + 1), n;
|
|
2395
|
+
}
|
|
1166
2396
|
getNextBoolVarName(e) {
|
|
1167
2397
|
let t = this.boolVarPrefixCounters.get(e) ?? 0, n = `${e}_${t}`;
|
|
1168
|
-
for (; this.hasVarName(n);) t++, n = `${e}_${t}`;
|
|
2398
|
+
for (; this.hasVarName(n) || this.hasConstraintName(n);) t++, n = `${e}_${t}`;
|
|
1169
2399
|
return this.boolVarPrefixCounters.set(e, t + 1), n;
|
|
1170
2400
|
}
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
return this.
|
|
2401
|
+
hasConstraintName(e) {
|
|
2402
|
+
return this.constrMapByName.has(e) || this.logicalConstrMapByName.has(e);
|
|
2403
|
+
}
|
|
2404
|
+
hasBoolVarName(e) {
|
|
2405
|
+
return this.boolVarMapByName.has(e);
|
|
2406
|
+
}
|
|
2407
|
+
getNextConstrName(e = "c") {
|
|
2408
|
+
let t = this.constrPrefixCounters.get(e) ?? 1, n = `${e}_${t}`;
|
|
2409
|
+
for (; this.hasConstraintName(n) || this.hasBoolVarName(n);) t++, n = `${e}_${t}`;
|
|
2410
|
+
return this.constrPrefixCounters.set(e, t + 1), n;
|
|
2411
|
+
}
|
|
2412
|
+
getNextLogicalConstrName() {
|
|
2413
|
+
let e = this.logicalConstrCounter + 1, t = `lc_${e}`;
|
|
2414
|
+
for (; this.hasConstraintName(t) || this.hasBoolVarName(t);) e++, t = `lc_${e}`;
|
|
2415
|
+
return this.logicalConstrCounter = e, t;
|
|
2416
|
+
}
|
|
2417
|
+
createBoolVar(e, t) {
|
|
2418
|
+
let n = typeof e == "string" ? e.trim() : void 0, r = typeof t == "string" ? t.trim() : "", i = r.length > 0 ? r : "p", a = n && n.length > 0 ? n : this.getNextBoolVarName(i);
|
|
2419
|
+
if (this.hasVarName(a)) throw Error(`Variable with name '${a}' already exists in model`);
|
|
2420
|
+
if (this.hasConstraintName(a)) throw Error(`Boolean variable name '${a}' conflicts with an existing constraint in model`);
|
|
2421
|
+
let o = new u(a);
|
|
2422
|
+
return this.boolVars.push(o), this.boolVarMapByName.set(o.name, o), this.recordModelMutation(), o;
|
|
1176
2423
|
}
|
|
1177
2424
|
addVar(e) {
|
|
1178
|
-
let t = e || {}, n = typeof t.name == "string" ? t.name.trim() : void 0, r = n && n.length > 0 ? n : void 0, i =
|
|
1179
|
-
|
|
1180
|
-
name
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
2425
|
+
let t = e || {}, n = typeof t.name == "string" ? t.name.trim() : void 0, r = n && n.length > 0 ? n : void 0, i = typeof t.prefix == "string" ? t.prefix.trim() : "", a = i.length > 0 ? i : "x", o = this.varPrefixCounters.get(a), s = r ?? this.getNextVarName(a);
|
|
2426
|
+
try {
|
|
2427
|
+
if (this.hasVarName(s)) throw Error(`Variable with name '${s}' already exists in model`);
|
|
2428
|
+
let e = new N({
|
|
2429
|
+
...t,
|
|
2430
|
+
name: s,
|
|
2431
|
+
prefix: a
|
|
2432
|
+
});
|
|
2433
|
+
return e.hasExplicitName = r !== void 0, A(e), k(e, this), e.ownerModel = this, this.variables.push(e), this.varMapByName.set(e.name, e), this.recordModelMutation(), e;
|
|
2434
|
+
} catch (e) {
|
|
2435
|
+
throw r === void 0 && (o === void 0 ? this.varPrefixCounters.delete(a) : this.varPrefixCounters.set(a, o)), e;
|
|
2436
|
+
}
|
|
1184
2437
|
}
|
|
1185
2438
|
getVarByName(e) {
|
|
1186
2439
|
return this.varMapByName.get(e);
|
|
@@ -1191,28 +2444,41 @@ var se = class {
|
|
|
1191
2444
|
getConstraintByName(e) {
|
|
1192
2445
|
return this.constrMapByName.get(e);
|
|
1193
2446
|
}
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
this.
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
if (
|
|
1206
|
-
|
|
2447
|
+
getLogicalConstraintByName(e) {
|
|
2448
|
+
return this.logicalConstrMapByName.get(e);
|
|
2449
|
+
}
|
|
2450
|
+
objective(e) {
|
|
2451
|
+
return e ? (this.applyObjective(e.expr, e.sense), this) : this.objectiveExpr;
|
|
2452
|
+
}
|
|
2453
|
+
applyObjective(e, t) {
|
|
2454
|
+
if (e instanceof v || typeof e == "object" && e && "sense" in e && "lhs" in e && "rhs" in e || typeof e == "string" && /(<=|>=|==|=<|=>|=)/.test(e)) throw Error(typeof e == "string" ? "Cannot use a comparison constraint as an objective. Did you mean to use m.constraint(expr`... <= ...`)?" : "Cannot use a Constraint as an objective. Did you mean to use m.constraint(expr`... <= ...`)? For objectives, supply an unconstrained expression like expr`45 * ${x} + 80 * ${y}`.");
|
|
2455
|
+
let n = t === void 0 ? this.sense : o(t), r;
|
|
2456
|
+
if (typeof e == "string") r = fe(e, (e) => this.getVarByName(e));
|
|
2457
|
+
else if (typeof e == "number") r = new S(/* @__PURE__ */ new Map(), e);
|
|
2458
|
+
else if (e instanceof x) r = e.clone();
|
|
2459
|
+
else if (e instanceof S) r = e.clone();
|
|
2460
|
+
else if (typeof e == "object" && e && "quadTerms" in e && e.quadTerms instanceof Map && "linearTerms" in e && e.linearTerms instanceof Map && typeof e.constant == "number") {
|
|
2461
|
+
let t = e;
|
|
2462
|
+
r = new x(t.linearTerms, t.quadTerms, t.constant);
|
|
2463
|
+
} else if (typeof e == "object" && e && "terms" in e && e.terms instanceof Map && typeof e.constant == "number") {
|
|
2464
|
+
let t = e;
|
|
2465
|
+
r = new S(t.terms, t.constant);
|
|
2466
|
+
} else if (e instanceof N || typeof e == "object" && e && "id" in e && "name" in e && "lb" in e && "ub" in e) r = new S(/* @__PURE__ */ new Map([[e, 1]]), 0);
|
|
2467
|
+
else throw Error("Invalid objective expression: expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.");
|
|
2468
|
+
ae(r, this.name, (e) => this.varMapByName.get(e.name) === e), this._sense = n, this._objectiveExpr = r, this.recordModelMutation();
|
|
2469
|
+
}
|
|
2470
|
+
constraint(e, t) {
|
|
2471
|
+
if (Array.isArray(e)) return this.runTransactionalBatch(() => {
|
|
2472
|
+
for (let t of e) this.constraint(t);
|
|
1207
2473
|
return this;
|
|
1208
|
-
}
|
|
1209
|
-
if (e instanceof
|
|
1210
|
-
if (e instanceof
|
|
2474
|
+
});
|
|
2475
|
+
if (e instanceof x || typeof e == "object" && e && "quadTerms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a quadratic expression as a constraint.");
|
|
2476
|
+
if (e instanceof S || typeof e == "object" && e && "terms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a linear expression without a comparison operator. Use expr`... <= ...` or .le(), .ge(), .eq().");
|
|
1211
2477
|
return this.addConstraint(e, t), this;
|
|
1212
2478
|
}
|
|
1213
2479
|
getValues(e) {
|
|
1214
2480
|
if (e == null) return null;
|
|
1215
|
-
if (e instanceof
|
|
2481
|
+
if (e instanceof N || e instanceof u) return e.value;
|
|
1216
2482
|
if (Array.isArray(e)) return e.map((e) => this.getValues(e));
|
|
1217
2483
|
if (typeof e == "object") {
|
|
1218
2484
|
let t = {};
|
|
@@ -1222,157 +2488,344 @@ var se = class {
|
|
|
1222
2488
|
return null;
|
|
1223
2489
|
}
|
|
1224
2490
|
addConstraint(e, t) {
|
|
1225
|
-
if (e instanceof
|
|
1226
|
-
if (e instanceof
|
|
1227
|
-
if (e instanceof
|
|
1228
|
-
let n = t
|
|
1229
|
-
|
|
1230
|
-
name
|
|
2491
|
+
if (e instanceof x || typeof e == "object" && e && "quadTerms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a quadratic expression as a constraint.");
|
|
2492
|
+
if (e instanceof S || typeof e == "object" && e && "terms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a linear expression without a comparison operator. Use expr`... <= ...` or .le(), .ge(), .eq().");
|
|
2493
|
+
if (e instanceof l) {
|
|
2494
|
+
let n = typeof t == "string" && t.trim().length > 0 ? t.trim() : void 0;
|
|
2495
|
+
if (n !== void 0) {
|
|
2496
|
+
if (this.hasConstraintName(n)) throw Error(`Constraint with name '${n}' already exists in model`);
|
|
2497
|
+
if (this.hasBoolVarName(n)) throw Error(`Constraint name '${n}' conflicts with an existing Boolean variable in model`);
|
|
2498
|
+
}
|
|
2499
|
+
let r = this.logicalConstrCounter, i = n ?? this.getNextLogicalConstrName();
|
|
2500
|
+
try {
|
|
2501
|
+
M(e, i, this.name, (e) => this.varMapByName.get(e.name) === e, (e) => this.boolVarMapByName.get(e.name) === e, this);
|
|
2502
|
+
} catch (e) {
|
|
2503
|
+
throw n === void 0 && (this.logicalConstrCounter = r), e;
|
|
2504
|
+
}
|
|
2505
|
+
O(e, this, this.batchDepth > 0 ? this.batchUndoActions : void 0);
|
|
2506
|
+
let a = {
|
|
2507
|
+
name: i,
|
|
1231
2508
|
expr: e
|
|
1232
|
-
}
|
|
2509
|
+
};
|
|
2510
|
+
return this.logicalConstraints.push(a), this.logicalConstrMapByName.set(i, a), this.recordModelMutation(), e;
|
|
1233
2511
|
}
|
|
1234
|
-
let n;
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
2512
|
+
let n = typeof e == "string" ? me(e, (e) => this.getVarByName(e), t) : e;
|
|
2513
|
+
n.ownerModel && n.ownerModel !== this && (j(n, this.name, (e) => this.varMapByName.get(e.name) === e, n.name), ee(n, this));
|
|
2514
|
+
let r = typeof t == "string" && t.trim().length > 0 ? t.trim() : n.hasExplicitName ? n.name.trim() : void 0;
|
|
2515
|
+
if (r !== void 0) {
|
|
2516
|
+
if (this.hasConstraintName(r)) throw Error(`Constraint with name '${r}' already exists in model`);
|
|
2517
|
+
if (this.hasBoolVarName(r)) throw Error(`Constraint name '${r}' conflicts with an existing Boolean variable in model`);
|
|
2518
|
+
}
|
|
2519
|
+
let i = this.constrPrefixCounters.get("c"), a = r ?? this.getNextConstrName("c"), o;
|
|
2520
|
+
try {
|
|
2521
|
+
j(n, this.name, (e) => this.varMapByName.get(e.name) === e, a), o = ee(n, this);
|
|
2522
|
+
} catch (e) {
|
|
2523
|
+
throw r === void 0 && (i === void 0 ? this.constrPrefixCounters.delete("c") : this.constrPrefixCounters.set("c", i)), e;
|
|
1242
2524
|
}
|
|
1243
|
-
|
|
2525
|
+
let s = n.name, c = n.hasExplicitName, u = n.ownerModel, d = o;
|
|
2526
|
+
return this.batchUndoActions.push(() => {
|
|
2527
|
+
n.ownerModel = u, n._assignModelName(s, c), ne(n, this, d);
|
|
2528
|
+
}), this.batchDepth === 0 && (this.batchUndoActions = []), n._assignModelName(a, !0), n.ownerModel = this, this.constraints.push(n), this.constrMapByName.set(n.name, n), this.recordModelMutation(), n;
|
|
1244
2529
|
}
|
|
1245
2530
|
indicator(e, t, n = {}) {
|
|
1246
|
-
if (
|
|
2531
|
+
if (!(e instanceof N)) throw Error("Invalid binary variable passed to indicator(). Expected a binary Var instance.");
|
|
2532
|
+
if (!(e.type === "Binary" || e.type === "Integer" && e.lb === 0 && e.ub === 1)) throw Error(`Invalid variable "${e.name}" passed to indicator(): variable has type "${e.type}" with bounds [${e.lb}, ${e.ub}]. Indicator activation variable must be a Binary variable (or Integer variable with bounds [0, 1]).`);
|
|
2533
|
+
if (t instanceof x) throw Error("Quadratic expressions or constraints are not supported in indicator constraints (only linear constraints are allowed).");
|
|
1247
2534
|
if (!("sense" in t) || !("lhs" in t)) throw Error("Invalid constraint expression passed to indicator(). Expression must include a comparison operator (<=, >=, ==).");
|
|
1248
|
-
let r = t, i = n.activeValue === void 0 ? 1 : n.activeValue
|
|
1249
|
-
if (i
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
2535
|
+
let r = t, i = n.activeValue === void 0 ? 1 : n.activeValue;
|
|
2536
|
+
if (i !== 0 && i !== 1) throw Error(`Invalid activeValue: ${i}. Indicator activeValue must be 0 or 1.`);
|
|
2537
|
+
if (this.varMapByName.get(e.name) !== e) throw Error(`Variable "${e.name}" passed to indicator() does not belong to model "${this.name}". All variables must belong to the model by object identity.`);
|
|
2538
|
+
let a = typeof n.name == "string" && n.name.trim().length > 0 ? n.name.trim() : void 0, o = this.constrPrefixCounters.get("c"), { lhs: s, sense: c, rhs: l } = r, u, d, f;
|
|
2539
|
+
if (a !== void 0) u = a, d = c === "==" ? `${u}_le` : u, f = c === "==" ? `${u}_ge` : u;
|
|
2540
|
+
else if (r.hasExplicitName) u = `ind_${e.name}_${r.name.trim()}`, d = c === "==" ? `${u}_le` : u, f = c === "==" ? `${u}_ge` : u;
|
|
2541
|
+
else do {
|
|
2542
|
+
let t = this.getNextConstrName("c");
|
|
2543
|
+
u = `ind_${e.name}_${t}`, d = c === "==" ? `${u}_le` : u, f = c === "==" ? `${u}_ge` : u;
|
|
2544
|
+
} while ((c === "<=" || c === "==") && (this.hasConstraintName(d) || this.hasBoolVarName(d)) || (c === ">=" || c === "==") && (this.hasConstraintName(f) || this.hasBoolVarName(f)));
|
|
2545
|
+
let p = [];
|
|
2546
|
+
try {
|
|
2547
|
+
if ((c === "<=" || c === "==") && (this.hasConstraintName(d) || this.hasBoolVarName(d))) throw Error(this.hasBoolVarName(d) ? `Constraint name '${d}' conflicts with an existing Boolean variable in model` : `Constraint with name '${d}' already exists in model`);
|
|
2548
|
+
if ((c === ">=" || c === "==") && (this.hasConstraintName(f) || this.hasBoolVarName(f))) throw Error(this.hasBoolVarName(f) ? `Constraint name '${f}' conflicts with an existing Boolean variable in model` : `Constraint with name '${f}' already exists in model`);
|
|
2549
|
+
n.M !== void 0 && Ie(n.M, u);
|
|
2550
|
+
let t = (e) => this.varMapByName.get(e.name) === e;
|
|
2551
|
+
for (let [e] of s.terms) if (!t(e)) throw Error(`Variable "${e.name}" in constraint "${u}" does not belong to model "${this.name}". All variables must belong to the model by object identity.`);
|
|
2552
|
+
if (c === "<=" || c === "==") {
|
|
2553
|
+
let t = X(e, s, "<=", l, i, n.M === void 0 ? Le(s, l, d) : n.M, d);
|
|
2554
|
+
p.push([new v(t.lhs, "<=", t.rhs, d), d]);
|
|
1262
2555
|
}
|
|
1263
|
-
if (
|
|
1264
|
-
let t =
|
|
1265
|
-
|
|
2556
|
+
if (c === ">=" || c === "==") {
|
|
2557
|
+
let t = X(e, s, ">=", l, i, n.M === void 0 ? Re(s, l, f) : n.M, f);
|
|
2558
|
+
p.push([new v(t.lhs, ">=", t.rhs, f), f]);
|
|
1266
2559
|
}
|
|
2560
|
+
for (let [e, n] of p) j(e, this.name, t, n);
|
|
2561
|
+
} catch (e) {
|
|
2562
|
+
throw o === void 0 ? this.constrPrefixCounters.delete("c") : this.constrPrefixCounters.set("c", o), e;
|
|
1267
2563
|
}
|
|
1268
|
-
return
|
|
2564
|
+
return this.runTransactionalBatch(() => p.map(([e, t]) => this.addConstraint(e, t)));
|
|
1269
2565
|
}
|
|
1270
2566
|
toLpString() {
|
|
2567
|
+
this.validateIntegrity();
|
|
1271
2568
|
let { lpString: e } = R({
|
|
1272
2569
|
name: this.name,
|
|
1273
2570
|
sense: this.sense,
|
|
1274
|
-
objective: this.
|
|
2571
|
+
objective: this.objectiveExpr,
|
|
1275
2572
|
constraints: this.constraints,
|
|
1276
2573
|
variables: this.variables
|
|
1277
2574
|
});
|
|
1278
2575
|
return e;
|
|
1279
2576
|
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
2577
|
+
validateIntegrity() {
|
|
2578
|
+
oe(this);
|
|
2579
|
+
}
|
|
2580
|
+
ensureExecutionValid(e, t, n) {
|
|
2581
|
+
if (this.modelRevision !== e) throw this.activeOperationId === t && this.clearSolutionFields(), Error(`Model "${this.name}" was modified while ${n}() was in progress; stale solver result was discarded.`);
|
|
2582
|
+
if (this.activeOperationId !== t) throw Error(`Stale ${n}() result discarded because a newer solve or check operation was started on model "${this.name}".`);
|
|
2583
|
+
}
|
|
2584
|
+
wrapSolveOptions(e, t, n) {
|
|
2585
|
+
let r = e.onProgress;
|
|
2586
|
+
return r ? {
|
|
2587
|
+
...e,
|
|
2588
|
+
onProgress: (e) => {
|
|
2589
|
+
this.activeOperationId === n && this.modelRevision === t && r(e);
|
|
2590
|
+
}
|
|
2591
|
+
} : e;
|
|
2592
|
+
}
|
|
2593
|
+
hasPrimalFromResult(e) {
|
|
2594
|
+
if (typeof e.hasPrimalSolution == "boolean") return e.hasPrimalSolution;
|
|
2595
|
+
let t = e.status, n = e.terminationStatus ?? t, r = e.values || {}, i = e.boolValues || {};
|
|
2596
|
+
return t !== "Infeasible" && t !== "Unsat" && t !== "Unbounded" && t !== "Error" && t !== "NotSolved" && n !== "Infeasible" && n !== "Unsat" && n !== "Unbounded" && n !== "InfeasibleOrUnbounded" && n !== "Error" && n !== "NotSolved" && (t === "Optimal" || t === "Feasible" || t === "Sat" || n === "Optimal" || n === "Feasible" || n === "Sat" || typeof e.objectiveValue == "number" && Number.isFinite(e.objectiveValue) || Object.values(r).some((e) => typeof e == "number" && Number.isFinite(e) || typeof e == "boolean") || Object.values(i).some((e) => typeof e == "boolean"));
|
|
2597
|
+
}
|
|
2598
|
+
resolveSolverAndOptions(e, t) {
|
|
2599
|
+
if (e && typeof e == "object" && "solve" in e && typeof e.solve == "function") {
|
|
2600
|
+
let { solver: n, ...r } = t || {};
|
|
2601
|
+
return {
|
|
2602
|
+
activeSolver: e,
|
|
2603
|
+
activeOptions: r
|
|
2604
|
+
};
|
|
2605
|
+
}
|
|
2606
|
+
if (typeof e == "function") {
|
|
2607
|
+
let { solver: n, ...r } = t || {};
|
|
2608
|
+
return {
|
|
2609
|
+
activeSolver: new e(r),
|
|
2610
|
+
activeOptions: r
|
|
2611
|
+
};
|
|
2612
|
+
}
|
|
2613
|
+
if (typeof e == "string") {
|
|
2614
|
+
let { solver: n, ...r } = t || {};
|
|
2615
|
+
return {
|
|
2616
|
+
activeSolver: H(e, r),
|
|
2617
|
+
activeOptions: r
|
|
2618
|
+
};
|
|
2619
|
+
}
|
|
2620
|
+
let { solver: n, ...r } = e || {};
|
|
2621
|
+
return n ? {
|
|
2622
|
+
activeSolver: H(n, r),
|
|
2623
|
+
activeOptions: r
|
|
2624
|
+
} : {
|
|
2625
|
+
activeSolver: this.solver || H(),
|
|
2626
|
+
activeOptions: r
|
|
2627
|
+
};
|
|
2628
|
+
}
|
|
2629
|
+
async solve(e, t) {
|
|
2630
|
+
let n = ++this.activeOperationId, r = this.modelRevision;
|
|
2631
|
+
this.clearSolutionFields(), this.validateIntegrity();
|
|
2632
|
+
let { activeSolver: i, activeOptions: a } = this.resolveSolverAndOptions(e, t);
|
|
2633
|
+
if (this._objectiveExpr instanceof x && this._objectiveExpr.quadTerms.size > 0 && i.capabilities?.supportsQP === !1) throw Error(`Solver "${i.name}" does not support quadratic objectives (QP). Please use a QP-capable solver such as HiGHS or Clarabel.`);
|
|
2634
|
+
if (this.logicalConstraints.length > 0 && i.capabilities?.supportsSMT !== !0) throw Error(`Solver "${i.name}" does not support SMT / logical constraints (or, implies, not, xor). Please use an SMT-capable solver such as Z3.`);
|
|
2635
|
+
if (this.variables.some((e) => e.initialValue !== void 0) && i.capabilities?.supportsWarmStart !== !0) throw Error(`Solver "${i.name}" does not support primal initial values (initialValue). Please use a solver with warm-start support such as HiGHS.`);
|
|
2636
|
+
let o = {
|
|
1285
2637
|
name: this.name,
|
|
1286
2638
|
sense: this.sense,
|
|
1287
|
-
objective: this.
|
|
2639
|
+
objective: this._objectiveExpr,
|
|
1288
2640
|
constraints: this.constraints,
|
|
1289
2641
|
variables: this.variables,
|
|
1290
2642
|
logicalConstraints: this.logicalConstraints,
|
|
1291
2643
|
boolVars: this.boolVars
|
|
1292
|
-
},
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
2644
|
+
}, s = this.wrapSolveOptions(a, r, n), c;
|
|
2645
|
+
try {
|
|
2646
|
+
c = await i.solve(o, s);
|
|
2647
|
+
} catch (e) {
|
|
2648
|
+
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
2649
|
+
}
|
|
2650
|
+
this.ensureExecutionValid(r, n, "solve"), this.runTime = c.runTime ?? 0, this.status = c.status, this.terminationStatus = c.terminationStatus ?? c.status;
|
|
2651
|
+
let l = this.hasPrimalFromResult(c);
|
|
2652
|
+
this.hasPrimalSolution = l, this.objectiveValue = l && typeof c.objectiveValue == "number" && Number.isFinite(c.objectiveValue) ? c.objectiveValue : null, this.objectiveBound = typeof c.objectiveBound == "number" && Number.isFinite(c.objectiveBound) ? c.objectiveBound : void 0;
|
|
2653
|
+
let u = typeof c.relGap == "number" && Number.isFinite(c.relGap) ? c.relGap : typeof c.mipGap == "number" && Number.isFinite(c.mipGap) ? c.mipGap : void 0;
|
|
2654
|
+
this.relGap = u, this.mipGap = u, this.absGap = typeof c.absGap == "number" && Number.isFinite(c.absGap) ? c.absGap : this.objectiveValue !== null && this.objectiveBound !== void 0 ? Math.abs(this.objectiveValue - this.objectiveBound) : void 0;
|
|
2655
|
+
let d = (e, t, n) => {
|
|
2656
|
+
Object.defineProperty(e, t, {
|
|
2657
|
+
value: n,
|
|
2658
|
+
enumerable: !0,
|
|
2659
|
+
writable: !0,
|
|
2660
|
+
configurable: !0
|
|
2661
|
+
});
|
|
2662
|
+
}, f = {}, p = {}, m = {}, h = {};
|
|
2663
|
+
if (this.values.clear(), l && c.values) {
|
|
2664
|
+
for (let [e, t] of Object.entries(c.values)) if (typeof t == "number" && Number.isFinite(t)) {
|
|
2665
|
+
let n = this.getVarByName(e), r = this.getBoolVarByName(e);
|
|
2666
|
+
n && (n.value = t, d(f, n.name, t), this.values.set(n.name, t)), r && (r.value = !!t, this.values.set(r.name, t)), !n && !r && this.values.set(e, t);
|
|
2667
|
+
} else if (typeof t == "boolean") {
|
|
2668
|
+
let n = t, r = this.getBoolVarByName(e);
|
|
2669
|
+
r ? (r.value = n, d(f, r.name, +!!n), this.values.set(r.name, n)) : this.values.set(e, n);
|
|
1308
2670
|
}
|
|
1309
2671
|
}
|
|
1310
|
-
if (
|
|
1311
|
-
|
|
1312
|
-
|
|
2672
|
+
if (l && c.boolValues) for (let [e, t] of Object.entries(c.boolValues)) {
|
|
2673
|
+
if (typeof t != "boolean") continue;
|
|
2674
|
+
let n = this.getBoolVarByName(e);
|
|
2675
|
+
n ? (n.value = t, this.values.has(n.name) || this.values.set(n.name, t)) : this.values.has(e) || this.values.set(e, t);
|
|
2676
|
+
}
|
|
2677
|
+
if (l && c.reducedCosts) for (let [e, t] of Object.entries(c.reducedCosts)) {
|
|
2678
|
+
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
2679
|
+
let n = this.getVarByName(e);
|
|
2680
|
+
n && (n.reducedCost = t, d(m, n.name, t));
|
|
1313
2681
|
}
|
|
1314
|
-
if (
|
|
1315
|
-
|
|
1316
|
-
|
|
2682
|
+
if (c.duals) for (let [e, t] of Object.entries(c.duals)) {
|
|
2683
|
+
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
2684
|
+
let n = this.getConstraintByName(e);
|
|
2685
|
+
n && (n.dual = t, d(p, n.name, t));
|
|
1317
2686
|
}
|
|
1318
|
-
if (
|
|
1319
|
-
|
|
1320
|
-
|
|
2687
|
+
if (c.slacks) for (let [e, t] of Object.entries(c.slacks)) {
|
|
2688
|
+
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
2689
|
+
let n = this.getConstraintByName(e);
|
|
2690
|
+
n && (n.slack = t, d(h, n.name, t));
|
|
1321
2691
|
}
|
|
1322
2692
|
return this.solution = {
|
|
1323
2693
|
status: this.status,
|
|
2694
|
+
terminationStatus: this.terminationStatus,
|
|
2695
|
+
hasPrimalSolution: this.hasPrimalSolution,
|
|
1324
2696
|
objectiveValue: this.objectiveValue,
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
2697
|
+
...this.objectiveBound === void 0 ? {} : { objectiveBound: this.objectiveBound },
|
|
2698
|
+
...this.relGap === void 0 ? {} : {
|
|
2699
|
+
relGap: this.relGap,
|
|
2700
|
+
mipGap: this.mipGap
|
|
2701
|
+
},
|
|
2702
|
+
...this.absGap === void 0 ? {} : { absGap: this.absGap },
|
|
2703
|
+
values: f,
|
|
2704
|
+
duals: p,
|
|
2705
|
+
reducedCosts: m,
|
|
2706
|
+
slacks: h,
|
|
1329
2707
|
runTime: this.runTime,
|
|
1330
|
-
raw:
|
|
1331
|
-
}, this.status;
|
|
1332
|
-
}
|
|
1333
|
-
async solve(e, t) {
|
|
1334
|
-
return this.optimize(e, t);
|
|
2708
|
+
raw: c.raw
|
|
2709
|
+
}, this.hasSolutionState = !0, this.status;
|
|
1335
2710
|
}
|
|
1336
2711
|
async check(e, t) {
|
|
1337
|
-
let n, r;
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
2712
|
+
let n = ++this.activeOperationId, r = this.modelRevision;
|
|
2713
|
+
this.clearSolutionFields(), this.validateIntegrity();
|
|
2714
|
+
let { activeSolver: i, activeOptions: a } = this.resolveSolverAndOptions(e, t);
|
|
2715
|
+
if (this.logicalConstraints.length > 0 && i.capabilities?.supportsSMT !== !0) throw Error(`Solver "${i.name}" does not support SMT / logical constraints (or, implies, not, xor). Please use an SMT-capable solver such as Z3.`);
|
|
2716
|
+
if (this.variables.some((e) => e.initialValue !== void 0) && i.capabilities?.supportsWarmStart !== !0) throw Error(`Solver "${i.name}" does not support primal initial values (initialValue). Please use a solver with warm-start support such as HiGHS.`);
|
|
2717
|
+
let o = this.wrapSolveOptions(a, r, n), s = (e, t, n) => {
|
|
2718
|
+
Object.defineProperty(e, t, {
|
|
2719
|
+
value: n,
|
|
2720
|
+
enumerable: !0,
|
|
2721
|
+
writable: !0,
|
|
2722
|
+
configurable: !0
|
|
2723
|
+
});
|
|
2724
|
+
}, c = {
|
|
2725
|
+
name: this.name,
|
|
2726
|
+
variables: this.variables,
|
|
2727
|
+
boolVars: this.boolVars,
|
|
2728
|
+
constraints: this.constraints,
|
|
2729
|
+
logicalConstraints: this.logicalConstraints
|
|
2730
|
+
};
|
|
2731
|
+
if (typeof i.check == "function") {
|
|
2732
|
+
let e;
|
|
2733
|
+
try {
|
|
2734
|
+
e = await i.check(c, o);
|
|
2735
|
+
} catch (e) {
|
|
2736
|
+
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
1356
2737
|
}
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
2738
|
+
this.ensureExecutionValid(r, n, "check"), this.status = e.status, this.terminationStatus = a.signal?.aborted ? "Interrupted" : e.status, this.hasPrimalSolution = e.status === "Sat", this.runTime = e.runTime ?? 0, this.unsatCore = e.unsatCore === void 0 ? void 0 : Object.freeze([...e.unsatCore]);
|
|
2739
|
+
let t = {};
|
|
2740
|
+
if (e.values && e.status === "Sat") {
|
|
2741
|
+
for (let [n, r] of Object.entries(e.values)) if (typeof r == "number") {
|
|
2742
|
+
if (!Number.isFinite(r)) continue;
|
|
2743
|
+
let e = this.getVarByName(n), i = this.getBoolVarByName(n);
|
|
2744
|
+
e && (e.value = r, this.values.set(e.name, r), s(t, e.name, r)), i && (i.value = !!r, this.values.set(i.name, i.value), s(t, i.name, i.value)), !e && !i && (this.values.set(n, r), s(t, n, r));
|
|
2745
|
+
} else if (typeof r == "boolean") {
|
|
2746
|
+
let e = this.getBoolVarByName(n);
|
|
2747
|
+
e ? (e.value = r, this.values.set(e.name, r), s(t, e.name, r)) : (this.values.set(n, r), s(t, n, r));
|
|
2748
|
+
}
|
|
1366
2749
|
}
|
|
1367
|
-
return {
|
|
1368
|
-
status:
|
|
1369
|
-
values:
|
|
2750
|
+
return this.hasSolutionState = !0, {
|
|
2751
|
+
status: e.status,
|
|
2752
|
+
values: t,
|
|
2753
|
+
unsatCore: this.unsatCore,
|
|
2754
|
+
conflicts: this.unsatCore,
|
|
1370
2755
|
runTime: this.runTime
|
|
1371
2756
|
};
|
|
1372
|
-
} finally {
|
|
1373
|
-
this.objective = i, this.sense = a;
|
|
1374
2757
|
}
|
|
2758
|
+
let l = {
|
|
2759
|
+
name: this.name,
|
|
2760
|
+
sense: "Minimize",
|
|
2761
|
+
objective: new S(),
|
|
2762
|
+
constraints: this.constraints,
|
|
2763
|
+
variables: this.variables,
|
|
2764
|
+
logicalConstraints: this.logicalConstraints,
|
|
2765
|
+
boolVars: this.boolVars
|
|
2766
|
+
}, u;
|
|
2767
|
+
try {
|
|
2768
|
+
u = await i.solve(l, o);
|
|
2769
|
+
} catch (e) {
|
|
2770
|
+
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
2771
|
+
}
|
|
2772
|
+
this.ensureExecutionValid(r, n, "check"), this.runTime = u.runTime ?? 0;
|
|
2773
|
+
let d = u.status, f = u.terminationStatus ?? d, p = this.hasPrimalFromResult(u) || d === "Optimal" || d === "Feasible", m = p ? "Sat" : d === "Infeasible" ? "Unsat" : "Unknown";
|
|
2774
|
+
this.status = m, this.terminationStatus = a.signal?.aborted || f === "Interrupted" ? "Interrupted" : f === "Optimal" || f === "Feasible" || f === "Infeasible" ? m : f, this.hasPrimalSolution = p, this.objectiveValue = null, this.objectiveBound = void 0, this.relGap = void 0, this.mipGap = void 0, this.absGap = void 0, this.solution = null, this.values.clear();
|
|
2775
|
+
let h = {};
|
|
2776
|
+
if (p && u.values) {
|
|
2777
|
+
for (let [e, t] of Object.entries(u.values)) if (typeof t == "number" && Number.isFinite(t)) {
|
|
2778
|
+
let n = this.getVarByName(e), r = this.getBoolVarByName(e);
|
|
2779
|
+
n && (n.value = t, this.values.set(n.name, t), s(h, n.name, t)), r && (r.value = !!t, this.values.set(r.name, r.value), s(h, r.name, r.value)), !n && !r && (this.values.set(e, t), s(h, e, t));
|
|
2780
|
+
} else if (typeof t == "boolean") {
|
|
2781
|
+
let n = t, r = this.getBoolVarByName(e);
|
|
2782
|
+
r ? (r.value = n, this.values.set(r.name, n), s(h, r.name, n)) : (this.values.set(e, n), s(h, e, n));
|
|
2783
|
+
}
|
|
2784
|
+
}
|
|
2785
|
+
if (p && u.boolValues) for (let [e, t] of Object.entries(u.boolValues)) {
|
|
2786
|
+
if (typeof t != "boolean") continue;
|
|
2787
|
+
let n = this.getBoolVarByName(e);
|
|
2788
|
+
n ? (n.value = t, this.values.set(n.name, t), s(h, n.name, t)) : (this.values.set(e, t), s(h, e, t));
|
|
2789
|
+
}
|
|
2790
|
+
if (u.slacks) for (let [e, t] of Object.entries(u.slacks)) {
|
|
2791
|
+
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
2792
|
+
let n = this.getConstraintByName(e);
|
|
2793
|
+
n && (n.slack = t);
|
|
2794
|
+
}
|
|
2795
|
+
return this.hasSolutionState = !0, {
|
|
2796
|
+
status: m,
|
|
2797
|
+
values: h,
|
|
2798
|
+
runTime: this.runTime
|
|
2799
|
+
};
|
|
2800
|
+
}
|
|
2801
|
+
validateSolution(e = {}) {
|
|
2802
|
+
return Fe(this, e);
|
|
1375
2803
|
}
|
|
1376
2804
|
};
|
|
1377
2805
|
//#endregion
|
|
1378
|
-
|
|
2806
|
+
//#region src/modeler/objective.ts
|
|
2807
|
+
function Be(e, t) {
|
|
2808
|
+
let n = e;
|
|
2809
|
+
if (n instanceof v || typeof n == "object" && n && "sense" in n && "lhs" in n && "rhs" in n) throw Error(`Cannot use a Constraint as an objective in ${t}(). Use model.constraint(expr\`... <= ...\`) for constraints, or supply an unconstrained arithmetic expression to ${t}().`);
|
|
2810
|
+
if (typeof n == "string" && /(<=|>=|==|=<|=>|=)/.test(n)) throw Error(`Cannot use a comparison constraint as an objective in ${t}(). Use model.constraint(expr\`... <= ...\`) for constraints, or supply an unconstrained arithmetic expression to ${t}().`);
|
|
2811
|
+
if (typeof n == "number") {
|
|
2812
|
+
if (!Number.isFinite(n)) throw Error(`Invalid non-finite objective constant "${n}" passed to ${t}().`);
|
|
2813
|
+
return n;
|
|
2814
|
+
}
|
|
2815
|
+
if (typeof n == "string" || n instanceof S || n instanceof x || n instanceof N || typeof n == "object" && n && ("terms" in n && n.terms instanceof Map && typeof n.constant == "number" || "quadTerms" in n && n.quadTerms instanceof Map && "linearTerms" in n && n.linearTerms instanceof Map && typeof n.constant == "number" || "id" in n && "name" in n && "lb" in n && "ub" in n)) return n;
|
|
2816
|
+
throw Error(`Invalid expression passed to ${t}(): expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.`);
|
|
2817
|
+
}
|
|
2818
|
+
function Ve(e) {
|
|
2819
|
+
return {
|
|
2820
|
+
expr: Be(e, "maximize"),
|
|
2821
|
+
sense: "Maximize"
|
|
2822
|
+
};
|
|
2823
|
+
}
|
|
2824
|
+
function He(e) {
|
|
2825
|
+
return {
|
|
2826
|
+
expr: Be(e, "minimize"),
|
|
2827
|
+
sense: "Minimize"
|
|
2828
|
+
};
|
|
2829
|
+
}
|
|
2830
|
+
//#endregion
|
|
2831
|
+
export { l as BoolExpr, d as BoolOp, u as BoolVar, v as Constraint, Ae as HiGHS, J as HighsSolver, S as LinExpr, Me as MockSolver, ze as Model, x as QuadExpr, N as Var, f as and, X as buildIndicatorLinearization, ye as buildLpSymbolMaps, Re as deriveBigMForGe, Le as deriveBigMForLe, w as dot, ve as expr, R as generateLpString, a as getHighs, n as getHighsWasmUrl, H as getSolver, h as implies, I as isLpExportResult, U as listAvailableSolvers, Ve as maximize, He as minimize, o as normalizeSense, m as not, p as or, me as parseConstraint, fe as parseExpr, V as registerSolver, L as sanitizeIdentifier, Se as setDefaultSolver, t as setHighsWasmUrl, e as solveLpWithHighs, C as sum, oe as validateModelIntegrity, Fe as validateModelSolution, Ie as validateUserBigM, g as xor };
|