@ohtaman/washi 0.5.0 → 0.7.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 +103 -386
- package/README.md +104 -387
- package/README.zh-CN.md +103 -386
- package/THIRD_PARTY_LICENSES.md +5 -4
- package/dist/browser/_washi-node-only-BvRk9kiK.js +0 -0
- package/dist/browser/browser-runtime-TLCY0hkc.js +1793 -0
- package/dist/browser/highs-worker.js +1 -1
- package/dist/browser/highs.wasm +0 -0
- package/dist/browser/highs.wasm.LICENSE +1 -2
- package/dist/browser/loader-DewlSho8.js +643 -0
- package/dist/browser/solvers/glpk.js +3 -3
- package/dist/browser/solvers/glpk.min.js +1 -1
- package/dist/browser/solvers/z3.js +7 -1
- package/dist/browser/solvers/z3.min.js +1 -1
- package/dist/browser/washi.js +1708 -540
- package/dist/browser/washi.min.js +3 -4
- package/dist/lib/_washi-node-only-BvRk9kiK.js +0 -0
- package/dist/lib/highs-browser-runtime.js +2120 -4124
- package/dist/lib/highs-node-runtime.js +24 -1
- package/dist/lib/highs-runtime.js +2 -0
- package/dist/lib/highs-worker.js +1 -1
- package/dist/lib/highs.wasm +0 -0
- package/dist/lib/highs.wasm.LICENSE +1 -2
- package/dist/lib/loader-BZUQNvh4.js +649 -0
- package/dist/lib/{registry-BEfvpZW3.js → registry-D7TZ3Wh_.js} +142 -59
- package/dist/lib/solvers/glpk.js +4 -4
- package/dist/lib/solvers/z3.js +1 -1
- package/dist/lib/washi.js +1576 -465
- package/dist/types/decomposition/benders.d.ts +32 -0
- package/dist/types/decomposition/benders.d.ts.map +1 -0
- package/dist/types/decomposition/column-generation.d.ts +34 -0
- package/dist/types/decomposition/column-generation.d.ts.map +1 -0
- package/dist/types/decomposition/index.d.ts +4 -0
- package/dist/types/decomposition/index.d.ts.map +1 -0
- package/dist/types/decomposition/types.d.ts +230 -0
- package/dist/types/decomposition/types.d.ts.map +1 -0
- package/dist/types/index.d.ts +4 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/modeler/boolean-expr.d.ts.map +1 -1
- package/dist/types/modeler/constraint.d.ts +11 -0
- package/dist/types/modeler/constraint.d.ts.map +1 -1
- package/dist/types/modeler/expression.d.ts +57 -26
- package/dist/types/modeler/expression.d.ts.map +1 -1
- package/dist/types/modeler/index.d.ts +4 -3
- package/dist/types/modeler/index.d.ts.map +1 -1
- package/dist/types/modeler/linearizer.d.ts +15 -0
- package/dist/types/modeler/linearizer.d.ts.map +1 -0
- package/dist/types/modeler/lp-writer.d.ts +3 -1
- package/dist/types/modeler/lp-writer.d.ts.map +1 -1
- package/dist/types/modeler/model.d.ts +159 -8
- package/dist/types/modeler/model.d.ts.map +1 -1
- package/dist/types/modeler/parser.d.ts +25 -5
- package/dist/types/modeler/parser.d.ts.map +1 -1
- package/dist/types/modeler/solvers/glpk/solver.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/browser-runtime.d.ts +2 -1
- package/dist/types/modeler/solvers/highs/browser-runtime.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/driver.d.ts +232 -0
- package/dist/types/modeler/solvers/highs/driver.d.ts.map +1 -0
- package/dist/types/modeler/solvers/highs/index.d.ts +1 -0
- package/dist/types/modeler/solvers/highs/index.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/loader.d.ts +4 -4
- package/dist/types/modeler/solvers/highs/loader.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/node-runtime.d.ts +2 -1
- package/dist/types/modeler/solvers/highs/node-runtime.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/solver.d.ts +1 -1
- 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/types.d.ts +4 -0
- package/dist/types/modeler/solvers/types.d.ts.map +1 -1
- package/dist/types/modeler/types.d.ts +27 -0
- package/dist/types/modeler/types.d.ts.map +1 -1
- package/docs/examples/diet-sensitivity.md +15 -14
- package/docs/examples/ecommerce-coupons.md +15 -22
- package/docs/examples/index.md +18 -12
- package/docs/examples/knapsack.md +8 -7
- package/docs/examples/portfolio-qp.md +11 -4
- package/docs/examples/production.md +4 -4
- package/docs/examples/shift-scheduling.md +20 -7
- package/docs/examples/smt-security.md +16 -4
- package/docs/examples/transportation.md +46 -19
- package/docs/examples/traveling-salesperson.md +157 -0
- package/docs/examples/unsat-core.md +15 -5
- package/docs/examples/vehicle-routing.md +208 -0
- package/docs/getting-started/ai-agents.md +33 -18
- package/docs/getting-started/cross-origin.md +56 -28
- package/docs/getting-started/index.md +40 -69
- package/docs/getting-started/runtimes.md +66 -61
- package/docs/guide/constraints.md +47 -41
- package/docs/guide/decomposition.md +267 -0
- package/docs/guide/expressions.md +90 -39
- package/docs/guide/formulation-tips.md +212 -0
- package/docs/guide/objectives.md +7 -4
- package/docs/guide/unsat-core.md +28 -9
- package/docs/guide/variables.md +33 -38
- package/docs/ja/getting-started/ai-agents.md +32 -18
- package/docs/solvers/custom-solver.md +1 -1
- package/docs/solvers/highs.md +48 -5
- package/docs/solvers/index.md +4 -4
- package/docs/solvers/z3.md +3 -0
- package/docs/zh/getting-started/ai-agents.md +32 -18
- package/llms-full.txt +1536 -478
- package/llms.txt +28 -22
- package/package.json +19 -16
- package/skills/washi/SKILL.md +21 -17
- package/dist/browser/browser-runtime-D13gHOT5.js +0 -4189
- package/dist/browser/loader-CtaDHef_.js +0 -273
- package/dist/lib/loader-DmNC_UNk.js +0 -279
package/dist/lib/washi.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { A as e, C as t, D as n, E as r, M as i, N as a, O as o, S as s, T as c, _ as l, a as u, b as d, c as f, d as p, f as m, g as h, h as g, i as _, j as v, k as y, l as b, m as x, n as S, o as C, p as
|
|
2
|
-
import { a as
|
|
3
|
-
import { createHighsWorker as
|
|
1
|
+
import { A as e, C as t, D as n, E as r, M as i, N as a, O as o, S as s, T as c, _ as l, a as u, b as d, c as f, d as p, f as m, g as h, h as g, i as _, j as v, k as y, l as b, m as x, n as S, o as C, p as ee, r as w, s as T, t as E, u as D, v as O, w as k, x as A, y as te } from "./registry-D7TZ3Wh_.js";
|
|
2
|
+
import { a as j, c as M, d as ne, f as re, h as ie, i as ae, l as oe, m as se, n as ce, o as N, p as le, r as P, s as F, t as ue, u as de } from "./loader-BZUQNvh4.js";
|
|
3
|
+
import { createHighsWorker as fe } from "./highs-worker-factory.js";
|
|
4
4
|
//#region \0rolldown/runtime.js
|
|
5
|
-
var
|
|
5
|
+
var pe = Object.defineProperty, me = Object.getOwnPropertyDescriptor, he = Object.getOwnPropertyNames, ge = Object.prototype.hasOwnProperty, _e = (e, t) => {
|
|
6
6
|
let n = {};
|
|
7
|
-
for (var r in e)
|
|
7
|
+
for (var r in e) pe(n, r, {
|
|
8
8
|
get: e[r],
|
|
9
9
|
enumerable: !0
|
|
10
10
|
});
|
|
11
|
-
return t ||
|
|
12
|
-
},
|
|
13
|
-
if (t && typeof t == "object" || typeof t == "function") for (var i =
|
|
11
|
+
return t || pe(n, Symbol.toStringTag, { value: "Module" }), n;
|
|
12
|
+
}, ve = (e, t, n, r) => {
|
|
13
|
+
if (t && typeof t == "object" || typeof t == "function") for (var i = he(t), a = 0, o = i.length, s; a < o; a++) s = i[a], !ge.call(e, s) && s !== n && pe(e, s, {
|
|
14
14
|
get: ((e) => t[e]).bind(null, s),
|
|
15
|
-
enumerable: !(r =
|
|
15
|
+
enumerable: !(r = me(t, s)) || r.enumerable
|
|
16
16
|
});
|
|
17
17
|
return e;
|
|
18
|
-
},
|
|
18
|
+
}, I = (e, t, n) => (ve(e, t, "default"), n && ve(n, t, "default"));
|
|
19
19
|
//#endregion
|
|
20
20
|
//#region src/modeler/types.ts
|
|
21
|
-
function
|
|
21
|
+
function ye(e) {
|
|
22
22
|
if (e === void 0) return "Minimize";
|
|
23
23
|
if (typeof e == "string") {
|
|
24
24
|
let t = e.toLowerCase();
|
|
@@ -29,8 +29,11 @@ function le(e) {
|
|
|
29
29
|
}
|
|
30
30
|
//#endregion
|
|
31
31
|
//#region src/modeler/parser.ts
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
function L(e) {
|
|
33
|
+
return typeof e == "object" && !!e && e.kind === "container";
|
|
34
|
+
}
|
|
35
|
+
var be = /^(?:[0-9]+(?:\.[0-9]+)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;
|
|
36
|
+
function xe(e, t) {
|
|
34
37
|
let n = [], r = 0, i = e.length;
|
|
35
38
|
for (; r < i;) {
|
|
36
39
|
let a = e[r];
|
|
@@ -69,6 +72,10 @@ function de(e, t) {
|
|
|
69
72
|
type: "RPAREN",
|
|
70
73
|
value: ")"
|
|
71
74
|
}), r++;
|
|
75
|
+
else if (a === ",") n.push({
|
|
76
|
+
type: "COMMA",
|
|
77
|
+
value: ","
|
|
78
|
+
}), r++;
|
|
72
79
|
else if (a === "<" || a === ">" || a === "=") {
|
|
73
80
|
let t = a;
|
|
74
81
|
r + 1 < i && (e[r + 1] === "=" || e[r + 1] === "<" || e[r + 1] === ">") ? (t += e[r + 1], r += 2) : r++, n.push({
|
|
@@ -86,7 +93,7 @@ function de(e, t) {
|
|
|
86
93
|
for (; r < i && (e[r] === "." || e[r] === "e" || e[r] === "E" || /[0-9]/.test(e[r]));) a += e[r++];
|
|
87
94
|
}
|
|
88
95
|
} else for (; r < i && (e[r] === "." || /[0-9]/.test(e[r]));) a += e[r++];
|
|
89
|
-
if (!
|
|
96
|
+
if (!be.test(a)) throw Error(`Invalid numeric literal '${a}' at position ${t} in: "${e}"`);
|
|
90
97
|
let o = Number(a);
|
|
91
98
|
if (!Number.isFinite(o)) throw Error(`Numeric literal '${a}' overflows finite floating-point range in: "${e}"`);
|
|
92
99
|
if (o === 0 && !/^[0.]+(?:[eE][+-]?\d+)?$/.test(a)) throw Error(`Numeric literal '${a}' underflows to zero at position ${t} in: "${e}"`);
|
|
@@ -113,12 +120,205 @@ function de(e, t) {
|
|
|
113
120
|
}
|
|
114
121
|
return n;
|
|
115
122
|
}
|
|
116
|
-
|
|
123
|
+
function Se(e) {
|
|
124
|
+
return e instanceof k && e.quadTerms.size === 0 ? new A(e.linearTerms, e.constant) : e;
|
|
125
|
+
}
|
|
126
|
+
function Ce(e) {
|
|
127
|
+
return typeof e == "number" || e instanceof b || e instanceof A || e instanceof k || H(e);
|
|
128
|
+
}
|
|
129
|
+
function we(e) {
|
|
130
|
+
return typeof e == "number" ? new A(/* @__PURE__ */ new Map(), e) : e instanceof b || "id" in e && !("terms" in e) && !("quadTerms" in e) ? new A(/* @__PURE__ */ new Map([[e, 1]]), 0) : e.clone();
|
|
131
|
+
}
|
|
132
|
+
function Te(e, t, n) {
|
|
133
|
+
if (typeof e == "number" && typeof t == "number") {
|
|
134
|
+
if (n === "+") {
|
|
135
|
+
let n = e + t;
|
|
136
|
+
if (!Number.isFinite(n)) throw Error(`Invalid non-finite constant "${n}" in expression.`);
|
|
137
|
+
return n;
|
|
138
|
+
}
|
|
139
|
+
if (n === "-") {
|
|
140
|
+
let n = e - t;
|
|
141
|
+
if (!Number.isFinite(n)) throw Error(`Invalid non-finite constant "${n}" in expression.`);
|
|
142
|
+
return n;
|
|
143
|
+
}
|
|
144
|
+
if (n === "*") {
|
|
145
|
+
let n = e * t;
|
|
146
|
+
if (e !== 0 && t !== 0 && n === 0) throw Error("Constant multiplication underflows to zero.");
|
|
147
|
+
if (!Number.isFinite(n)) throw Error(`Invalid non-finite constant "${n}" in expression.`);
|
|
148
|
+
return n;
|
|
149
|
+
}
|
|
150
|
+
if (t === 0) throw Error("Division by zero");
|
|
151
|
+
let r = 1 / t * e;
|
|
152
|
+
if (e !== 0 && r === 0) throw Error("Constant multiplication underflows to zero.");
|
|
153
|
+
if (!Number.isFinite(r)) throw Error(`Invalid non-finite constant "${r}" in expression.`);
|
|
154
|
+
return r;
|
|
155
|
+
}
|
|
156
|
+
let r = we(e), i = we(t), a;
|
|
157
|
+
a = n === "+" ? r.add(i) : n === "-" ? r.sub(i) : n === "*" ? r.mul(i) : r.div(i);
|
|
158
|
+
let o = Se(a);
|
|
159
|
+
return U(o), o;
|
|
160
|
+
}
|
|
161
|
+
function R(e, t) {
|
|
162
|
+
if (Array.isArray(e)) {
|
|
163
|
+
let n = Array(e.length);
|
|
164
|
+
for (let r = 0; r < e.length; r++) {
|
|
165
|
+
let i = e[r];
|
|
166
|
+
n[r] = Ce(i) ? t(i) : R(i, t);
|
|
167
|
+
}
|
|
168
|
+
return n;
|
|
169
|
+
}
|
|
170
|
+
let n = Object.create(null);
|
|
171
|
+
for (let r of Object.keys(e)) {
|
|
172
|
+
let i = e[r];
|
|
173
|
+
n[r] = Ce(i) ? t(i) : R(i, t);
|
|
174
|
+
}
|
|
175
|
+
return n;
|
|
176
|
+
}
|
|
177
|
+
function Ee(e, t, n, r = "") {
|
|
178
|
+
let i = Ce(e), a = Ce(t);
|
|
179
|
+
if (i && a) return Te(e, t, n);
|
|
180
|
+
if (i || a) throw Error(`Dimension mismatch in template expression at '${r || "root"}': cannot combine scalar element with sub-container.`);
|
|
181
|
+
if (Array.isArray(e) || Array.isArray(t)) {
|
|
182
|
+
if (Array.isArray(e) && Array.isArray(t)) {
|
|
183
|
+
if (e.length !== t.length) throw Error(`Array length mismatch in template expression at '${r || "root"}': received lengths ${e.length} and ${t.length}.`);
|
|
184
|
+
let i = Array(e.length);
|
|
185
|
+
for (let a = 0; a < e.length; a++) i[a] = Ee(e[a], t[a], n, r ? `${r}[${a}]` : `[${a}]`);
|
|
186
|
+
return i;
|
|
187
|
+
}
|
|
188
|
+
let i = Array.isArray(e) ? e : t, a = Array.isArray(e) ? t : e, o = Object.keys(a);
|
|
189
|
+
if (o.length === i.length && o.every((e) => /^(?:0|[1-9]\d*)$/.test(e))) {
|
|
190
|
+
let o = [];
|
|
191
|
+
for (let e = 0; e < i.length; e++) Object.prototype.hasOwnProperty.call(a, e) || o.push(e);
|
|
192
|
+
if (o.length > 0) throw Error(`Key mismatch in template expression at '${r || "root"}': missing indices [${o.join(", ")}] in numeric record.`);
|
|
193
|
+
let s = Array(i.length);
|
|
194
|
+
for (let a = 0; a < i.length; a++) {
|
|
195
|
+
let i = e[a], o = t[a];
|
|
196
|
+
s[a] = Ee(i, o, n, r ? `${r}[${a}]` : `[${a}]`);
|
|
197
|
+
}
|
|
198
|
+
return s;
|
|
199
|
+
}
|
|
200
|
+
throw o.length > 0 && o.every((e) => /^(?:0|[1-9]\d*)$/.test(e)) ? Error(`Array length mismatch in template expression at '${r || "root"}': array has length ${i.length}, but object has ${o.length} indices.`) : Error(`Type mismatch in template expression at '${r || "root"}': one operand is an Array while the other is an Object with keys [${o.slice(0, 5).join(", ")}].`);
|
|
201
|
+
}
|
|
202
|
+
let o = e, s = t, c = Object.keys(o), l = Object.keys(s), u = c.filter((e) => !Object.prototype.hasOwnProperty.call(s, e)), d = l.filter((e) => !Object.prototype.hasOwnProperty.call(o, e));
|
|
203
|
+
if (u.length > 0 || d.length > 0) {
|
|
204
|
+
let e = [];
|
|
205
|
+
throw u.length > 0 && e.push(`missing in second operand: [${u.join(", ")}]`), d.length > 0 && e.push(`missing in first operand: [${d.join(", ")}]`), Error(`Key mismatch in template expression at '${r || "root"}': ${e.join("; ")}.`);
|
|
206
|
+
}
|
|
207
|
+
let f = Object.create(null);
|
|
208
|
+
for (let e of c) f[e] = Ee(o[e], s[e], n, r ? `${r}.${e}` : e);
|
|
209
|
+
return f;
|
|
210
|
+
}
|
|
211
|
+
function z(e, t, n) {
|
|
212
|
+
let r = L(e), i = L(t);
|
|
213
|
+
if (!r && !i) return Te(e, t, n);
|
|
214
|
+
if (r && !i) return {
|
|
215
|
+
kind: "container",
|
|
216
|
+
data: R(e.data, (e) => Te(e, t, n)),
|
|
217
|
+
fromNonArrayIterable: e.fromNonArrayIterable
|
|
218
|
+
};
|
|
219
|
+
if (!r && i) return {
|
|
220
|
+
kind: "container",
|
|
221
|
+
data: R(t.data, (t) => Te(e, t, n)),
|
|
222
|
+
fromNonArrayIterable: t.fromNonArrayIterable
|
|
223
|
+
};
|
|
224
|
+
let a = e, o = t;
|
|
225
|
+
return {
|
|
226
|
+
kind: "container",
|
|
227
|
+
data: Ee(a.data, o.data, n),
|
|
228
|
+
fromNonArrayIterable: a.fromNonArrayIterable || o.fromNonArrayIterable
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function De(e) {
|
|
232
|
+
return typeof e == "number" ? -e : L(e) ? {
|
|
233
|
+
kind: "container",
|
|
234
|
+
data: R(e.data, (e) => typeof e == "number" ? -e : we(e).neg()),
|
|
235
|
+
fromNonArrayIterable: e.fromNonArrayIterable
|
|
236
|
+
} : e.neg();
|
|
237
|
+
}
|
|
238
|
+
function Oe(e, t) {
|
|
239
|
+
let n = e instanceof k, r = n ? e.quadTerms.size : 0, i = n ? e.linearTerms.size : e.terms.size;
|
|
240
|
+
if (r === 0 && i === 0) {
|
|
241
|
+
let n = e.constant ** +t;
|
|
242
|
+
if (e.constant !== 0 && t > 0 && n === 0) throw Error("Constant exponentiation underflows to zero.");
|
|
243
|
+
return new A(/* @__PURE__ */ new Map(), n);
|
|
244
|
+
}
|
|
245
|
+
if (t === 0) return new A(/* @__PURE__ */ new Map(), 1);
|
|
246
|
+
if (t === 1) return e;
|
|
247
|
+
if (t === 2) return e.mul(e);
|
|
248
|
+
throw Error(`Exponent ${t} creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)`);
|
|
249
|
+
}
|
|
250
|
+
function B(e) {
|
|
251
|
+
if (typeof e != "object" || !e || Array.isArray(e) || H(e) || W(e)) return !1;
|
|
252
|
+
let t = Object.getPrototypeOf(e);
|
|
253
|
+
return t === Object.prototype || t === null;
|
|
254
|
+
}
|
|
255
|
+
function ke(e) {
|
|
256
|
+
if (typeof e == "number") {
|
|
257
|
+
if (!Number.isFinite(e)) throw Error(`Invalid numeric value "${e}" in template expression: interpolated numbers must be finite.`);
|
|
258
|
+
return e;
|
|
259
|
+
}
|
|
260
|
+
if (W(e)) throw Error("Cannot interpolate a constraint comparison (<=, >=, ==) inside a template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
261
|
+
if (H(e)) return U(e), e instanceof b || "id" in e && !("terms" in e) && !("quadTerms" in e) ? e : e.clone();
|
|
262
|
+
throw Error("Unsupported interpolation value in template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
263
|
+
}
|
|
264
|
+
function V(e) {
|
|
265
|
+
return typeof e == "object" && !!e && !(e instanceof String) && !(e instanceof Map) && !H(e) && !W(e) && Symbol.iterator in e && typeof e[Symbol.iterator] == "function";
|
|
266
|
+
}
|
|
267
|
+
function Ae(e, t = 0) {
|
|
268
|
+
if (Array.isArray(e)) {
|
|
269
|
+
let n = !1, r = Array(e.length);
|
|
270
|
+
for (let i = 0; i < e.length; i++) {
|
|
271
|
+
if (!(i in e)) throw Error(`Unsupported interpolation value in template expression: sparse array hole at index ${i}.`);
|
|
272
|
+
let a = e[i];
|
|
273
|
+
if (Array.isArray(a) || B(a) || V(a)) {
|
|
274
|
+
if (t >= 1) throw Error("Nested containers deeper than 2D are not supported in template expressions.");
|
|
275
|
+
let e = Ae(a, t + 1);
|
|
276
|
+
e.fromNonArrayIterable && (n = !0), r[i] = e.data;
|
|
277
|
+
} else r[i] = ke(a);
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
kind: "container",
|
|
281
|
+
data: r,
|
|
282
|
+
fromNonArrayIterable: n
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
if (V(e)) return {
|
|
286
|
+
kind: "container",
|
|
287
|
+
data: Array.from(e).map((e) => {
|
|
288
|
+
if (Array.isArray(e) || B(e) || V(e)) {
|
|
289
|
+
if (t >= 1) throw Error("Nested containers deeper than 2D are not supported in template expressions.");
|
|
290
|
+
return Ae(e, t + 1).data;
|
|
291
|
+
}
|
|
292
|
+
return ke(e);
|
|
293
|
+
}),
|
|
294
|
+
fromNonArrayIterable: !0
|
|
295
|
+
};
|
|
296
|
+
if (B(e)) {
|
|
297
|
+
if (Object.getOwnPropertySymbols(e).length > 0) throw Error("Symbol keys are not supported in template expression at 'root'.");
|
|
298
|
+
let n = !1, r = Object.create(null);
|
|
299
|
+
for (let i of Object.keys(e)) {
|
|
300
|
+
let a = e[i];
|
|
301
|
+
if (Array.isArray(a) || B(a) || V(a)) {
|
|
302
|
+
if (t >= 1) throw Error("Nested containers deeper than 2D are not supported in template expressions.");
|
|
303
|
+
let e = Ae(a, t + 1);
|
|
304
|
+
e.fromNonArrayIterable && (n = !0), r[i] = e.data;
|
|
305
|
+
} else r[i] = ke(a);
|
|
306
|
+
}
|
|
307
|
+
return {
|
|
308
|
+
kind: "container",
|
|
309
|
+
data: r,
|
|
310
|
+
fromNonArrayIterable: n
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
throw Error("Unsupported interpolation value in template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
314
|
+
}
|
|
315
|
+
var je = class {
|
|
117
316
|
tokens;
|
|
118
317
|
pos = 0;
|
|
119
318
|
resolver;
|
|
120
|
-
|
|
121
|
-
|
|
319
|
+
templateCtx;
|
|
320
|
+
constructor(e, t, n) {
|
|
321
|
+
this.tokens = e, this.resolver = t, this.templateCtx = n;
|
|
122
322
|
}
|
|
123
323
|
peek() {
|
|
124
324
|
return this.tokens[this.pos];
|
|
@@ -130,54 +330,240 @@ var fe = class {
|
|
|
130
330
|
return t;
|
|
131
331
|
}
|
|
132
332
|
parseExpression() {
|
|
133
|
-
let e = this.
|
|
333
|
+
let e = this.parseExpressionNode();
|
|
334
|
+
if (L(e)) throw Error("Container expression (Array or Record) cannot be used directly as a scalar expression or constraint; wrap it in sum(...) or use dot(a, b).");
|
|
335
|
+
return typeof e == "number" ? new A(/* @__PURE__ */ new Map(), e) : Se(e);
|
|
336
|
+
}
|
|
337
|
+
parseExpressionNode() {
|
|
338
|
+
let e = this.parseTermNode();
|
|
134
339
|
for (; this.pos < this.tokens.length;) {
|
|
135
340
|
let t = this.peek();
|
|
136
341
|
if (!t) break;
|
|
137
|
-
if (t.type === "PLUS") this.consume(), e = e
|
|
138
|
-
else if (t.type === "MINUS") this.consume(), e = e
|
|
342
|
+
if (t.type === "PLUS") this.consume(), e = z(e, this.parseTermNode(), "+");
|
|
343
|
+
else if (t.type === "MINUS") this.consume(), e = z(e, this.parseTermNode(), "-");
|
|
139
344
|
else break;
|
|
140
345
|
}
|
|
141
|
-
return e
|
|
346
|
+
return L(e) || typeof e == "number" ? e : Se(e);
|
|
142
347
|
}
|
|
143
|
-
|
|
144
|
-
let e = this.
|
|
348
|
+
parseTermNode() {
|
|
349
|
+
let e = this.parseFactorNode();
|
|
145
350
|
for (; this.pos < this.tokens.length;) {
|
|
146
351
|
let t = this.peek();
|
|
147
352
|
if (!t) break;
|
|
148
|
-
if (t.type === "STAR") this.consume(), e = e
|
|
149
|
-
else if (t.type === "SLASH") this.consume(), e = e
|
|
353
|
+
if (t.type === "STAR") this.consume(), e = z(e, this.parseFactorNode(), "*");
|
|
354
|
+
else if (t.type === "SLASH") this.consume(), e = z(e, this.parseFactorNode(), "/");
|
|
150
355
|
else break;
|
|
151
356
|
}
|
|
152
357
|
return e;
|
|
153
358
|
}
|
|
154
|
-
|
|
359
|
+
parseFactorNode() {
|
|
155
360
|
let e = this.peek();
|
|
156
361
|
if (!e) throw Error("Unexpected end of expression");
|
|
157
|
-
if (e.type === "PLUS") return this.consume(), this.
|
|
158
|
-
if (e.type === "MINUS") return this.consume(), this.
|
|
362
|
+
if (e.type === "PLUS") return this.consume(), this.parseFactorNode();
|
|
363
|
+
if (e.type === "MINUS") return this.consume(), De(this.parseFactorNode());
|
|
159
364
|
let t;
|
|
160
365
|
if (e.type === "NUMBER") {
|
|
161
366
|
this.consume();
|
|
162
367
|
let n = e.numericValue ?? Number(e.value);
|
|
163
368
|
if (this.peek()?.type === "IDENT" || this.peek()?.type === "LPAREN") {
|
|
164
|
-
let e;
|
|
165
|
-
|
|
166
|
-
let t = this.consume(), n = this.resolve(t.value);
|
|
167
|
-
e = n instanceof b || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new j(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
|
|
168
|
-
} else this.consume("LPAREN"), e = this.parseExpression(), this.consume("RPAREN");
|
|
169
|
-
return this.applyPower(e).mul(n);
|
|
369
|
+
let e = this.parsePrimaryNode();
|
|
370
|
+
return z(this.applyPowerNode(e), n, "*");
|
|
170
371
|
}
|
|
171
|
-
t =
|
|
172
|
-
} else if (e.type === "IDENT")
|
|
173
|
-
this.consume();
|
|
174
|
-
let n = this.resolve(e.value);
|
|
175
|
-
t = n instanceof b || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new j(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
|
|
176
|
-
} else if (e.type === "LPAREN") this.consume("LPAREN"), t = this.parseExpression(), this.consume("RPAREN");
|
|
372
|
+
t = n;
|
|
373
|
+
} else if (e.type === "IDENT" || e.type === "LPAREN") t = this.parsePrimaryNode();
|
|
177
374
|
else throw Error(`Unexpected token '${e.value}' in expression`);
|
|
178
|
-
return this.
|
|
375
|
+
return this.applyPowerNode(t);
|
|
376
|
+
}
|
|
377
|
+
parsePrimaryNode() {
|
|
378
|
+
if (this.peek()?.type === "IDENT") {
|
|
379
|
+
let e = this.consume();
|
|
380
|
+
return (e.value === "sum" || e.value === "dot") && this.peek()?.type === "LPAREN" ? this.parseFunctionCall(e.value) : this.resolveNode(e.value);
|
|
381
|
+
}
|
|
382
|
+
this.consume("LPAREN");
|
|
383
|
+
let e = this.parseExpressionNode();
|
|
384
|
+
return this.consume("RPAREN"), e;
|
|
385
|
+
}
|
|
386
|
+
parseFunctionCall(e) {
|
|
387
|
+
this.consume("LPAREN");
|
|
388
|
+
let t = 1;
|
|
389
|
+
for (let n = this.pos; n < this.tokens.length && t > 0; n++) {
|
|
390
|
+
let r = this.tokens[n];
|
|
391
|
+
if (r.type === "LPAREN") t++;
|
|
392
|
+
else if (r.type === "RPAREN") t--;
|
|
393
|
+
else if (r.type === "COMP") throw Error(e === "sum" ? "Cannot sum a constraint comparison (<=, >=, ==) in sum(): expected a number, Var, LinExpr, or QuadExpr." : "Cannot use a constraint comparison (<=, >=, ==) in dot(): expected 1D or 2D Array or Record containers.");
|
|
394
|
+
}
|
|
395
|
+
if (this.peek()?.type === "RPAREN") throw this.consume("RPAREN"), Error(e === "sum" ? "sum() in template expression requires at least 1 argument." : "dot() in template expression requires exactly 2 arguments: dot(a, b).");
|
|
396
|
+
if (e === "sum") {
|
|
397
|
+
if (this.tokens[this.pos]?.type === "IDENT" && this.templateCtx?.rawContainerMap.has(this.tokens[this.pos].value) && this.tokens[this.pos + 1]?.type === "RPAREN") {
|
|
398
|
+
let e = this.consume();
|
|
399
|
+
this.consume("RPAREN");
|
|
400
|
+
let t = this.templateCtx.rawContainerMap.get(e.value);
|
|
401
|
+
return this.accumulateSumItems((e) => {
|
|
402
|
+
e(t, 0);
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
let e = this.pos, t = 0;
|
|
406
|
+
for (; this.tokens[e]?.type === "LPAREN";) t++, e++;
|
|
407
|
+
if (this.tokens[e]?.type === "IDENT" && this.templateCtx?.rawContainerMap.has(this.tokens[e].value)) {
|
|
408
|
+
let n = this.tokens[e].value, r = e + 1, i = 0;
|
|
409
|
+
for (; i < t && this.tokens[r]?.type === "RPAREN";) i++, r++;
|
|
410
|
+
if (i === t && this.tokens[r]?.type === "COMMA") {
|
|
411
|
+
this.pos = r + 1;
|
|
412
|
+
let e = this.peek();
|
|
413
|
+
if (!e || e.type !== "IDENT" || !this.templateCtx.functionMap.has(e.value)) throw Error("Second argument to sum() must be a mapping function: sum(itemsOrCount, mapFn).");
|
|
414
|
+
if (this.consume(), this.peek()?.type === "COMMA") throw Error("sum() in template expression accepts at most 2 arguments: sum(container) or sum(itemsOrCount, mapFn).");
|
|
415
|
+
return this.consume("RPAREN"), this.evalSumWithMapper(this.templateCtx.rawContainerMap.get(n), this.templateCtx.functionMap.get(e.value));
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
let n = this.parseExpressionNode();
|
|
419
|
+
if (this.peek()?.type === "COMMA") {
|
|
420
|
+
this.consume("COMMA");
|
|
421
|
+
let e = this.peek();
|
|
422
|
+
if (!e || e.type !== "IDENT" || !this.templateCtx?.functionMap.has(e.value)) throw Error("Second argument to sum() must be a mapping function: sum(itemsOrCount, mapFn).");
|
|
423
|
+
if (this.consume(), this.peek()?.type === "COMMA") throw Error("sum() in template expression accepts at most 2 arguments: sum(container) or sum(itemsOrCount, mapFn).");
|
|
424
|
+
this.consume("RPAREN");
|
|
425
|
+
let t = this.templateCtx.functionMap.get(e.value);
|
|
426
|
+
if (typeof n == "number") return this.evalSumWithMapper(n, t);
|
|
427
|
+
if (!L(n) && n instanceof A && n.terms.size === 0) return this.evalSumWithMapper(n.constant, t);
|
|
428
|
+
if (L(n)) return this.evalSumWithMapper(n.data, t);
|
|
429
|
+
throw Error("Invalid first argument in sum(itemsOrCount, mapFn): expected an Iterable, Record, or non-negative integer count.");
|
|
430
|
+
}
|
|
431
|
+
return this.consume("RPAREN"), this.evalSumSingle(n);
|
|
432
|
+
}
|
|
433
|
+
let n = this.parseExpressionNode();
|
|
434
|
+
if (this.peek()?.type !== "COMMA") throw Error("dot() in template expression requires exactly 2 arguments: dot(a, b).");
|
|
435
|
+
this.consume("COMMA");
|
|
436
|
+
let r = this.parseExpressionNode();
|
|
437
|
+
if (this.peek()?.type === "COMMA") throw Error("dot() in template expression requires exactly 2 arguments: dot(a, b).");
|
|
438
|
+
return this.consume("RPAREN"), this.evalDot(n, r);
|
|
439
|
+
}
|
|
440
|
+
accumulateSumItems(e) {
|
|
441
|
+
let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), r = 0, i = (e, a = 0) => {
|
|
442
|
+
if (e != null) {
|
|
443
|
+
if (typeof e == "number") {
|
|
444
|
+
if (!Number.isFinite(e)) throw Error(`Invalid non-finite number "${e}" in sum().`);
|
|
445
|
+
let t = r + e;
|
|
446
|
+
if (!Number.isFinite(t)) throw Error("Constant accumulation overflows finite floating-point range in sum().");
|
|
447
|
+
r = t;
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
if (W(e)) throw Error("Cannot sum a constraint comparison (<=, >=, ==) in sum(): expected a number, Var, LinExpr, or QuadExpr.");
|
|
451
|
+
if (e instanceof k || typeof e == "object" && e && "quadTerms" in e && e.quadTerms instanceof Map && "linearTerms" in e && e.linearTerms instanceof Map) {
|
|
452
|
+
let i = e;
|
|
453
|
+
U(i);
|
|
454
|
+
let a = r + i.constant;
|
|
455
|
+
if (!Number.isFinite(a)) throw Error("Constant accumulation overflows finite floating-point range in sum().");
|
|
456
|
+
r = a;
|
|
457
|
+
for (let [e, n] of i.linearTerms) {
|
|
458
|
+
let r = (t.get(e) ?? 0) + n;
|
|
459
|
+
if (!Number.isFinite(r)) throw Error("Coefficient accumulation overflows finite floating-point range in sum().");
|
|
460
|
+
t.set(e, r);
|
|
461
|
+
}
|
|
462
|
+
for (let [e, t] of i.quadTerms) {
|
|
463
|
+
let r = n.get(e);
|
|
464
|
+
if (r) {
|
|
465
|
+
let i = r.coeff + t.coeff;
|
|
466
|
+
if (!Number.isFinite(i)) throw Error("Quadratic coefficient accumulation overflows finite floating-point range in sum().");
|
|
467
|
+
n.set(e, {
|
|
468
|
+
var1: t.var1,
|
|
469
|
+
var2: t.var2,
|
|
470
|
+
coeff: i
|
|
471
|
+
});
|
|
472
|
+
} else n.set(e, {
|
|
473
|
+
var1: t.var1,
|
|
474
|
+
var2: t.var2,
|
|
475
|
+
coeff: t.coeff
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
if (e instanceof A || typeof e == "object" && e && "terms" in e && e.terms instanceof Map && typeof e.constant == "number") {
|
|
481
|
+
let n = e;
|
|
482
|
+
U(n);
|
|
483
|
+
let i = r + n.constant;
|
|
484
|
+
if (!Number.isFinite(i)) throw Error("Constant accumulation overflows finite floating-point range in sum().");
|
|
485
|
+
r = i;
|
|
486
|
+
for (let [e, r] of n.terms) {
|
|
487
|
+
let n = (t.get(e) ?? 0) + r;
|
|
488
|
+
if (!Number.isFinite(n)) throw Error("Coefficient accumulation overflows finite floating-point range in sum().");
|
|
489
|
+
t.set(e, n);
|
|
490
|
+
}
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
if (H(e)) {
|
|
494
|
+
let n = e, r = (t.get(n) ?? 0) + 1;
|
|
495
|
+
if (!Number.isFinite(r)) throw Error("Coefficient accumulation overflows finite floating-point range in sum().");
|
|
496
|
+
t.set(n, r);
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
if (Array.isArray(e)) {
|
|
500
|
+
if (a >= 2) throw Error("Nested containers deeper than 2D are not supported in sum().");
|
|
501
|
+
for (let t = 0; t < e.length; t++) {
|
|
502
|
+
if (!(t in e)) throw Error(`Unsupported item in sum(): sparse array hole at index ${t}.`);
|
|
503
|
+
i(e[t], a + 1);
|
|
504
|
+
}
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
if (V(e)) {
|
|
508
|
+
if (a >= 2) throw Error("Nested containers deeper than 2D are not supported in sum().");
|
|
509
|
+
for (let t of e) i(t, a + 1);
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
if (B(e)) {
|
|
513
|
+
if (a >= 2) throw Error("Nested containers deeper than 2D are not supported in sum().");
|
|
514
|
+
if (Object.getOwnPropertySymbols(e).length > 0) throw Error("Symbol keys are not supported in sum().");
|
|
515
|
+
for (let t of Object.keys(e)) i(e[t], a + 1);
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
throw Error("Unsupported item in sum(): expected a number, Var, LinExpr, or QuadExpr.");
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
e(i);
|
|
522
|
+
for (let [e, n] of t) n === 0 && t.delete(e);
|
|
523
|
+
for (let [e, t] of n) t.coeff === 0 && n.delete(e);
|
|
524
|
+
return n.size > 0 ? new k(t, n, r) : new A(t, r);
|
|
525
|
+
}
|
|
526
|
+
evalSumSingle(e) {
|
|
527
|
+
if (!L(e)) throw Error("sum() requires a container (Array, Iterable, or Record) or (itemsOrCount, mapFn).");
|
|
528
|
+
return this.accumulateSumItems((t) => {
|
|
529
|
+
t(e.data, 0);
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
evalSumWithMapper(e, t) {
|
|
533
|
+
return this.accumulateSumItems((n) => {
|
|
534
|
+
if (typeof e == "number") {
|
|
535
|
+
if (!Number.isInteger(e) || e < 0) throw Error("sum(count, mapFn) requires a non-negative integer count.");
|
|
536
|
+
for (let r = 0; r < e; r++) n(t(r, r));
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
if (Array.isArray(e)) {
|
|
540
|
+
for (let r = 0; r < e.length; r++) {
|
|
541
|
+
if (!(r in e)) throw Error(`Unsupported item in sum(): sparse array hole at index ${r}.`);
|
|
542
|
+
n(t(e[r], r));
|
|
543
|
+
}
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
if (typeof e == "object" && e && !(e instanceof String) && Symbol.iterator in e && typeof e[Symbol.iterator] == "function") {
|
|
547
|
+
let r = 0;
|
|
548
|
+
for (let i of e) n(t(i, r++));
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
if (B(e)) {
|
|
552
|
+
if (Object.getOwnPropertySymbols(e).length > 0) throw Error("Symbol keys are not supported in sum().");
|
|
553
|
+
let r = 0;
|
|
554
|
+
for (let i of Object.keys(e)) n(t(e[i], r++));
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
throw Error("Invalid first argument in sum(itemsOrCount, mapFn): expected an Iterable, Record, or non-negative integer count.");
|
|
558
|
+
});
|
|
179
559
|
}
|
|
180
|
-
|
|
560
|
+
evalDot(e, t) {
|
|
561
|
+
if (!L(e) || !L(t)) throw Error("dot() in template expression requires 1D or 2D Array or Record containers as arguments.");
|
|
562
|
+
if (e.fromNonArrayIterable || t.fromNonArrayIterable) throw Error("Unsupported operand types in dot() at 'root': dot() requires Array or Record containers (use sum() for general Iterables).");
|
|
563
|
+
let n = s(e.data, t.data);
|
|
564
|
+
return U(n), n;
|
|
565
|
+
}
|
|
566
|
+
applyPowerNode(e) {
|
|
181
567
|
if (this.peek()?.type !== "CARET") return e;
|
|
182
568
|
let t = [];
|
|
183
569
|
for (; this.peek()?.type === "CARET";) {
|
|
@@ -194,55 +580,87 @@ var fe = class {
|
|
|
194
580
|
let n = t[t.length - 1];
|
|
195
581
|
for (let e = t.length - 2; e >= 0; e--) n = t[e] ** +n;
|
|
196
582
|
if (!Number.isFinite(n) || n < 0) throw Error("Exponent creates an invalid or out-of-range power");
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
if (
|
|
201
|
-
return
|
|
583
|
+
if (typeof e == "number") {
|
|
584
|
+
let t = e ** +n;
|
|
585
|
+
if (e !== 0 && n > 0 && t === 0) throw Error("Constant exponentiation underflows to zero.");
|
|
586
|
+
if (!Number.isFinite(t)) throw Error(`Invalid non-finite constant "${t}" in expression.`);
|
|
587
|
+
return t;
|
|
202
588
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
589
|
+
return L(e) ? {
|
|
590
|
+
kind: "container",
|
|
591
|
+
data: R(e.data, (e) => {
|
|
592
|
+
if (typeof e == "number") {
|
|
593
|
+
let t = e ** +n;
|
|
594
|
+
if (e !== 0 && n > 0 && t === 0) throw Error("Constant exponentiation underflows to zero.");
|
|
595
|
+
if (!Number.isFinite(t)) throw Error("Constant exponentiation overflows finite floating-point range.");
|
|
596
|
+
return t;
|
|
597
|
+
}
|
|
598
|
+
let t = Se(Oe(we(e), n));
|
|
599
|
+
return U(t), t;
|
|
600
|
+
}),
|
|
601
|
+
fromNonArrayIterable: e.fromNonArrayIterable
|
|
602
|
+
} : Oe(e, n);
|
|
207
603
|
}
|
|
208
604
|
getRemainingToken() {
|
|
209
605
|
return this.peek();
|
|
210
606
|
}
|
|
211
|
-
|
|
607
|
+
resolveNode(e) {
|
|
608
|
+
if (this.templateCtx?.functionMap.has(e)) throw Error("Function interpolation is only supported as the second argument of sum(itemsOrCount, mapFn) in template expressions.");
|
|
609
|
+
if (this.templateCtx?.rawContainerMap.has(e)) return Ae(this.templateCtx.rawContainerMap.get(e));
|
|
212
610
|
let t = this.resolver(e);
|
|
213
611
|
if (!t) throw Error(`Unknown variable '${e}' in expression`);
|
|
214
|
-
return t;
|
|
612
|
+
return t instanceof b || "id" in t && !("terms" in t) && !("quadTerms" in t) ? new A(/* @__PURE__ */ new Map([[t, 1]]), 0) : t.clone();
|
|
215
613
|
}
|
|
216
614
|
};
|
|
217
|
-
function
|
|
218
|
-
let
|
|
219
|
-
if (
|
|
220
|
-
return
|
|
615
|
+
function Me(e, t, n, r) {
|
|
616
|
+
let i = new je(xe(e, n), t, r), a = i.parseExpression(), o = i.getRemainingToken();
|
|
617
|
+
if (o) throw Error(`Unexpected token '${o.value}' after expression in "${e}"`);
|
|
618
|
+
return U(a), a;
|
|
221
619
|
}
|
|
222
|
-
function
|
|
223
|
-
return
|
|
620
|
+
function Ne(e, t) {
|
|
621
|
+
return Me(e, t);
|
|
224
622
|
}
|
|
225
|
-
function
|
|
226
|
-
let
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
623
|
+
function Pe(e) {
|
|
624
|
+
let t = 0;
|
|
625
|
+
for (let n = 0; n < e.length; n++) {
|
|
626
|
+
let r = e[n];
|
|
627
|
+
if (r === "(") t++;
|
|
628
|
+
else if (r === ")") t > 0 && t--;
|
|
629
|
+
else if (t === 0) {
|
|
630
|
+
let t = e.slice(n, n + 2);
|
|
631
|
+
if (t === "<=" || t === ">=" || t === "==" || t === "=<" || t === "=>") return {
|
|
632
|
+
rawOp: t,
|
|
633
|
+
index: n
|
|
634
|
+
};
|
|
635
|
+
if (r === "=") return {
|
|
636
|
+
rawOp: "=",
|
|
637
|
+
index: n
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
return null;
|
|
238
642
|
}
|
|
239
|
-
function
|
|
240
|
-
|
|
643
|
+
function Fe(e, t, n, r, i) {
|
|
644
|
+
let a = Pe(e);
|
|
645
|
+
if (!a) throw Error(`Constraint must contain a comparison operator (<=, >=, ==, =): "${e}"`);
|
|
646
|
+
let o = a.rawOp, s = a.index, c = e.substring(0, s).trim(), l = e.substring(s + o.length).trim(), u;
|
|
647
|
+
if (o === "<=" || o === "=<") u = "<=";
|
|
648
|
+
else if (o === ">=" || o === "=>") u = ">=";
|
|
649
|
+
else if (o === "==" || o === "=") u = "==";
|
|
650
|
+
else throw Error(`Unsupported operator "${o}"`);
|
|
651
|
+
let d = Me(c, t, r, i), f = Me(l, t, r, i);
|
|
652
|
+
if (d instanceof k && d.quadTerms.size > 0 || f instanceof k && f.quadTerms.size > 0) throw Error("Quadratic constraints are not supported (only linear constraints are allowed in MILP/LP/QP)");
|
|
653
|
+
let p = d instanceof k ? new A(d.linearTerms, d.constant) : d, m = f instanceof k ? new A(f.linearTerms, f.constant) : f, h;
|
|
654
|
+
if (h = u === "<=" ? p.le(m, n) : u === ">=" ? p.ge(m, n) : p.eq(m, n), U(h.lhs), !Number.isFinite(h.rhs)) throw Error(`Invalid non-finite right-hand side "${h.rhs}" in constraint.`);
|
|
655
|
+
return h;
|
|
241
656
|
}
|
|
242
|
-
function
|
|
243
|
-
return e
|
|
657
|
+
function Ie(e, t, n) {
|
|
658
|
+
return Fe(e, t, n);
|
|
659
|
+
}
|
|
660
|
+
function H(e) {
|
|
661
|
+
return e instanceof b || e instanceof A || e instanceof k ? !0 : typeof e != "object" || !e || W(e) ? !1 : "terms" in e && e.terms instanceof Map && typeof e.constant == "number" || "quadTerms" in e && e.quadTerms instanceof Map && "linearTerms" in e && e.linearTerms instanceof Map && typeof e.constant == "number" || typeof e.id == "number" && typeof e.name == "string" && typeof e.lb == "number" && typeof e.ub == "number" && typeof e.type == "string" && typeof e.mul == "function";
|
|
244
662
|
}
|
|
245
|
-
function
|
|
663
|
+
function U(e) {
|
|
246
664
|
if ("constant" in e && !Number.isFinite(e.constant)) throw Error(`Invalid non-finite constant "${e.constant}" in expression.`);
|
|
247
665
|
if ("terms" in e && e.terms instanceof Map) {
|
|
248
666
|
for (let [, t] of e.terms) if (!Number.isFinite(t)) throw Error(`Invalid non-finite coefficient "${t}" in expression.`);
|
|
@@ -254,40 +672,50 @@ function _e(e) {
|
|
|
254
672
|
for (let [, t] of e.quadTerms) if (!Number.isFinite(t.coeff)) throw Error(`Invalid non-finite quadratic coefficient "${t.coeff}" in expression.`);
|
|
255
673
|
}
|
|
256
674
|
}
|
|
257
|
-
function
|
|
258
|
-
return e instanceof c
|
|
675
|
+
function W(e) {
|
|
676
|
+
return e instanceof c ? !0 : typeof e != "object" || !e ? !1 : e.kind === "constraint" || "sense" in e && (e.sense === "<=" || e.sense === ">=" || e.sense === "==") && "lhs" in e && "rhs" in e && typeof e.rhs == "number" && typeof e.lhs == "object" && e.lhs !== null && "terms" in e.lhs && e.lhs.terms instanceof Map;
|
|
259
677
|
}
|
|
260
|
-
function
|
|
261
|
-
let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), i = e.join(""),
|
|
262
|
-
for (;
|
|
263
|
-
let
|
|
264
|
-
for (let
|
|
265
|
-
let e = t[
|
|
678
|
+
function Le(e, t) {
|
|
679
|
+
let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map(), o = e.join(""), s = "__washi_";
|
|
680
|
+
for (; o.includes(s);) s += "_";
|
|
681
|
+
let c = "";
|
|
682
|
+
for (let o = 0; o < e.length; o++) if (c += e[o], o < t.length) {
|
|
683
|
+
let e = t[o];
|
|
266
684
|
if (typeof e == "number") {
|
|
267
685
|
if (!Number.isFinite(e)) throw Error(`Invalid numeric value "${e}" in template expression: interpolated numbers must be finite.`);
|
|
268
|
-
let t = `${
|
|
269
|
-
r.set(t, e),
|
|
270
|
-
} else if (
|
|
271
|
-
else if (
|
|
272
|
-
|
|
273
|
-
let t = `${
|
|
274
|
-
n.set(t, e),
|
|
686
|
+
let t = `${s}num_${o}__`;
|
|
687
|
+
r.set(t, e), c += `(${t})`;
|
|
688
|
+
} else if (W(e)) throw Error("Cannot interpolate a constraint comparison (<=, >=, ==) inside a template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
689
|
+
else if (H(e)) {
|
|
690
|
+
U(e);
|
|
691
|
+
let t = `${s}ph_${o}__`;
|
|
692
|
+
n.set(t, e), c += ` ${t} `;
|
|
693
|
+
} else if (typeof e == "function") {
|
|
694
|
+
let t = `${s}fn_${o}__`;
|
|
695
|
+
a.set(t, e), c += ` ${t} `;
|
|
696
|
+
} else if (Array.isArray(e) || V(e) || e instanceof Map || B(e)) {
|
|
697
|
+
let t = `${s}ph_${o}__`;
|
|
698
|
+
i.set(t, e), c += ` ${t} `;
|
|
275
699
|
} else throw Error("Unsupported interpolation value in template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
276
700
|
}
|
|
277
701
|
return {
|
|
278
|
-
fullText:
|
|
702
|
+
fullText: c,
|
|
279
703
|
resolver: (e) => n.get(e),
|
|
280
|
-
numberMap: r
|
|
704
|
+
numberMap: r,
|
|
705
|
+
templateCtx: {
|
|
706
|
+
rawContainerMap: i,
|
|
707
|
+
functionMap: a
|
|
708
|
+
}
|
|
281
709
|
};
|
|
282
710
|
}
|
|
283
|
-
function
|
|
284
|
-
let { fullText: n, resolver: r, numberMap: i } =
|
|
285
|
-
return
|
|
711
|
+
function Re(e, ...t) {
|
|
712
|
+
let { fullText: n, resolver: r, numberMap: i, templateCtx: a } = Le(e, t);
|
|
713
|
+
return Pe(n) ? Fe(n, r, void 0, i, a) : Me(n, r, i, a);
|
|
286
714
|
}
|
|
287
715
|
//#endregion
|
|
288
716
|
//#region src/modeler/solvers/highs/worker-client.ts
|
|
289
|
-
var
|
|
290
|
-
function
|
|
717
|
+
var G = null, ze = 0, K = /* @__PURE__ */ new Map();
|
|
718
|
+
function Be(e, t) {
|
|
291
719
|
return e ? {
|
|
292
720
|
Status: "Interrupted",
|
|
293
721
|
StatusCode: 17,
|
|
@@ -311,8 +739,8 @@ function Se(e, t) {
|
|
|
311
739
|
Rows: []
|
|
312
740
|
};
|
|
313
741
|
}
|
|
314
|
-
function
|
|
315
|
-
let t =
|
|
742
|
+
function Ve(e) {
|
|
743
|
+
let t = K.values().next().value;
|
|
316
744
|
if (t && !t.dispatched) {
|
|
317
745
|
t.dispatched = !0;
|
|
318
746
|
try {
|
|
@@ -324,30 +752,30 @@ function U(e) {
|
|
|
324
752
|
...t.reportProgress ? { reportProgress: !0 } : {}
|
|
325
753
|
});
|
|
326
754
|
} catch (n) {
|
|
327
|
-
|
|
755
|
+
K.delete(t.id), t.cleanupAbort?.(), t.reject(n), Ve(e);
|
|
328
756
|
}
|
|
329
757
|
}
|
|
330
758
|
}
|
|
331
|
-
function
|
|
332
|
-
let e =
|
|
333
|
-
e && (
|
|
334
|
-
for (let e of
|
|
335
|
-
if (
|
|
336
|
-
let e =
|
|
337
|
-
if (e)
|
|
759
|
+
function He() {
|
|
760
|
+
let e = G;
|
|
761
|
+
e && (G = null, e.terminate());
|
|
762
|
+
for (let e of K.values()) e.dispatched = !1;
|
|
763
|
+
if (K.size > 0) {
|
|
764
|
+
let e = Ue();
|
|
765
|
+
if (e) Ve(e);
|
|
338
766
|
else {
|
|
339
767
|
let e = /* @__PURE__ */ Error("[WaSHI] Failed to recreate HiGHS Worker after interruption.");
|
|
340
|
-
for (let t of Array.from(
|
|
768
|
+
for (let t of Array.from(K.values())) K.delete(t.id), t.cleanupAbort?.(), t.reject(e);
|
|
341
769
|
}
|
|
342
770
|
}
|
|
343
771
|
}
|
|
344
|
-
function
|
|
772
|
+
function Ue() {
|
|
345
773
|
if (typeof window > "u" || typeof Worker > "u") return null;
|
|
346
|
-
if (!
|
|
347
|
-
|
|
348
|
-
let e =
|
|
349
|
-
|
|
350
|
-
let { type: n, id: r, result: i, runTime: a, error: o, progress: s, incumbent: c } = t.data, l =
|
|
774
|
+
if (!G) try {
|
|
775
|
+
G = fe();
|
|
776
|
+
let e = G;
|
|
777
|
+
G.onmessage = (t) => {
|
|
778
|
+
let { type: n, id: r, result: i, runTime: a, error: o, progress: s, incumbent: c } = t.data, l = K.get(r);
|
|
351
779
|
if (l) {
|
|
352
780
|
if (n === "SOLVE_PROGRESS") {
|
|
353
781
|
if (s) {
|
|
@@ -355,10 +783,10 @@ function we() {
|
|
|
355
783
|
try {
|
|
356
784
|
l.onProgress?.(s);
|
|
357
785
|
} catch (e) {
|
|
358
|
-
let t =
|
|
786
|
+
let t = K.get(r);
|
|
359
787
|
if (t) {
|
|
360
|
-
let n =
|
|
361
|
-
|
|
788
|
+
let n = K.keys().next().value;
|
|
789
|
+
K.delete(r), t.cleanupAbort?.(), n === r && He(), t.reject(e);
|
|
362
790
|
}
|
|
363
791
|
}
|
|
364
792
|
}
|
|
@@ -368,72 +796,72 @@ function we() {
|
|
|
368
796
|
c && (l.lastIncumbent = c);
|
|
369
797
|
return;
|
|
370
798
|
}
|
|
371
|
-
|
|
799
|
+
K.delete(r), l.cleanupAbort?.(), n === "SOLVE_SUCCESS" ? l.resolve({
|
|
372
800
|
result: i,
|
|
373
801
|
runTime: a
|
|
374
|
-
}) : l.reject(Error(o || "Worker solve failed")),
|
|
802
|
+
}) : l.reject(Error(o || "Worker solve failed")), G === e && Ve(e);
|
|
375
803
|
}
|
|
376
804
|
};
|
|
377
805
|
let t = (t) => {
|
|
378
|
-
if (
|
|
379
|
-
|
|
380
|
-
for (let e of
|
|
381
|
-
|
|
806
|
+
if (G === e) {
|
|
807
|
+
G = null, e.terminate();
|
|
808
|
+
for (let e of K.values()) e.cleanupAbort?.(), e.reject(t);
|
|
809
|
+
K.clear();
|
|
382
810
|
}
|
|
383
811
|
};
|
|
384
|
-
|
|
812
|
+
G.onerror = (e) => t(/* @__PURE__ */ Error(`[WaSHI] HiGHS Worker failed to load or execute. Check Worker assets, CORS and CSP. ${e?.message || ""}`)), G.onmessageerror = () => t(/* @__PURE__ */ Error("[WaSHI] Could not deserialize the HiGHS Worker response."));
|
|
385
813
|
} catch {
|
|
386
|
-
|
|
814
|
+
G = null;
|
|
387
815
|
}
|
|
388
|
-
return
|
|
816
|
+
return G;
|
|
389
817
|
}
|
|
390
|
-
async function
|
|
818
|
+
async function We(e, t = {}) {
|
|
391
819
|
if (t.signal?.aborted) return {
|
|
392
|
-
result:
|
|
820
|
+
result: Be(),
|
|
393
821
|
runTime: 0
|
|
394
822
|
};
|
|
395
|
-
let n = await
|
|
823
|
+
let n = await N(t.wasmUrl);
|
|
396
824
|
if (t.signal?.aborted) return {
|
|
397
|
-
result:
|
|
825
|
+
result: Be(),
|
|
398
826
|
runTime: 0
|
|
399
827
|
};
|
|
400
|
-
let r = t.useWorker ?? typeof window < "u" ?
|
|
401
|
-
if (!
|
|
402
|
-
let { signal:
|
|
403
|
-
for (let [e, t] of Object.entries(
|
|
404
|
-
|
|
405
|
-
let
|
|
828
|
+
let r = typeof window < "u" ? typeof window.origin == "string" ? window.origin : window.location?.origin : void 0, i = t.useWorker ?? (typeof window < "u" && r !== "null" && !r?.startsWith("file:")) ? Ue() : null;
|
|
829
|
+
if (!i) return M(e, t);
|
|
830
|
+
let { signal: a, onProgress: o, ...s } = t, c = {};
|
|
831
|
+
for (let [e, t] of Object.entries(s)) typeof t != "function" && (c[e] = t);
|
|
832
|
+
c.wasmUrl = n;
|
|
833
|
+
let l = !!(o || a), u = `req_${++ze}`, d = performance.now();
|
|
406
834
|
return new Promise((t, n) => {
|
|
407
|
-
let
|
|
408
|
-
id:
|
|
835
|
+
let r = {
|
|
836
|
+
id: u,
|
|
409
837
|
lpString: e,
|
|
410
|
-
workerOptions:
|
|
411
|
-
reportProgress:
|
|
412
|
-
startTime:
|
|
413
|
-
onProgress:
|
|
838
|
+
workerOptions: c,
|
|
839
|
+
reportProgress: l,
|
|
840
|
+
startTime: d,
|
|
841
|
+
onProgress: o,
|
|
414
842
|
resolve: t,
|
|
415
843
|
reject: n
|
|
416
844
|
};
|
|
417
|
-
if (
|
|
845
|
+
if (a) {
|
|
418
846
|
let e = () => {
|
|
419
|
-
let e =
|
|
847
|
+
let e = K.get(u);
|
|
420
848
|
if (!e) return;
|
|
421
|
-
let t =
|
|
422
|
-
|
|
849
|
+
let t = K.keys().next().value;
|
|
850
|
+
K.delete(u), e.cleanupAbort?.(), t === u && He();
|
|
423
851
|
let n = (performance.now() - e.startTime) / 1e3;
|
|
424
852
|
e.resolve({
|
|
425
|
-
result:
|
|
853
|
+
result: Be(e.lastIncumbent, e.lastProgress),
|
|
426
854
|
runTime: n
|
|
427
855
|
});
|
|
428
856
|
};
|
|
429
|
-
|
|
857
|
+
a.addEventListener("abort", e, { once: !0 }), r.cleanupAbort = () => a.removeEventListener("abort", e);
|
|
430
858
|
}
|
|
431
|
-
|
|
859
|
+
K.set(u, r), Ve(i);
|
|
432
860
|
});
|
|
433
861
|
}
|
|
434
862
|
//#endregion
|
|
435
863
|
//#region src/modeler/solvers/highs/solver.ts
|
|
436
|
-
function
|
|
864
|
+
function q(e, t) {
|
|
437
865
|
if (typeof t == "number") switch (t) {
|
|
438
866
|
case 0: return "NotSolved";
|
|
439
867
|
case 1:
|
|
@@ -492,8 +920,8 @@ function G(e, t) {
|
|
|
492
920
|
let r = n.toLowerCase();
|
|
493
921
|
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";
|
|
494
922
|
}
|
|
495
|
-
function
|
|
496
|
-
switch (
|
|
923
|
+
function Ge(e, t, n) {
|
|
924
|
+
switch (q(e, t)) {
|
|
497
925
|
case "Optimal": return "Optimal";
|
|
498
926
|
case "Infeasible": return "Infeasible";
|
|
499
927
|
case "Unbounded": return "Unbounded";
|
|
@@ -510,35 +938,35 @@ function K(e, t, n) {
|
|
|
510
938
|
default: return "Unknown";
|
|
511
939
|
}
|
|
512
940
|
}
|
|
513
|
-
var
|
|
941
|
+
var J = class e {
|
|
514
942
|
static capabilities = {
|
|
515
943
|
supportsMIP: !0,
|
|
516
944
|
supportsQP: !0,
|
|
517
945
|
supportsWarmStart: !0
|
|
518
946
|
};
|
|
519
947
|
name = "HiGHS";
|
|
520
|
-
version = "1.15.
|
|
948
|
+
version = "1.15.1";
|
|
521
949
|
capabilities = e.capabilities;
|
|
522
950
|
options;
|
|
523
951
|
constructor(e = {}) {
|
|
524
952
|
this.options = e;
|
|
525
953
|
}
|
|
526
954
|
async solve(e, t = {}, n = {}) {
|
|
527
|
-
let r =
|
|
955
|
+
let r = T(t), i = r ? n : t, a = {
|
|
528
956
|
...this.options,
|
|
529
957
|
...i
|
|
530
958
|
}, o = e.objective.constant || 0;
|
|
531
959
|
for (let t of e.variables) d(t);
|
|
532
|
-
let { lpString: s, nameToVar: c, nameToConstraint: l } = r ? t : C(e), u = Object.create(null), p = !1, m = /* @__PURE__ */ new Set();
|
|
960
|
+
let { lpString: s, nameToVar: c, nameToConstraint: l } = r ? t : C(e, { relax: a.relax }), u = Object.create(null), p = !1, m = /* @__PURE__ */ new Set();
|
|
533
961
|
for (let [e, t] of c.entries()) {
|
|
534
962
|
m.add(t);
|
|
535
|
-
let n =
|
|
963
|
+
let n = ee(t);
|
|
536
964
|
n !== void 0 && (u[e] = n, p = !0);
|
|
537
965
|
}
|
|
538
966
|
for (let t = 0; t < e.variables.length; t++) {
|
|
539
967
|
let n = e.variables[t];
|
|
540
968
|
if (!m.has(n)) {
|
|
541
|
-
let e =
|
|
969
|
+
let e = ee(n);
|
|
542
970
|
if (e !== void 0) {
|
|
543
971
|
let r = f(n.name, "x", t);
|
|
544
972
|
Object.prototype.hasOwnProperty.call(u, r) || (u[r] = e, p = !0);
|
|
@@ -551,33 +979,33 @@ var q = class e {
|
|
|
551
979
|
...o === 0 ? {} : { objectiveOffset: o },
|
|
552
980
|
initialValues: p ? u : void 0
|
|
553
981
|
});
|
|
554
|
-
let { result: g, runTime: _ } = await
|
|
982
|
+
let { result: g, runTime: _ } = await We(s, h), v = g?.ObjectiveOffsetApplied ? 0 : o, y = q(g?.Status, g?.StatusCode), b = a.relax ? !1 : typeof g?.IsMip == "boolean" ? g.IsMip : e.variables.some((e) => e.type === "Integer" || e.type === "Binary"), x;
|
|
555
983
|
if (typeof g?.HasPrimalSolution == "boolean") x = g.HasPrimalSolution;
|
|
556
984
|
else {
|
|
557
985
|
let e = g?.Columns ? Object.values(g.Columns) : [], t = e.length > 0 && e.some((e) => typeof e?.Primal == "number" && Number.isFinite(e.Primal)), n = typeof g?.ObjectiveValue == "number" && Number.isFinite(g.ObjectiveValue);
|
|
558
986
|
x = y === "Infeasible" || y === "Unbounded" || y === "InfeasibleOrUnbounded" || y === "Error" || y === "NotSolved" ? !1 : y === "Optimal" || y === "Feasible" ? n || t : n && (e.length === 0 || t);
|
|
559
987
|
}
|
|
560
|
-
let S =
|
|
561
|
-
x && typeof g?.ObjectiveValue == "number" && Number.isFinite(g.ObjectiveValue) && (
|
|
562
|
-
let D, O
|
|
563
|
-
if (typeof g?.MipDualBound == "number" && Number.isFinite(g.MipDualBound) ?
|
|
564
|
-
if (
|
|
565
|
-
else if (Math.abs(
|
|
566
|
-
let e =
|
|
567
|
-
|
|
568
|
-
} else
|
|
569
|
-
} else typeof g?.MipGap == "number" && Number.isFinite(g.MipGap) ?
|
|
988
|
+
let S = Ge(g?.Status, g?.StatusCode, x), w = null;
|
|
989
|
+
x && typeof g?.ObjectiveValue == "number" && Number.isFinite(g.ObjectiveValue) && (w = g.ObjectiveValue + v);
|
|
990
|
+
let E, D, O;
|
|
991
|
+
if (typeof g?.MipDualBound == "number" && Number.isFinite(g.MipDualBound) ? E = g.MipDualBound + v : !b && y === "Optimal" && w !== null && (E = w), w !== null && E !== void 0 && Number.isFinite(E) && (O = Math.abs(w - E)), v !== 0 && b && w !== null && E !== void 0 && O !== void 0) {
|
|
992
|
+
if (O === 0) D = 0;
|
|
993
|
+
else if (Math.abs(w) > 0) {
|
|
994
|
+
let e = O / Math.abs(w);
|
|
995
|
+
D = Number.isFinite(e) ? e : void 0;
|
|
996
|
+
} else D = void 0;
|
|
997
|
+
} else typeof g?.MipGap == "number" && Number.isFinite(g.MipGap) ? D = g.MipGap : b && y === "Optimal" && x && (O === void 0 || O === 0) && (D = 0);
|
|
570
998
|
if (!x) return {
|
|
571
999
|
status: S,
|
|
572
1000
|
terminationStatus: y,
|
|
573
1001
|
hasPrimalSolution: !1,
|
|
574
1002
|
objectiveValue: null,
|
|
575
|
-
...
|
|
576
|
-
...
|
|
577
|
-
relGap:
|
|
578
|
-
mipGap:
|
|
1003
|
+
...E === void 0 ? {} : { objectiveBound: E },
|
|
1004
|
+
...D === void 0 ? {} : {
|
|
1005
|
+
relGap: D,
|
|
1006
|
+
mipGap: D
|
|
579
1007
|
},
|
|
580
|
-
...
|
|
1008
|
+
...O === void 0 ? {} : { absGap: O },
|
|
581
1009
|
values: {},
|
|
582
1010
|
reducedCosts: {},
|
|
583
1011
|
duals: {},
|
|
@@ -585,31 +1013,31 @@ var q = class e {
|
|
|
585
1013
|
runTime: _,
|
|
586
1014
|
raw: g
|
|
587
1015
|
};
|
|
588
|
-
let
|
|
1016
|
+
let k = (e, t, n) => {
|
|
589
1017
|
Object.defineProperty(e, t, {
|
|
590
1018
|
value: n,
|
|
591
1019
|
enumerable: !0,
|
|
592
1020
|
writable: !0,
|
|
593
1021
|
configurable: !0
|
|
594
1022
|
});
|
|
595
|
-
},
|
|
1023
|
+
}, A = {}, te = {}, j = {}, M = {};
|
|
596
1024
|
if (g.Columns) for (let [e, t] of Object.entries(g.Columns)) {
|
|
597
1025
|
let n = c.get(e);
|
|
598
1026
|
if (n) {
|
|
599
1027
|
if (typeof t.Primal == "number" && Number.isFinite(t.Primal)) {
|
|
600
1028
|
let e = Math.abs(t.Primal) < 1e-9 ? 0 : t.Primal;
|
|
601
|
-
|
|
1029
|
+
!a.relax && (n.type === "Integer" || n.type === "Binary") && Math.abs(e - Math.round(e)) <= 1e-5 && (e = Math.round(e) + 0), k(A, n.name, e);
|
|
602
1030
|
}
|
|
603
|
-
typeof t.Dual == "number" && Number.isFinite(t.Dual) &&
|
|
1031
|
+
typeof t.Dual == "number" && Number.isFinite(t.Dual) && k(j, n.name, Math.abs(t.Dual) < 1e-9 ? 0 : t.Dual);
|
|
604
1032
|
}
|
|
605
1033
|
}
|
|
606
1034
|
if (g.Rows) {
|
|
607
1035
|
let e = Array.isArray(g.Rows) ? g.Rows : Object.values(g.Rows);
|
|
608
1036
|
for (let t of e) {
|
|
609
1037
|
let e = t.Name, n = e ? l.get(e) : void 0;
|
|
610
|
-
if (n && (typeof t.Dual == "number" && Number.isFinite(t.Dual) &&
|
|
1038
|
+
if (n && (typeof t.Dual == "number" && Number.isFinite(t.Dual) && k(te, n.name, Math.abs(t.Dual) < 1e-9 ? 0 : t.Dual), typeof t.Primal == "number" && Number.isFinite(t.Primal))) {
|
|
611
1039
|
let e = n.rhs - t.Primal;
|
|
612
|
-
|
|
1040
|
+
k(M, n.name, Math.abs(e) < 1e-9 ? 0 : e);
|
|
613
1041
|
}
|
|
614
1042
|
}
|
|
615
1043
|
}
|
|
@@ -617,70 +1045,84 @@ var q = class e {
|
|
|
617
1045
|
status: S,
|
|
618
1046
|
terminationStatus: y,
|
|
619
1047
|
hasPrimalSolution: !0,
|
|
620
|
-
objectiveValue:
|
|
621
|
-
...
|
|
622
|
-
...
|
|
623
|
-
relGap:
|
|
624
|
-
mipGap:
|
|
1048
|
+
objectiveValue: w,
|
|
1049
|
+
...E === void 0 ? {} : { objectiveBound: E },
|
|
1050
|
+
...D === void 0 ? {} : {
|
|
1051
|
+
relGap: D,
|
|
1052
|
+
mipGap: D
|
|
625
1053
|
},
|
|
626
|
-
...
|
|
627
|
-
values:
|
|
628
|
-
reducedCosts:
|
|
629
|
-
duals:
|
|
630
|
-
slacks:
|
|
1054
|
+
...O === void 0 ? {} : { absGap: O },
|
|
1055
|
+
values: A,
|
|
1056
|
+
reducedCosts: j,
|
|
1057
|
+
duals: te,
|
|
1058
|
+
slacks: M,
|
|
631
1059
|
runTime: _,
|
|
632
1060
|
raw: g
|
|
633
1061
|
};
|
|
634
1062
|
}
|
|
635
|
-
},
|
|
636
|
-
function
|
|
637
|
-
|
|
1063
|
+
}, Ke = J;
|
|
1064
|
+
function qe() {
|
|
1065
|
+
w("highs", (e) => new J(e)), _((e) => new J(e));
|
|
638
1066
|
}
|
|
639
|
-
|
|
1067
|
+
qe();
|
|
640
1068
|
//#endregion
|
|
641
1069
|
//#region src/modeler/solvers/highs/index.ts
|
|
642
|
-
var
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
1070
|
+
var Je = /* @__PURE__ */ _e({
|
|
1071
|
+
HIGHS_CONSTANTS: () => oe,
|
|
1072
|
+
HIGHS_STATUS_NAMES: () => de,
|
|
1073
|
+
HiGHS: () => Ke,
|
|
1074
|
+
Highs: () => ne,
|
|
1075
|
+
HighsError: () => re,
|
|
1076
|
+
HighsModel: () => le,
|
|
1077
|
+
HighsSolver: () => J,
|
|
1078
|
+
HighsUnsupportedOptionError: () => se,
|
|
1079
|
+
OFFICIAL_HIGHS_CDN_WASM_URL: () => ue,
|
|
1080
|
+
bindHighsFunctions: () => ie,
|
|
1081
|
+
getHighs: () => ce,
|
|
1082
|
+
getHighsWasmUrl: () => P,
|
|
1083
|
+
isValidWasmHeader: () => ae,
|
|
1084
|
+
mapHighsStatus: () => Ge,
|
|
1085
|
+
mapHighsTerminationStatus: () => q,
|
|
1086
|
+
probeWasmUrl: () => j,
|
|
1087
|
+
registerHighsSolver: () => qe,
|
|
1088
|
+
resolveBrowserWasmUrl: () => N,
|
|
1089
|
+
setHighsWasmUrl: () => F,
|
|
1090
|
+
solveLp: () => We,
|
|
1091
|
+
solveLpWithHighs: () => M
|
|
657
1092
|
});
|
|
658
|
-
import * as
|
|
659
|
-
|
|
660
|
-
import * as
|
|
661
|
-
|
|
1093
|
+
import * as Ye from "./highs-worker-factory.js";
|
|
1094
|
+
I(Je, Ye);
|
|
1095
|
+
import * as Xe from "./highs-assets.js";
|
|
1096
|
+
I(Je, Xe);
|
|
662
1097
|
//#endregion
|
|
663
1098
|
//#region src/modeler/solvers/highs.ts
|
|
664
|
-
var
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
1099
|
+
var Ze = /* @__PURE__ */ _e({
|
|
1100
|
+
HIGHS_CONSTANTS: () => oe,
|
|
1101
|
+
HIGHS_STATUS_NAMES: () => de,
|
|
1102
|
+
HiGHS: () => Ke,
|
|
1103
|
+
Highs: () => ne,
|
|
1104
|
+
HighsError: () => re,
|
|
1105
|
+
HighsModel: () => le,
|
|
1106
|
+
HighsSolver: () => J,
|
|
1107
|
+
HighsUnsupportedOptionError: () => se,
|
|
1108
|
+
OFFICIAL_HIGHS_CDN_WASM_URL: () => ue,
|
|
1109
|
+
bindHighsFunctions: () => ie,
|
|
1110
|
+
getHighs: () => ce,
|
|
1111
|
+
getHighsWasmUrl: () => P,
|
|
1112
|
+
isValidWasmHeader: () => ae,
|
|
1113
|
+
mapHighsStatus: () => Ge,
|
|
1114
|
+
mapHighsTerminationStatus: () => q,
|
|
1115
|
+
probeWasmUrl: () => j,
|
|
1116
|
+
registerHighsSolver: () => qe,
|
|
1117
|
+
resolveBrowserWasmUrl: () => N,
|
|
1118
|
+
setHighsWasmUrl: () => F,
|
|
1119
|
+
solveLp: () => We,
|
|
1120
|
+
solveLpWithHighs: () => M
|
|
679
1121
|
});
|
|
680
|
-
|
|
1122
|
+
I(Ze, Je);
|
|
681
1123
|
//#endregion
|
|
682
1124
|
//#region src/modeler/solvers/mock.ts
|
|
683
|
-
var
|
|
1125
|
+
var Qe = class {
|
|
684
1126
|
name;
|
|
685
1127
|
capabilities;
|
|
686
1128
|
options;
|
|
@@ -692,7 +1134,7 @@ var ke = class {
|
|
|
692
1134
|
}, this.options = e;
|
|
693
1135
|
}
|
|
694
1136
|
async solve(e, t = {}, n = {}) {
|
|
695
|
-
let r =
|
|
1137
|
+
let r = T(t) ? n : t, i = {
|
|
696
1138
|
...this.options,
|
|
697
1139
|
...r
|
|
698
1140
|
}, a = !!(i.values && Object.keys(i.values).length > 0 || i.boolValues && Object.keys(i.boolValues).length > 0);
|
|
@@ -780,44 +1222,51 @@ var ke = class {
|
|
|
780
1222
|
};
|
|
781
1223
|
}
|
|
782
1224
|
};
|
|
783
|
-
function
|
|
784
|
-
|
|
1225
|
+
function $e() {
|
|
1226
|
+
w("mock", (e) => new Qe(e));
|
|
785
1227
|
}
|
|
786
|
-
|
|
1228
|
+
$e();
|
|
787
1229
|
//#endregion
|
|
788
1230
|
//#region src/modeler/solvers/index.ts
|
|
789
|
-
var
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
1231
|
+
var et = /* @__PURE__ */ _e({
|
|
1232
|
+
HIGHS_CONSTANTS: () => oe,
|
|
1233
|
+
HIGHS_STATUS_NAMES: () => de,
|
|
1234
|
+
HiGHS: () => Ke,
|
|
1235
|
+
Highs: () => ne,
|
|
1236
|
+
HighsError: () => re,
|
|
1237
|
+
HighsModel: () => le,
|
|
1238
|
+
HighsSolver: () => J,
|
|
1239
|
+
HighsUnsupportedOptionError: () => se,
|
|
1240
|
+
MockSolver: () => Qe,
|
|
1241
|
+
OFFICIAL_HIGHS_CDN_WASM_URL: () => ue,
|
|
1242
|
+
bindHighsFunctions: () => ie,
|
|
1243
|
+
getHighs: () => ce,
|
|
1244
|
+
getHighsWasmUrl: () => P,
|
|
1245
|
+
getSolver: () => E,
|
|
1246
|
+
isValidWasmHeader: () => ae,
|
|
798
1247
|
listAvailableSolvers: () => S,
|
|
799
|
-
mapHighsStatus: () =>
|
|
800
|
-
mapHighsTerminationStatus: () =>
|
|
801
|
-
probeWasmUrl: () =>
|
|
802
|
-
registerHighsSolver: () =>
|
|
803
|
-
registerMockSolver: () =>
|
|
804
|
-
registerSolver: () =>
|
|
805
|
-
resolveBrowserWasmUrl: () =>
|
|
1248
|
+
mapHighsStatus: () => Ge,
|
|
1249
|
+
mapHighsTerminationStatus: () => q,
|
|
1250
|
+
probeWasmUrl: () => j,
|
|
1251
|
+
registerHighsSolver: () => qe,
|
|
1252
|
+
registerMockSolver: () => $e,
|
|
1253
|
+
registerSolver: () => w,
|
|
1254
|
+
resolveBrowserWasmUrl: () => N,
|
|
806
1255
|
setDefaultSolver: () => _,
|
|
807
|
-
setHighsWasmUrl: () =>
|
|
808
|
-
solveLp: () =>
|
|
809
|
-
solveLpWithHighs: () =>
|
|
1256
|
+
setHighsWasmUrl: () => F,
|
|
1257
|
+
solveLp: () => We,
|
|
1258
|
+
solveLpWithHighs: () => M
|
|
810
1259
|
});
|
|
811
|
-
|
|
1260
|
+
I(et, Ze);
|
|
812
1261
|
//#endregion
|
|
813
1262
|
//#region src/modeler/solution-validator.ts
|
|
814
|
-
function
|
|
1263
|
+
function tt(e, t) {
|
|
815
1264
|
if (e === void 0) return 1e-6;
|
|
816
1265
|
if (typeof e != "number" || !Number.isFinite(e) || e < 0) throw Error(`Invalid ${t}: expected a finite non-negative number, received ${String(e)}.`);
|
|
817
1266
|
return e;
|
|
818
1267
|
}
|
|
819
|
-
function
|
|
820
|
-
let r =
|
|
1268
|
+
function nt(e, t = {}) {
|
|
1269
|
+
let r = tt(t.feasibilityTolerance, "feasibilityTolerance"), i = tt(t.integralityTolerance, "integralityTolerance"), a = t.evaluateLogicalConstraints === void 0 || !!t.evaluateLogicalConstraints, s = t.values !== void 0 && t.values !== null;
|
|
821
1270
|
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.");
|
|
822
1271
|
let l = t.values, u = [], d = Object.create(null), f = [], p = [], m = 0, h = (e) => {
|
|
823
1272
|
typeof e == "number" && !Number.isNaN(e) && e > m && (m = e);
|
|
@@ -975,7 +1424,7 @@ function Ne(e, t = {}) {
|
|
|
975
1424
|
ok: !0,
|
|
976
1425
|
value: n
|
|
977
1426
|
};
|
|
978
|
-
},
|
|
1427
|
+
}, ee = (e, t = r) => {
|
|
979
1428
|
if (typeof e.rhs != "number" || !Number.isFinite(e.rhs)) return {
|
|
980
1429
|
status: "unchecked",
|
|
981
1430
|
reason: `non-finite right-hand side (${String(e.rhs)})`
|
|
@@ -1005,7 +1454,7 @@ function Ne(e, t = {}) {
|
|
|
1005
1454
|
};
|
|
1006
1455
|
};
|
|
1007
1456
|
for (let t of e.constraints) {
|
|
1008
|
-
let e =
|
|
1457
|
+
let e = ee(t);
|
|
1009
1458
|
e.status === "unchecked" ? (f.push(t.name), g({
|
|
1010
1459
|
type: "unchecked_constraint",
|
|
1011
1460
|
target: "constraint",
|
|
@@ -1028,7 +1477,7 @@ function Ne(e, t = {}) {
|
|
|
1028
1477
|
message: e.message
|
|
1029
1478
|
})) : (x++, h(e.violation));
|
|
1030
1479
|
}
|
|
1031
|
-
let
|
|
1480
|
+
let w = (e) => {
|
|
1032
1481
|
if (e instanceof o) return v.has(e) ? {
|
|
1033
1482
|
ok: !0,
|
|
1034
1483
|
value: v.get(e),
|
|
@@ -1038,7 +1487,7 @@ function Ne(e, t = {}) {
|
|
|
1038
1487
|
reason: `missing or invalid value for Boolean variable "${e.name}"`
|
|
1039
1488
|
};
|
|
1040
1489
|
if (e instanceof c) {
|
|
1041
|
-
let t =
|
|
1490
|
+
let t = ee(e, 0);
|
|
1042
1491
|
if (t.status === "unchecked") return {
|
|
1043
1492
|
ok: !1,
|
|
1044
1493
|
reason: t.reason
|
|
@@ -1058,7 +1507,7 @@ function Ne(e, t = {}) {
|
|
|
1058
1507
|
}
|
|
1059
1508
|
if (e instanceof n) switch (e.op) {
|
|
1060
1509
|
case "not": {
|
|
1061
|
-
let t =
|
|
1510
|
+
let t = w(e.children[0]);
|
|
1062
1511
|
return t.ok ? {
|
|
1063
1512
|
ok: !0,
|
|
1064
1513
|
value: !t.value,
|
|
@@ -1068,7 +1517,7 @@ function Ne(e, t = {}) {
|
|
|
1068
1517
|
case "and": {
|
|
1069
1518
|
let t = 0;
|
|
1070
1519
|
for (let n of e.children) {
|
|
1071
|
-
let e =
|
|
1520
|
+
let e = w(n);
|
|
1072
1521
|
if (!e.ok) return e;
|
|
1073
1522
|
if (!e.value) return {
|
|
1074
1523
|
ok: !0,
|
|
@@ -1086,7 +1535,7 @@ function Ne(e, t = {}) {
|
|
|
1086
1535
|
case "or": {
|
|
1087
1536
|
let t = !1, n = Infinity;
|
|
1088
1537
|
for (let r of e.children) {
|
|
1089
|
-
let e =
|
|
1538
|
+
let e = w(r);
|
|
1090
1539
|
if (!e.ok) return e;
|
|
1091
1540
|
e.value && (t = !0, e.violation < n && (n = e.violation));
|
|
1092
1541
|
}
|
|
@@ -1097,14 +1546,14 @@ function Ne(e, t = {}) {
|
|
|
1097
1546
|
};
|
|
1098
1547
|
}
|
|
1099
1548
|
case "implies": {
|
|
1100
|
-
let t =
|
|
1549
|
+
let t = w(e.children[0]);
|
|
1101
1550
|
if (!t.ok) return t;
|
|
1102
1551
|
if (!t.value) return {
|
|
1103
1552
|
ok: !0,
|
|
1104
1553
|
value: !0,
|
|
1105
1554
|
violation: 0
|
|
1106
1555
|
};
|
|
1107
|
-
let n =
|
|
1556
|
+
let n = w(e.children[1]);
|
|
1108
1557
|
return n.ok ? {
|
|
1109
1558
|
ok: !0,
|
|
1110
1559
|
value: n.value,
|
|
@@ -1114,7 +1563,7 @@ function Ne(e, t = {}) {
|
|
|
1114
1563
|
case "xor": {
|
|
1115
1564
|
let t = !1, n = 0;
|
|
1116
1565
|
for (let r of e.children) {
|
|
1117
|
-
let e =
|
|
1566
|
+
let e = w(r);
|
|
1118
1567
|
if (!e.ok) return e;
|
|
1119
1568
|
e.value && (t = !t, e.violation > n && (n = e.violation));
|
|
1120
1569
|
}
|
|
@@ -1146,7 +1595,7 @@ function Ne(e, t = {}) {
|
|
|
1146
1595
|
});
|
|
1147
1596
|
continue;
|
|
1148
1597
|
}
|
|
1149
|
-
let i =
|
|
1598
|
+
let i = w(n.expr);
|
|
1150
1599
|
if (!i.ok) {
|
|
1151
1600
|
f.push(r), g({
|
|
1152
1601
|
type: "unchecked_constraint",
|
|
@@ -1168,10 +1617,10 @@ function Ne(e, t = {}) {
|
|
|
1168
1617
|
message: `Logical constraint "${r}" evaluated to false.`
|
|
1169
1618
|
});
|
|
1170
1619
|
}
|
|
1171
|
-
let
|
|
1620
|
+
let T = y === e.variables.length && b === e.boolVars.length && x === e.constraints.length && S === e.logicalConstraints.length && f.length === 0 && p.length === 0;
|
|
1172
1621
|
return {
|
|
1173
|
-
valid:
|
|
1174
|
-
complete:
|
|
1622
|
+
valid: T && u.length === 0,
|
|
1623
|
+
complete: T,
|
|
1175
1624
|
violations: u,
|
|
1176
1625
|
violationsByName: d,
|
|
1177
1626
|
uncheckedConstraints: f,
|
|
@@ -1191,10 +1640,10 @@ function Ne(e, t = {}) {
|
|
|
1191
1640
|
}
|
|
1192
1641
|
//#endregion
|
|
1193
1642
|
//#region src/modeler/big-m.ts
|
|
1194
|
-
function
|
|
1643
|
+
function rt(e, t) {
|
|
1195
1644
|
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}.`);
|
|
1196
1645
|
}
|
|
1197
|
-
function
|
|
1646
|
+
function it(e, t, n) {
|
|
1198
1647
|
let r = e.constant === void 0 ? 0 : e.constant;
|
|
1199
1648
|
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}).`);
|
|
1200
1649
|
let i = t - r;
|
|
@@ -1205,8 +1654,8 @@ function Fe(e, t, n) {
|
|
|
1205
1654
|
}
|
|
1206
1655
|
return i;
|
|
1207
1656
|
}
|
|
1208
|
-
function
|
|
1209
|
-
let r =
|
|
1657
|
+
function at(e, t, n) {
|
|
1658
|
+
let r = it(e, t, n), i = 0;
|
|
1210
1659
|
for (let [t, r] of e.terms) {
|
|
1211
1660
|
if (r === 0) continue;
|
|
1212
1661
|
let e;
|
|
@@ -1226,8 +1675,8 @@ function Ie(e, t, n) {
|
|
|
1226
1675
|
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.`);
|
|
1227
1676
|
return o;
|
|
1228
1677
|
}
|
|
1229
|
-
function
|
|
1230
|
-
let r =
|
|
1678
|
+
function ot(e, t, n) {
|
|
1679
|
+
let r = it(e, t, n), i = 0;
|
|
1231
1680
|
for (let [t, r] of e.terms) {
|
|
1232
1681
|
if (r === 0) continue;
|
|
1233
1682
|
let e;
|
|
@@ -1247,10 +1696,10 @@ function Le(e, t, n) {
|
|
|
1247
1696
|
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.`);
|
|
1248
1697
|
return o;
|
|
1249
1698
|
}
|
|
1250
|
-
function
|
|
1699
|
+
function Y(e, t, n, r, i, a, o) {
|
|
1251
1700
|
if (!(e instanceof b && (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}].`);
|
|
1252
1701
|
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.`);
|
|
1253
|
-
let s =
|
|
1702
|
+
let s = it(t, r, o);
|
|
1254
1703
|
if (i !== 0 && i !== 1) throw Error(`Invalid activeValue: ${i}. Indicator activation value must be 0 or 1.`);
|
|
1255
1704
|
if (n !== "<=" && n !== ">=") throw Error(`Invalid indicator sense for "${o}": expected "<=" or ">=", received "${String(n)}".`);
|
|
1256
1705
|
if (!Number.isFinite(a) || a < 0) throw Error(`Invalid Big-M value for indicator constraint "${o}": expected a finite non-negative number, received ${a}.`);
|
|
@@ -1261,11 +1710,532 @@ function X(e, t, n, r, i, a, o) {
|
|
|
1261
1710
|
let d = /* @__PURE__ */ new Map();
|
|
1262
1711
|
for (let [e, n] of t.terms) n !== 0 && d.set(e, n);
|
|
1263
1712
|
return l !== 0 && d.set(e, l), {
|
|
1264
|
-
lhs: new
|
|
1713
|
+
lhs: new A(d, 0),
|
|
1265
1714
|
rhs: u
|
|
1266
1715
|
};
|
|
1267
1716
|
}
|
|
1268
1717
|
//#endregion
|
|
1718
|
+
//#region src/modeler/linearizer.ts
|
|
1719
|
+
function X(e, t = 0) {
|
|
1720
|
+
return new A(new Map(e), t);
|
|
1721
|
+
}
|
|
1722
|
+
function st(e, t, r, i) {
|
|
1723
|
+
let a = [...e], s = [...r], l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
|
|
1724
|
+
for (let e of r) u.set(e, e.name);
|
|
1725
|
+
let d = new Set(e.map((e) => e.name)), f = 0;
|
|
1726
|
+
function p(e) {
|
|
1727
|
+
let t;
|
|
1728
|
+
do
|
|
1729
|
+
t = `__washi_${e}_${++f}`;
|
|
1730
|
+
while (d.has(t));
|
|
1731
|
+
return d.add(t), t;
|
|
1732
|
+
}
|
|
1733
|
+
for (let e of t) {
|
|
1734
|
+
let t = e.name;
|
|
1735
|
+
d.has(t) ? t = p(`bool_${e.name}`) : d.add(t);
|
|
1736
|
+
let n = new b({
|
|
1737
|
+
name: t,
|
|
1738
|
+
type: "Binary",
|
|
1739
|
+
lb: 0,
|
|
1740
|
+
ub: 1
|
|
1741
|
+
});
|
|
1742
|
+
l.set(e, n), a.push(n);
|
|
1743
|
+
}
|
|
1744
|
+
function m(e, t) {
|
|
1745
|
+
if (e instanceof ct) return e.wrappedVar;
|
|
1746
|
+
if (e instanceof o) {
|
|
1747
|
+
let n = l.get(e);
|
|
1748
|
+
if (!n) throw Error(`Unregistered BoolVar "${e.name}" in logical constraint "${t}".`);
|
|
1749
|
+
return n;
|
|
1750
|
+
}
|
|
1751
|
+
let n = new b({
|
|
1752
|
+
name: p("expr"),
|
|
1753
|
+
type: "Binary",
|
|
1754
|
+
lb: 0,
|
|
1755
|
+
ub: 1
|
|
1756
|
+
});
|
|
1757
|
+
return a.push(n), g(n, e, t), n;
|
|
1758
|
+
}
|
|
1759
|
+
function h(e, t, n, r) {
|
|
1760
|
+
let i = new c(X([
|
|
1761
|
+
[e, 1],
|
|
1762
|
+
[t, -1],
|
|
1763
|
+
[n, -1]
|
|
1764
|
+
], 0), "<=", 0, `${r}_xor_1`), a = new c(X([
|
|
1765
|
+
[e, 1],
|
|
1766
|
+
[t, -1],
|
|
1767
|
+
[n, 1]
|
|
1768
|
+
], 0), ">=", 0, `${r}_xor_2`), o = new c(X([
|
|
1769
|
+
[e, 1],
|
|
1770
|
+
[n, -1],
|
|
1771
|
+
[t, 1]
|
|
1772
|
+
], 0), ">=", 0, `${r}_xor_3`), l = new c(X([
|
|
1773
|
+
[e, 1],
|
|
1774
|
+
[t, 1],
|
|
1775
|
+
[n, 1]
|
|
1776
|
+
], 0), "<=", 2, `${r}_xor_4`);
|
|
1777
|
+
s.push(i, a, o, l), u.set(i, r), u.set(a, r), u.set(o, r), u.set(l, r);
|
|
1778
|
+
}
|
|
1779
|
+
function g(e, t, r) {
|
|
1780
|
+
if (t instanceof o) {
|
|
1781
|
+
let n = l.get(t), i = new c(X([[e, 1], [n, -1]], 0), "==", 0, `${r}_equiv`);
|
|
1782
|
+
s.push(i), u.set(i, r);
|
|
1783
|
+
return;
|
|
1784
|
+
}
|
|
1785
|
+
if (t instanceof n) {
|
|
1786
|
+
if (t.op === "not") {
|
|
1787
|
+
let n = m(t.children[0], r), i = new c(X([[e, 1], [n, 1]], 0), "==", 1, `${r}_not`);
|
|
1788
|
+
s.push(i), u.set(i, r);
|
|
1789
|
+
return;
|
|
1790
|
+
}
|
|
1791
|
+
if (t.op === "and") {
|
|
1792
|
+
let n = t.children.map((e) => m(e, r));
|
|
1793
|
+
for (let t = 0; t < n.length; t++) {
|
|
1794
|
+
let i = new c(X([[e, 1], [n[t], -1]], 0), "<=", 0, `${r}_and_ub_${t}`);
|
|
1795
|
+
s.push(i), u.set(i, r);
|
|
1796
|
+
}
|
|
1797
|
+
let i = [[e, 1], ...n.map((e) => [e, -1])], a = new c(X(i, 0), ">=", 1 - n.length, `${r}_and_lb`);
|
|
1798
|
+
s.push(a), u.set(a, r);
|
|
1799
|
+
return;
|
|
1800
|
+
}
|
|
1801
|
+
if (t.op === "or") {
|
|
1802
|
+
let n = t.children.map((e) => m(e, r));
|
|
1803
|
+
for (let t = 0; t < n.length; t++) {
|
|
1804
|
+
let i = new c(X([[e, 1], [n[t], -1]], 0), ">=", 0, `${r}_or_lb_${t}`);
|
|
1805
|
+
s.push(i), u.set(i, r);
|
|
1806
|
+
}
|
|
1807
|
+
let i = [[e, 1], ...n.map((e) => [e, -1])], a = new c(X(i, 0), "<=", 0, `${r}_or_ub`);
|
|
1808
|
+
s.push(a), u.set(a, r);
|
|
1809
|
+
return;
|
|
1810
|
+
}
|
|
1811
|
+
if (t.op === "implies") {
|
|
1812
|
+
let n = m(t.children[0], r), i = m(t.children[1], r), a = new c(X([
|
|
1813
|
+
[e, 1],
|
|
1814
|
+
[i, -1],
|
|
1815
|
+
[n, 1]
|
|
1816
|
+
], 0), ">=", 0, `${r}_imp_1`), o = new c(X([
|
|
1817
|
+
[e, 1],
|
|
1818
|
+
[n, 1],
|
|
1819
|
+
[i, -1]
|
|
1820
|
+
], 0), "<=", 1, `${r}_imp_2`);
|
|
1821
|
+
s.push(a, o), u.set(a, r), u.set(o, r);
|
|
1822
|
+
return;
|
|
1823
|
+
}
|
|
1824
|
+
if (t.op === "xor") {
|
|
1825
|
+
if (t.children.length === 0) {
|
|
1826
|
+
let t = new c(X([[e, 1]], 0), "==", 0, `${r}_xor_empty`);
|
|
1827
|
+
s.push(t), u.set(t, r);
|
|
1828
|
+
return;
|
|
1829
|
+
}
|
|
1830
|
+
if (t.children.length === 1) {
|
|
1831
|
+
let n = m(t.children[0], r), i = new c(X([[e, 1], [n, -1]], 0), "==", 0, `${r}_xor_single`);
|
|
1832
|
+
s.push(i), u.set(i, r);
|
|
1833
|
+
return;
|
|
1834
|
+
}
|
|
1835
|
+
let n = t.children.map((e) => m(e, r)), i = n[0];
|
|
1836
|
+
for (let e = 1; e < n.length - 1; e++) {
|
|
1837
|
+
let t = new b({
|
|
1838
|
+
name: p(`xor_fold_${e}`),
|
|
1839
|
+
type: "Binary",
|
|
1840
|
+
lb: 0,
|
|
1841
|
+
ub: 1
|
|
1842
|
+
});
|
|
1843
|
+
a.push(t), h(t, i, n[e], `${r}_xor_fold_${e}`), i = t;
|
|
1844
|
+
}
|
|
1845
|
+
h(e, i, n[n.length - 1], r);
|
|
1846
|
+
return;
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
throw Error(`Unsupported logical element in equivalence linearization: ${t}`);
|
|
1850
|
+
}
|
|
1851
|
+
for (let e of i) {
|
|
1852
|
+
let t = e.name, n = e.expr;
|
|
1853
|
+
_(n, t);
|
|
1854
|
+
}
|
|
1855
|
+
function _(e, t) {
|
|
1856
|
+
if (e instanceof o) {
|
|
1857
|
+
let n = l.get(e), r = new c(X([[n, 1]], 0), ">=", 1, t);
|
|
1858
|
+
s.push(r), u.set(r, t);
|
|
1859
|
+
return;
|
|
1860
|
+
}
|
|
1861
|
+
if (e instanceof n) {
|
|
1862
|
+
if (e.op === "not") {
|
|
1863
|
+
let n = e.children[0];
|
|
1864
|
+
if (n instanceof o) {
|
|
1865
|
+
let e = l.get(n), r = new c(X([[e, 1]], 0), "<=", 0, t);
|
|
1866
|
+
s.push(r), u.set(r, t);
|
|
1867
|
+
return;
|
|
1868
|
+
}
|
|
1869
|
+
let r = m(n, t), i = new c(X([[r, 1]], 0), "<=", 0, t);
|
|
1870
|
+
s.push(i), u.set(i, t);
|
|
1871
|
+
return;
|
|
1872
|
+
}
|
|
1873
|
+
if (e.op === "and") {
|
|
1874
|
+
for (let n = 0; n < e.children.length; n++) _(e.children[n], `${t}_and_${n}`);
|
|
1875
|
+
return;
|
|
1876
|
+
}
|
|
1877
|
+
if (e.op === "or") {
|
|
1878
|
+
if (e.children.every((e) => e instanceof o || e instanceof n)) {
|
|
1879
|
+
let n = e.children.map((e) => m(e, t)).map((e) => [e, 1]), r = new c(X(n, 0), ">=", 1, t);
|
|
1880
|
+
s.push(r), u.set(r, t);
|
|
1881
|
+
return;
|
|
1882
|
+
}
|
|
1883
|
+
let r = [];
|
|
1884
|
+
for (let n = 0; n < e.children.length; n++) {
|
|
1885
|
+
let i = e.children[n], o = new b({
|
|
1886
|
+
name: p(`or_branch_${n}`),
|
|
1887
|
+
type: "Binary",
|
|
1888
|
+
lb: 0,
|
|
1889
|
+
ub: 1
|
|
1890
|
+
});
|
|
1891
|
+
if (a.push(o), r.push(o), i instanceof c) v(o, i, 1, `${t}_or_branch_${n}`, t);
|
|
1892
|
+
else {
|
|
1893
|
+
let e = m(i, t), r = new c(X([[o, 1], [e, -1]], 0), "<=", 0, `${t}_or_bool_${n}`);
|
|
1894
|
+
s.push(r), u.set(r, t);
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
let i = r.map((e) => [e, 1]), l = new c(X(i, 0), ">=", 1, t);
|
|
1898
|
+
s.push(l), u.set(l, t);
|
|
1899
|
+
return;
|
|
1900
|
+
}
|
|
1901
|
+
if (e.op === "xor") {
|
|
1902
|
+
if (e.children.length === 0) {
|
|
1903
|
+
let e = new b({
|
|
1904
|
+
name: p("unsat"),
|
|
1905
|
+
type: "Binary",
|
|
1906
|
+
lb: 0,
|
|
1907
|
+
ub: 0
|
|
1908
|
+
});
|
|
1909
|
+
a.push(e);
|
|
1910
|
+
let n = new c(X([[e, 1]], 0), ">=", 1, t);
|
|
1911
|
+
s.push(n), u.set(n, t);
|
|
1912
|
+
return;
|
|
1913
|
+
}
|
|
1914
|
+
if (e.children.length === 1) {
|
|
1915
|
+
_(e.children[0], t);
|
|
1916
|
+
return;
|
|
1917
|
+
}
|
|
1918
|
+
let n = e.children.map((e) => m(e, t));
|
|
1919
|
+
if (n.length === 2) {
|
|
1920
|
+
let e = new c(X([[n[0], 1], [n[1], 1]], 0), "==", 1, t);
|
|
1921
|
+
s.push(e), u.set(e, t);
|
|
1922
|
+
return;
|
|
1923
|
+
}
|
|
1924
|
+
let r = n[0];
|
|
1925
|
+
for (let e = 1; e < n.length - 1; e++) {
|
|
1926
|
+
let i = new b({
|
|
1927
|
+
name: p(`xor_fold_${e}`),
|
|
1928
|
+
type: "Binary",
|
|
1929
|
+
lb: 0,
|
|
1930
|
+
ub: 1
|
|
1931
|
+
});
|
|
1932
|
+
a.push(i), h(i, r, n[e], `${t}_xor_fold_${e}`), r = i;
|
|
1933
|
+
}
|
|
1934
|
+
let i = n[n.length - 1], o = new c(X([[r, 1], [i, 1]], 0), "==", 1, t);
|
|
1935
|
+
s.push(o), u.set(o, t);
|
|
1936
|
+
return;
|
|
1937
|
+
}
|
|
1938
|
+
if (e.op === "implies") {
|
|
1939
|
+
let [r, i] = e.children;
|
|
1940
|
+
if (r instanceof c && r.lhs.terms.size === 1 && r.lhs.constant === 0) {
|
|
1941
|
+
let [[e, n]] = Array.from(r.lhs.terms.entries());
|
|
1942
|
+
if ((e.type === "Binary" || e.type === "Integer" && e.lb === 0 && e.ub === 1) && n === 1) {
|
|
1943
|
+
let n = null;
|
|
1944
|
+
if (r.sense === "==" && r.rhs === 1 ? n = 1 : r.sense === "==" && r.rhs === 0 || r.sense === "<=" && r.rhs === 0 ? n = 0 : r.sense === ">=" && r.rhs === 1 && (n = 1), n !== null && i instanceof c) {
|
|
1945
|
+
v(e, i, n, t, t);
|
|
1946
|
+
return;
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
let d;
|
|
1951
|
+
if (r instanceof c ? (d = new b({
|
|
1952
|
+
name: p("ante"),
|
|
1953
|
+
type: "Binary",
|
|
1954
|
+
lb: 0,
|
|
1955
|
+
ub: 1
|
|
1956
|
+
}), a.push(d), v(d, r, 1, `${t}_ante_active`, t)) : d = m(r, t), i instanceof c) {
|
|
1957
|
+
v(d, i, 1, t, t);
|
|
1958
|
+
return;
|
|
1959
|
+
}
|
|
1960
|
+
if (i instanceof o) {
|
|
1961
|
+
let e = l.get(i), n = new c(X([[e, 1], [d, -1]], 0), ">=", 0, t);
|
|
1962
|
+
s.push(n), u.set(n, t);
|
|
1963
|
+
return;
|
|
1964
|
+
}
|
|
1965
|
+
if (i instanceof n) {
|
|
1966
|
+
if (i.op === "and") {
|
|
1967
|
+
for (let e = 0; e < i.children.length; e++) _(new n("implies", [d instanceof b ? new ct(d) : r, i.children[e]]), `${t}_and_${e}`);
|
|
1968
|
+
return;
|
|
1969
|
+
}
|
|
1970
|
+
if (i.op === "not") {
|
|
1971
|
+
let e = i.children[0], n = m(e, t), r = new c(X([[d, 1], [n, 1]], 0), "<=", 1, t);
|
|
1972
|
+
s.push(r), u.set(r, t);
|
|
1973
|
+
return;
|
|
1974
|
+
}
|
|
1975
|
+
let e = m(i, t), a = new c(X([[e, 1], [d, -1]], 0), ">=", 0, t);
|
|
1976
|
+
s.push(a), u.set(a, t);
|
|
1977
|
+
return;
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
throw Error(`Unsupported top-level logical constraint "${t}": ${e}`);
|
|
1982
|
+
}
|
|
1983
|
+
function v(e, t, n, r, i) {
|
|
1984
|
+
let { lhs: a, sense: o, rhs: l } = t;
|
|
1985
|
+
if (o === "<=" || o === ">=") {
|
|
1986
|
+
let t = Y(e, a, o, l, n, o === "<=" ? at(a, l, r) : ot(a, l, r), r), d = new c(t.lhs, o, t.rhs, r);
|
|
1987
|
+
s.push(d), u.set(d, i);
|
|
1988
|
+
} else {
|
|
1989
|
+
let t = at(a, l, `${r}_le`), o = ot(a, l, `${r}_ge`), d = Y(e, a, "<=", l, n, t, `${r}_le`), f = Y(e, a, ">=", l, n, o, `${r}_ge`), p = new c(d.lhs, "<=", d.rhs, `${r}_le`), m = new c(f.lhs, ">=", f.rhs, `${r}_ge`);
|
|
1990
|
+
s.push(p, m), u.set(p, i), u.set(m, i);
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
return {
|
|
1994
|
+
variables: a,
|
|
1995
|
+
constraints: s,
|
|
1996
|
+
boolVarToBinary: l,
|
|
1997
|
+
constraintToOriginalName: u
|
|
1998
|
+
};
|
|
1999
|
+
}
|
|
2000
|
+
var ct = class extends o {
|
|
2001
|
+
wrappedVar;
|
|
2002
|
+
constructor(e) {
|
|
2003
|
+
super(e.name), this.wrappedVar = e;
|
|
2004
|
+
}
|
|
2005
|
+
};
|
|
2006
|
+
//#endregion
|
|
2007
|
+
//#region src/decomposition/column-generation.ts
|
|
2008
|
+
async function lt(e) {
|
|
2009
|
+
let t = e.master;
|
|
2010
|
+
if (!t) throw Error("A master Model must be provided for solveColumnGeneration.");
|
|
2011
|
+
let { pricing: n, maxIterations: r = 100, reducedCostTolerance: i = 1e-6, finalizeAsMIP: a = !0, solver: o, solverOptions: s, onIteration: c } = e, l = t.sense.toLowerCase() === "maximize", u = n;
|
|
2012
|
+
if (!u) throw Error("The 'pricing' callback must be provided in ColumnGenerationOptions.");
|
|
2013
|
+
let d = [], f = null, p = 0, m = t.status;
|
|
2014
|
+
for (let e = 1; e <= r; e++) {
|
|
2015
|
+
p = e;
|
|
2016
|
+
let n = await t.relax(o, s);
|
|
2017
|
+
if (m = n, n !== "Optimal" && n !== "Feasible" || !t.solution) break;
|
|
2018
|
+
f = t.objectiveValue;
|
|
2019
|
+
let r = t.solution, a = r.duals || {}, h = (e) => typeof e == "string" ? a[e] ?? 0 : e.dual ?? (e.name ? a[e.name] ?? 0 : 0), g = await u({
|
|
2020
|
+
iteration: e,
|
|
2021
|
+
duals: a,
|
|
2022
|
+
getDual: h,
|
|
2023
|
+
masterSolution: r,
|
|
2024
|
+
reducedCostTolerance: i,
|
|
2025
|
+
master: t
|
|
2026
|
+
}), _ = [];
|
|
2027
|
+
g && (Array.isArray(g) ? _.push(...g) : _.push(g));
|
|
2028
|
+
let v = [];
|
|
2029
|
+
for (let e of _) {
|
|
2030
|
+
let t = e.reducedCost;
|
|
2031
|
+
if (typeof t != "number" || !Number.isFinite(t)) {
|
|
2032
|
+
let n = 0, r = e.coefficients;
|
|
2033
|
+
if (Array.isArray(r)) for (let e of r) Array.isArray(e) ? n += e[1] * h(e[0]) : e && typeof e == "object" && (n += e.coeff * h(e.constraint));
|
|
2034
|
+
else if (r instanceof Map) for (let [e, t] of r.entries()) n += t * h(e);
|
|
2035
|
+
else if (r && typeof r == "object") for (let [e, t] of Object.entries(r)) n += t * h(e);
|
|
2036
|
+
t = e.cost - n;
|
|
2037
|
+
}
|
|
2038
|
+
(l ? t > i : t < -i) && v.push(e);
|
|
2039
|
+
}
|
|
2040
|
+
if (c && c({
|
|
2041
|
+
iteration: e,
|
|
2042
|
+
relaxationObjective: f,
|
|
2043
|
+
columnsAdded: d.length + v.length,
|
|
2044
|
+
proposedColumns: v
|
|
2045
|
+
}), v.length === 0) break;
|
|
2046
|
+
for (let e of v) {
|
|
2047
|
+
let n = t.addColumn({
|
|
2048
|
+
name: e.name,
|
|
2049
|
+
type: e.type || "Continuous",
|
|
2050
|
+
lb: e.lb,
|
|
2051
|
+
ub: e.ub,
|
|
2052
|
+
cost: e.cost,
|
|
2053
|
+
coefficients: e.coefficients
|
|
2054
|
+
});
|
|
2055
|
+
d.push({
|
|
2056
|
+
variable: n,
|
|
2057
|
+
proposal: e
|
|
2058
|
+
});
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
let h = f;
|
|
2062
|
+
a && (m === "Optimal" || m === "Feasible") && (m = await t.solve(o, s), h = t.objectiveValue);
|
|
2063
|
+
let g = {};
|
|
2064
|
+
for (let e of t.variables) e.value !== null && (g[e.name] = e.value);
|
|
2065
|
+
let _ = {
|
|
2066
|
+
status: m,
|
|
2067
|
+
objectiveValue: h,
|
|
2068
|
+
relaxationObjectiveValue: f,
|
|
2069
|
+
iterations: p,
|
|
2070
|
+
columnsAdded: d.length,
|
|
2071
|
+
generatedColumns: d,
|
|
2072
|
+
master: t,
|
|
2073
|
+
values: g
|
|
2074
|
+
};
|
|
2075
|
+
return t.decomposition = _, _;
|
|
2076
|
+
}
|
|
2077
|
+
//#endregion
|
|
2078
|
+
//#region src/modeler/objective.ts
|
|
2079
|
+
function ut(e, t) {
|
|
2080
|
+
let n = e;
|
|
2081
|
+
if (n instanceof c || 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 m.constraint(expr\`... <= ...\`) for constraints, or supply an unconstrained arithmetic expression to ${t}(), e.g. m.objective(${t}(expr\`30 * \${x}\`)).`);
|
|
2082
|
+
if (typeof n == "string" && /(<=|>=|==|=<|=>|=)/.test(n)) throw Error(`Cannot use a comparison constraint as an objective in ${t}(). Use m.constraint(expr\`... <= ...\`) for constraints, or supply an unconstrained arithmetic expression to ${t}(), e.g. m.objective(${t}(expr\`30 * \${x}\`)).`);
|
|
2083
|
+
if (typeof n == "number") {
|
|
2084
|
+
if (!Number.isFinite(n)) throw Error(`Invalid non-finite objective constant "${n}" passed to ${t}().`);
|
|
2085
|
+
return n;
|
|
2086
|
+
}
|
|
2087
|
+
if (typeof n == "string" || n instanceof A || n instanceof k || n instanceof b || 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;
|
|
2088
|
+
throw Error(`Invalid expression passed to ${t}(): expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.`);
|
|
2089
|
+
}
|
|
2090
|
+
function dt(e) {
|
|
2091
|
+
return {
|
|
2092
|
+
expr: ut(e, "maximize"),
|
|
2093
|
+
sense: "Maximize"
|
|
2094
|
+
};
|
|
2095
|
+
}
|
|
2096
|
+
function ft(e) {
|
|
2097
|
+
return {
|
|
2098
|
+
expr: ut(e, "minimize"),
|
|
2099
|
+
sense: "Minimize"
|
|
2100
|
+
};
|
|
2101
|
+
}
|
|
2102
|
+
//#endregion
|
|
2103
|
+
//#region src/decomposition/benders.ts
|
|
2104
|
+
function pt(e) {
|
|
2105
|
+
return !!(e && typeof e == "object" && "constraints" in e && "variables" in e && typeof e.solve == "function");
|
|
2106
|
+
}
|
|
2107
|
+
async function mt(e, t, n, r, i, a, o, s, l = 1) {
|
|
2108
|
+
let u = [];
|
|
2109
|
+
for (let r = 0; r < t.length; r++) {
|
|
2110
|
+
let a = t[r], o = a.lhs, s = a.sense, d = a.rhs - (o.constant || 0), f = [], p = [], m = 0;
|
|
2111
|
+
for (let [e, t] of o.terms.entries()) if (e.ownerModel === n || n.getVarByName(e.name) !== void 0) {
|
|
2112
|
+
p.push([e, t]);
|
|
2113
|
+
let n = i[e.name] ?? 0;
|
|
2114
|
+
m += t * n;
|
|
2115
|
+
} else f.push([e, t]);
|
|
2116
|
+
let h = d - m, g = new A();
|
|
2117
|
+
for (let [e, t] of f) g.addTerm(e, t);
|
|
2118
|
+
let _ = `__benders_link_${l}_${r}`, v = new c(g, s, h, _);
|
|
2119
|
+
e.constraint(v), u.push({
|
|
2120
|
+
origConstraint: a,
|
|
2121
|
+
subConstr: v,
|
|
2122
|
+
masterTerms: p,
|
|
2123
|
+
baseRhs: d
|
|
2124
|
+
});
|
|
2125
|
+
}
|
|
2126
|
+
let d = await e.solve(o, {
|
|
2127
|
+
...s,
|
|
2128
|
+
relax: !0
|
|
2129
|
+
});
|
|
2130
|
+
if (d !== "Optimal" && d !== "Feasible") return null;
|
|
2131
|
+
let f = e.objectiveValue ?? 0, p = i[r.name] ?? 0, m = 1e-4;
|
|
2132
|
+
if (!(a ? p < f - m : p > f + m)) return null;
|
|
2133
|
+
let h = 0, g = /* @__PURE__ */ new Map(), _ = new Set(u.map((e) => e.subConstr.name));
|
|
2134
|
+
for (let t of e.constraints) {
|
|
2135
|
+
if (_.has(t.name)) continue;
|
|
2136
|
+
let n = e.solution?.duals[t.name] ?? t.dual ?? 0;
|
|
2137
|
+
if (Math.abs(n) > 1e-12) {
|
|
2138
|
+
let e = t.rhs - (t.lhs.constant || 0);
|
|
2139
|
+
h += n * e;
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
for (let t of u) {
|
|
2143
|
+
let n = e.solution?.duals[t.subConstr.name] ?? t.subConstr.dual ?? 0;
|
|
2144
|
+
if (Math.abs(n) > 1e-12) {
|
|
2145
|
+
h += n * t.baseRhs;
|
|
2146
|
+
for (let [e, r] of t.masterTerms) {
|
|
2147
|
+
let t = g.get(e) ?? 0;
|
|
2148
|
+
g.set(e, t + n * r);
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
let v = new A();
|
|
2153
|
+
v.addTerm(r, 1);
|
|
2154
|
+
for (let [e, t] of g.entries()) Math.abs(t) > 1e-12 && v.addTerm(e, t);
|
|
2155
|
+
let y = new c(v, a ? ">=" : "<=", h, `__benders_opt_cut_${l}`), b = (n.objectiveValue ?? 0) - p + f;
|
|
2156
|
+
return {
|
|
2157
|
+
kind: "optimality",
|
|
2158
|
+
constraint: y,
|
|
2159
|
+
name: y.name,
|
|
2160
|
+
subproblemObjective: b
|
|
2161
|
+
};
|
|
2162
|
+
}
|
|
2163
|
+
async function ht(e) {
|
|
2164
|
+
let t = e.master;
|
|
2165
|
+
if (!t) throw Error("A master Model must be provided for solveBenders.");
|
|
2166
|
+
let { subproblem: n, maxIterations: r = 100, gapTolerance: i = 1e-4, solver: a, solverOptions: o, onIteration: s } = e, c;
|
|
2167
|
+
e.theta && (c = typeof e.theta == "string" ? t.getVarByName(e.theta) : e.theta), c ||= t.variables.find((e) => e.name === "theta" || e.name === "__benders_theta");
|
|
2168
|
+
let l = 0, u = 0, d = t.status, f, p, m, h = {}, g = null;
|
|
2169
|
+
for (let e = 1; e <= r; e++) {
|
|
2170
|
+
u = e;
|
|
2171
|
+
let r = await t.solve(a, o);
|
|
2172
|
+
if (d = r, r !== "Optimal" && r !== "Feasible") break;
|
|
2173
|
+
let _ = t.objectiveValue, v = t.sense.toLowerCase() === "minimize";
|
|
2174
|
+
v ? f = _ === null ? f : _ : p = _ === null ? p : _;
|
|
2175
|
+
let y = {};
|
|
2176
|
+
for (let e of t.variables) e.value !== null && (y[e.name] = e.value);
|
|
2177
|
+
let b = await n({
|
|
2178
|
+
iteration: e,
|
|
2179
|
+
masterValues: y,
|
|
2180
|
+
getMasterValue: (e) => typeof e == "string" ? y[e] ?? 0 : e.value ?? (e.name ? y[e.name] ?? 0 : 0),
|
|
2181
|
+
masterObjective: _,
|
|
2182
|
+
lowerBound: f,
|
|
2183
|
+
upperBound: p,
|
|
2184
|
+
master: t
|
|
2185
|
+
}), x = [];
|
|
2186
|
+
if (b) {
|
|
2187
|
+
if (pt(b)) {
|
|
2188
|
+
let n = b, r = n.linkingConstraints;
|
|
2189
|
+
c || (c = t.continuous("__benders_theta", { lb: 0 }), v ? t.objective(ft(t.objectiveExpr.add(c))) : t.objective(dt(t.objectiveExpr.sub(c))));
|
|
2190
|
+
let i = await mt(n, r, t, c, y, v, a, o, e);
|
|
2191
|
+
i && x.push(i);
|
|
2192
|
+
} else Array.isArray(b) ? x.push(...b) : x.push(b);
|
|
2193
|
+
}
|
|
2194
|
+
for (let e of x) if (typeof e.subproblemObjective == "number" && Number.isFinite(e.subproblemObjective)) {
|
|
2195
|
+
if (v) {
|
|
2196
|
+
let t = e.subproblemObjective;
|
|
2197
|
+
(p === void 0 || t < p) && (p = t, g = t, h = { ...y });
|
|
2198
|
+
} else {
|
|
2199
|
+
let t = e.subproblemObjective;
|
|
2200
|
+
(f === void 0 || t > f) && (f = t, g = t, h = { ...y });
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
if (f !== void 0 && p !== void 0) {
|
|
2204
|
+
let e = Math.abs(p) + 1e-10;
|
|
2205
|
+
m = Math.abs(p - f) / e;
|
|
2206
|
+
}
|
|
2207
|
+
if (s && s({
|
|
2208
|
+
iteration: e,
|
|
2209
|
+
masterObjective: _,
|
|
2210
|
+
lowerBound: f,
|
|
2211
|
+
upperBound: p,
|
|
2212
|
+
cutsAdded: l + x.length,
|
|
2213
|
+
proposedCuts: x
|
|
2214
|
+
}), x.length === 0) {
|
|
2215
|
+
g = _, h = { ...y };
|
|
2216
|
+
break;
|
|
2217
|
+
}
|
|
2218
|
+
if (m !== void 0 && m <= i) break;
|
|
2219
|
+
for (let e of x) t.constraint(e.constraint, e.name), l++;
|
|
2220
|
+
}
|
|
2221
|
+
let _ = Object.keys(h).length > 0 ? h : (() => {
|
|
2222
|
+
let e = {};
|
|
2223
|
+
for (let n of t.variables) n.value !== null && (e[n.name] = n.value);
|
|
2224
|
+
return e;
|
|
2225
|
+
})(), v = g === null ? t.objectiveValue : g, y = {
|
|
2226
|
+
status: d,
|
|
2227
|
+
objectiveValue: v,
|
|
2228
|
+
lowerBound: f,
|
|
2229
|
+
upperBound: p,
|
|
2230
|
+
gap: m,
|
|
2231
|
+
iterations: u,
|
|
2232
|
+
cutsAdded: l,
|
|
2233
|
+
master: t,
|
|
2234
|
+
values: _
|
|
2235
|
+
};
|
|
2236
|
+
return t.decomposition = y, y;
|
|
2237
|
+
}
|
|
2238
|
+
//#endregion
|
|
1269
2239
|
//#region src/modeler/model.ts
|
|
1270
2240
|
function Z(e) {
|
|
1271
2241
|
return Array.isArray(e) || typeof e == "object" && !!e && !(e instanceof String) && typeof e[Symbol.iterator] == "function";
|
|
@@ -1273,10 +2243,13 @@ function Z(e) {
|
|
|
1273
2243
|
function Q(e) {
|
|
1274
2244
|
return typeof e == "object" && !!e && !Array.isArray(e) && !(e instanceof String) && typeof e[Symbol.iterator] != "function";
|
|
1275
2245
|
}
|
|
2246
|
+
function gt(e) {
|
|
2247
|
+
return e instanceof b || typeof e == "object" && !!e && !(e instanceof r) && !(e instanceof c) && "id" in e && "name" in e && "lb" in e && "ub" in e && !("terms" in e) && !("quadTerms" in e) && !("sense" in e);
|
|
2248
|
+
}
|
|
1276
2249
|
function $(e, t) {
|
|
1277
2250
|
if (!Number.isInteger(e) || e < 0) throw Error(`Invalid count (${e}) for ${t} variable creation: count must be a non-negative integer.`);
|
|
1278
2251
|
}
|
|
1279
|
-
var
|
|
2252
|
+
var _t = class {
|
|
1280
2253
|
name;
|
|
1281
2254
|
_sense;
|
|
1282
2255
|
_objectiveExpr;
|
|
@@ -1285,6 +2258,7 @@ var Re = class {
|
|
|
1285
2258
|
boolVars = [];
|
|
1286
2259
|
logicalConstraints = [];
|
|
1287
2260
|
unsatCore = void 0;
|
|
2261
|
+
_conflicts = void 0;
|
|
1288
2262
|
values = /* @__PURE__ */ new Map();
|
|
1289
2263
|
varMapByName = /* @__PURE__ */ new Map();
|
|
1290
2264
|
varPrefixCounters = /* @__PURE__ */ new Map();
|
|
@@ -1305,6 +2279,8 @@ var Re = class {
|
|
|
1305
2279
|
runTime = 0;
|
|
1306
2280
|
solution = null;
|
|
1307
2281
|
solver = null;
|
|
2282
|
+
decomposition;
|
|
2283
|
+
_linkingConstraints;
|
|
1308
2284
|
hasSolutionState = !1;
|
|
1309
2285
|
modelRevision = 0;
|
|
1310
2286
|
activeOperationId = 0;
|
|
@@ -1316,13 +2292,13 @@ var Re = class {
|
|
|
1316
2292
|
n = typeof e == "string" ? {
|
|
1317
2293
|
...t,
|
|
1318
2294
|
name: e
|
|
1319
|
-
} : e, this.name = n.name || "OptimizationModel", this._sense =
|
|
2295
|
+
} : e, this.name = n.name || "OptimizationModel", this._sense = ye(n.sense), this._objectiveExpr = new A(), n.solver && (this.solver = E(n.solver));
|
|
1320
2296
|
}
|
|
1321
2297
|
get sense() {
|
|
1322
2298
|
return this._sense;
|
|
1323
2299
|
}
|
|
1324
2300
|
set sense(e) {
|
|
1325
|
-
let t =
|
|
2301
|
+
let t = ye(e);
|
|
1326
2302
|
this._sense !== t && (this._sense = t, this.recordModelMutation());
|
|
1327
2303
|
}
|
|
1328
2304
|
get objectiveExpr() {
|
|
@@ -1332,7 +2308,10 @@ var Re = class {
|
|
|
1332
2308
|
this.applyObjective(e);
|
|
1333
2309
|
}
|
|
1334
2310
|
get conflicts() {
|
|
1335
|
-
return this.unsatCore;
|
|
2311
|
+
return this._conflicts ?? this.unsatCore;
|
|
2312
|
+
}
|
|
2313
|
+
set conflicts(e) {
|
|
2314
|
+
this._conflicts = e;
|
|
1336
2315
|
}
|
|
1337
2316
|
get numVars() {
|
|
1338
2317
|
return this.variables.length;
|
|
@@ -1342,7 +2321,7 @@ var Re = class {
|
|
|
1342
2321
|
}
|
|
1343
2322
|
clearSolutionFields() {
|
|
1344
2323
|
if (this.hasSolutionState || this.status !== "NotSolved" || this.terminationStatus !== "NotSolved" || this.hasPrimalSolution || this.solution !== null || this.unsatCore !== void 0) {
|
|
1345
|
-
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();
|
|
2324
|
+
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._conflicts = void 0, this.values.clear();
|
|
1346
2325
|
for (let e of this.variables) e.value = null, e.reducedCost = null;
|
|
1347
2326
|
for (let e of this.boolVars) e.value = null;
|
|
1348
2327
|
for (let e of this.constraints) e.dual = null, e.slack = null;
|
|
@@ -1467,6 +2446,37 @@ var Re = class {
|
|
|
1467
2446
|
continuous(e, t, n) {
|
|
1468
2447
|
return this.createDomainVars("Continuous", e, t, n);
|
|
1469
2448
|
}
|
|
2449
|
+
addColumn(e) {
|
|
2450
|
+
let t = e.type || "Continuous", n = this.addVar({
|
|
2451
|
+
name: e.name,
|
|
2452
|
+
type: t,
|
|
2453
|
+
lb: e.lb,
|
|
2454
|
+
ub: e.ub
|
|
2455
|
+
});
|
|
2456
|
+
if (typeof e.cost == "number" && e.cost !== 0 && (this._objectiveExpr = this._objectiveExpr.add(n.mul(e.cost)), this.recordModelMutation()), e.coefficients) {
|
|
2457
|
+
if (Array.isArray(e.coefficients)) {
|
|
2458
|
+
for (let t of e.coefficients) if (Array.isArray(t)) {
|
|
2459
|
+
let [e, r] = t, i = typeof e == "string" ? this.getConstraintByName(e) : e;
|
|
2460
|
+
if (!i) throw Error(`Constraint '${String(e)}' not found in model when adding column`);
|
|
2461
|
+
i.addTerm(n, r);
|
|
2462
|
+
} else if (typeof t == "object" && t) {
|
|
2463
|
+
let e = typeof t.constraint == "string" ? this.getConstraintByName(t.constraint) : t.constraint;
|
|
2464
|
+
if (!e) throw Error(`Constraint '${String(t.constraint)}' not found in model when adding column`);
|
|
2465
|
+
e.addTerm(n, t.coeff);
|
|
2466
|
+
}
|
|
2467
|
+
} else if (e.coefficients instanceof Map) for (let [t, r] of e.coefficients.entries()) {
|
|
2468
|
+
let e = typeof t == "string" ? this.getConstraintByName(t) : t;
|
|
2469
|
+
if (!e) throw Error(`Constraint '${String(t)}' not found in model when adding column`);
|
|
2470
|
+
e.addTerm(n, r);
|
|
2471
|
+
}
|
|
2472
|
+
else if (typeof e.coefficients == "object") for (let [t, r] of Object.entries(e.coefficients)) {
|
|
2473
|
+
let e = this.getConstraintByName(t);
|
|
2474
|
+
if (!e) throw Error(`Constraint '${t}' not found in model when adding column`);
|
|
2475
|
+
e.addTerm(n, r);
|
|
2476
|
+
}
|
|
2477
|
+
}
|
|
2478
|
+
return n;
|
|
2479
|
+
}
|
|
1470
2480
|
bool(e, t, n) {
|
|
1471
2481
|
let r = typeof e == "number", i = typeof t == "number", a = Z(e), o = Z(t);
|
|
1472
2482
|
if (i || o) {
|
|
@@ -1572,33 +2582,39 @@ var Re = class {
|
|
|
1572
2582
|
return this.logicalConstrMapByName.get(e);
|
|
1573
2583
|
}
|
|
1574
2584
|
objective(e) {
|
|
1575
|
-
|
|
2585
|
+
if (arguments.length === 0) return this.objectiveExpr;
|
|
2586
|
+
let t = e;
|
|
2587
|
+
if (t instanceof c || typeof t == "object" && t && "sense" in t && "lhs" in t && "rhs" in t || typeof t == "string" && /(<=|>=|==|=<|=>|=)/.test(t)) throw Error("Cannot use a Constraint as an objective. Did you mean to use m.constraint(expr`... <= ...`)? To set an objective, wrap an unconstrained expression with maximize(...) or minimize(...), e.g. m.objective(maximize(expr`30 * ${x}`)).");
|
|
2588
|
+
if (typeof t != "object" || !t || !("expr" in t) || !("sense" in t)) throw Error("m.objective(...) expects an ObjectiveSpec created with maximize(...) or minimize(...), e.g. m.objective(maximize(expr`30 * ${x}`)).");
|
|
2589
|
+
return this.applyObjective(t.expr, t.sense), this;
|
|
1576
2590
|
}
|
|
1577
2591
|
applyObjective(e, t) {
|
|
1578
|
-
if (e instanceof c || 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`... <= ...`)?
|
|
1579
|
-
let n = t === void 0 ? this.sense :
|
|
1580
|
-
if (typeof e == "string") r =
|
|
1581
|
-
else if (typeof e == "number") r = new
|
|
2592
|
+
if (e instanceof c || 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`... <= ...`)? To set an objective, wrap an unconstrained expression with maximize(...) or minimize(...), e.g. m.objective(maximize(expr`30 * ${x}`))." : "Cannot use a Constraint as an objective. Did you mean to use m.constraint(expr`... <= ...`)? To set an objective, wrap an unconstrained expression with maximize(...) or minimize(...), e.g. m.objective(maximize(expr`30 * ${x}`)).");
|
|
2593
|
+
let n = t === void 0 ? this.sense : ye(t), r;
|
|
2594
|
+
if (typeof e == "string") r = Ne(e, (e) => this.getVarByName(e));
|
|
2595
|
+
else if (typeof e == "number") r = new A(/* @__PURE__ */ new Map(), e);
|
|
2596
|
+
else if (e instanceof k) r = e.clone();
|
|
1582
2597
|
else if (e instanceof A) r = e.clone();
|
|
1583
|
-
else if (e instanceof j) r = e.clone();
|
|
1584
2598
|
else if (typeof e == "object" && e && "quadTerms" in e && e.quadTerms instanceof Map && "linearTerms" in e && e.linearTerms instanceof Map && typeof e.constant == "number") {
|
|
1585
2599
|
let t = e;
|
|
1586
|
-
r = new
|
|
2600
|
+
r = new k(t.linearTerms, t.quadTerms, t.constant);
|
|
1587
2601
|
} else if (typeof e == "object" && e && "terms" in e && e.terms instanceof Map && typeof e.constant == "number") {
|
|
1588
2602
|
let t = e;
|
|
1589
|
-
r = new
|
|
1590
|
-
} else if (e instanceof b || typeof e == "object" && e && "id" in e && "name" in e && "lb" in e && "ub" in e) r = new
|
|
2603
|
+
r = new A(t.terms, t.constant);
|
|
2604
|
+
} else if (e instanceof b || typeof e == "object" && e && "id" in e && "name" in e && "lb" in e && "ub" in e) r = new A(/* @__PURE__ */ new Map([[e, 1]]), 0);
|
|
1591
2605
|
else throw Error("Invalid objective expression: expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.");
|
|
1592
|
-
|
|
2606
|
+
te(r, this.name, (e) => this.varMapByName.get(e.name) === e), this._sense = n, this._objectiveExpr = r, this.recordModelMutation();
|
|
1593
2607
|
}
|
|
1594
2608
|
constraint(e, t) {
|
|
1595
2609
|
if (Array.isArray(e)) return this.runTransactionalBatch(() => {
|
|
1596
|
-
|
|
1597
|
-
|
|
2610
|
+
let t = [];
|
|
2611
|
+
for (let n of e) t.push(this.constraint(n));
|
|
2612
|
+
return t;
|
|
1598
2613
|
});
|
|
1599
|
-
if (e instanceof
|
|
1600
|
-
if (e instanceof
|
|
1601
|
-
|
|
2614
|
+
if (e instanceof k || typeof e == "object" && e && "quadTerms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a quadratic expression as a constraint.");
|
|
2615
|
+
if (e instanceof A || 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().");
|
|
2616
|
+
if (gt(e)) throw Error(`Cannot add numeric variable "${e.name}" directly as a constraint without a comparison operator (<=, >=, ==). Numeric variables require a comparison such as expr\`\${x} <= 10\` or x.le(10), whereas propositional BoolVar variables must be created with m.bool().`);
|
|
2617
|
+
return this.addConstraint(e, t);
|
|
1602
2618
|
}
|
|
1603
2619
|
getValues(e) {
|
|
1604
2620
|
if (e == null) return null;
|
|
@@ -1612,8 +2628,9 @@ var Re = class {
|
|
|
1612
2628
|
return null;
|
|
1613
2629
|
}
|
|
1614
2630
|
addConstraint(e, t) {
|
|
1615
|
-
if (e instanceof
|
|
1616
|
-
if (e instanceof
|
|
2631
|
+
if (e instanceof k || typeof e == "object" && e && "quadTerms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a quadratic expression as a constraint.");
|
|
2632
|
+
if (e instanceof A || 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().");
|
|
2633
|
+
if (gt(e)) throw Error(`Cannot add numeric variable "${e.name}" directly as a constraint without a comparison operator (<=, >=, ==). Numeric variables require a comparison such as expr\`\${x} <= 10\` or x.le(10), whereas propositional BoolVar variables must be created with m.bool().`);
|
|
1617
2634
|
if (e instanceof r) {
|
|
1618
2635
|
let n = typeof t == "string" && t.trim().length > 0 ? t.trim() : void 0;
|
|
1619
2636
|
if (n !== void 0) {
|
|
@@ -1626,14 +2643,15 @@ var Re = class {
|
|
|
1626
2643
|
} catch (e) {
|
|
1627
2644
|
throw n === void 0 && (this.logicalConstrCounter = r), e;
|
|
1628
2645
|
}
|
|
1629
|
-
|
|
2646
|
+
D(e, this, this.batchDepth > 0 ? this.batchUndoActions : void 0);
|
|
1630
2647
|
let a = {
|
|
1631
2648
|
name: i,
|
|
1632
2649
|
expr: e
|
|
1633
2650
|
};
|
|
1634
2651
|
return this.logicalConstraints.push(a), this.logicalConstrMapByName.set(i, a), this.recordModelMutation(), e;
|
|
1635
2652
|
}
|
|
1636
|
-
let n = typeof e == "string" ?
|
|
2653
|
+
let n = typeof e == "string" ? Ie(e, (e) => this.getVarByName(e), t) : e;
|
|
2654
|
+
if (typeof n != "object" || !n || !("sense" in n) || !("lhs" in n) || !("rhs" in n)) throw Error("Invalid constraint passed to m.constraint(...): expected a linear Constraint (e.g. expr`${x} <= 10` or x.le(10)), a propositional BoolVar/BoolExpr (created with m.bool()), or an array of constraints.");
|
|
1637
2655
|
n.ownerModel && n.ownerModel !== this && (h(n, this.name, (e) => this.varMapByName.get(e.name) === e, n.name), p(n, this));
|
|
1638
2656
|
let i = typeof t == "string" && t.trim().length > 0 ? t.trim() : n.hasExplicitName ? n.name.trim() : void 0;
|
|
1639
2657
|
if (i !== void 0) {
|
|
@@ -1652,40 +2670,41 @@ var Re = class {
|
|
|
1652
2670
|
}), this.batchDepth === 0 && (this.batchUndoActions = []), n._assignModelName(o, !0), n.ownerModel = this, this.constraints.push(n), this.constrMapByName.set(n.name, n), this.recordModelMutation(), n;
|
|
1653
2671
|
}
|
|
1654
2672
|
indicator(e, t, n = {}) {
|
|
1655
|
-
if (
|
|
1656
|
-
if (!(e
|
|
1657
|
-
if (
|
|
1658
|
-
if (
|
|
1659
|
-
|
|
1660
|
-
|
|
2673
|
+
if (e instanceof r) throw Error("Invalid binary variable passed to indicator(): received a propositional BoolVar/BoolExpr, but m.indicator() requires a 0-1 numeric binary Var created with m.binary(). For general boolean logic with m.bool(), use m.constraint(implies(flag, expr`${x} <= 10`)) with the Z3 solver.");
|
|
2674
|
+
if (!(e instanceof b)) throw Error("Invalid binary variable passed to indicator(). Expected a 0-1 binary Var instance created with m.binary() (or use implies(flag, ...) with m.bool() and the Z3 solver for general boolean logic).");
|
|
2675
|
+
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 created with m.binary() (or Integer variable with bounds [0, 1]).`);
|
|
2676
|
+
if (t instanceof k || typeof t == "object" && t && "quadTerms" in t) throw Error("Quadratic expressions or constraints are not supported in indicator constraints (only linear Constraints with <=, >=, or == such as expr`${x} <= 10` are allowed).");
|
|
2677
|
+
if (typeof t != "object" || !t || !("sense" in t) || !("lhs" in t) || !("rhs" in t)) throw Error("Invalid constraint expression passed to indicator(). Expression must include a comparison operator (<=, >=, ==), e.g. m.indicator(b, expr`${x} <= 10`). For general boolean logic (such as BoolVar or implies/and/or/not), use m.constraint(implies(flag, ...)) with the Z3 solver.");
|
|
2678
|
+
let i = t, a = n.activeValue === void 0 ? 1 : n.activeValue;
|
|
2679
|
+
if (a !== 0 && a !== 1) throw Error(`Invalid activeValue: ${a}. Indicator activeValue must be 0 or 1.`);
|
|
1661
2680
|
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.`);
|
|
1662
|
-
let
|
|
1663
|
-
if (
|
|
1664
|
-
else if (
|
|
2681
|
+
let o = typeof n.name == "string" && n.name.trim().length > 0 ? n.name.trim() : void 0, s = this.constrPrefixCounters.get("c"), { lhs: l, sense: u, rhs: d } = i, f, p, m;
|
|
2682
|
+
if (o !== void 0) f = o, p = u === "==" ? `${f}_le` : f, m = u === "==" ? `${f}_ge` : f;
|
|
2683
|
+
else if (i.hasExplicitName) f = `ind_${e.name}_${i.name.trim()}`, p = u === "==" ? `${f}_le` : f, m = u === "==" ? `${f}_ge` : f;
|
|
1665
2684
|
else do {
|
|
1666
2685
|
let t = this.getNextConstrName("c");
|
|
1667
|
-
|
|
1668
|
-
} while ((
|
|
1669
|
-
let
|
|
2686
|
+
f = `ind_${e.name}_${t}`, p = u === "==" ? `${f}_le` : f, m = u === "==" ? `${f}_ge` : f;
|
|
2687
|
+
} while ((u === "<=" || u === "==") && (this.hasConstraintName(p) || this.hasBoolVarName(p)) || (u === ">=" || u === "==") && (this.hasConstraintName(m) || this.hasBoolVarName(m)));
|
|
2688
|
+
let g = [];
|
|
1670
2689
|
try {
|
|
1671
|
-
if ((
|
|
1672
|
-
if ((
|
|
1673
|
-
n.M !== void 0 &&
|
|
2690
|
+
if ((u === "<=" || u === "==") && (this.hasConstraintName(p) || this.hasBoolVarName(p))) throw Error(this.hasBoolVarName(p) ? `Constraint name '${p}' conflicts with an existing Boolean variable in model` : `Constraint with name '${p}' already exists in model`);
|
|
2691
|
+
if ((u === ">=" || u === "==") && (this.hasConstraintName(m) || this.hasBoolVarName(m))) throw Error(this.hasBoolVarName(m) ? `Constraint name '${m}' conflicts with an existing Boolean variable in model` : `Constraint with name '${m}' already exists in model`);
|
|
2692
|
+
n.M !== void 0 && rt(n.M, f);
|
|
1674
2693
|
let t = (e) => this.varMapByName.get(e.name) === e;
|
|
1675
|
-
for (let [e] of
|
|
1676
|
-
if (
|
|
1677
|
-
let t =
|
|
1678
|
-
|
|
2694
|
+
for (let [e] of l.terms) if (!t(e)) throw Error(`Variable "${e.name}" in constraint "${f}" does not belong to model "${this.name}". All variables must belong to the model by object identity.`);
|
|
2695
|
+
if (u === "<=" || u === "==") {
|
|
2696
|
+
let t = Y(e, l, "<=", d, a, n.M === void 0 ? at(l, d, p) : n.M, p);
|
|
2697
|
+
g.push([new c(t.lhs, "<=", t.rhs, p), p]);
|
|
1679
2698
|
}
|
|
1680
|
-
if (
|
|
1681
|
-
let t =
|
|
1682
|
-
|
|
2699
|
+
if (u === ">=" || u === "==") {
|
|
2700
|
+
let t = Y(e, l, ">=", d, a, n.M === void 0 ? ot(l, d, m) : n.M, m);
|
|
2701
|
+
g.push([new c(t.lhs, ">=", t.rhs, m), m]);
|
|
1683
2702
|
}
|
|
1684
|
-
for (let [e, n] of
|
|
2703
|
+
for (let [e, n] of g) h(e, this.name, t, n);
|
|
1685
2704
|
} catch (e) {
|
|
1686
|
-
throw
|
|
2705
|
+
throw s === void 0 ? this.constrPrefixCounters.delete("c") : this.constrPrefixCounters.set("c", s), e;
|
|
1687
2706
|
}
|
|
1688
|
-
return this.runTransactionalBatch(() =>
|
|
2707
|
+
return this.runTransactionalBatch(() => g.map(([e, t]) => this.addConstraint(e, t)));
|
|
1689
2708
|
}
|
|
1690
2709
|
toLpString() {
|
|
1691
2710
|
this.validateIntegrity();
|
|
@@ -1699,7 +2718,7 @@ var Re = class {
|
|
|
1699
2718
|
return e;
|
|
1700
2719
|
}
|
|
1701
2720
|
validateIntegrity() {
|
|
1702
|
-
|
|
2721
|
+
O(this);
|
|
1703
2722
|
}
|
|
1704
2723
|
ensureExecutionValid(e, t, n) {
|
|
1705
2724
|
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.`);
|
|
@@ -1719,6 +2738,9 @@ var Re = class {
|
|
|
1719
2738
|
let t = e.status, n = e.terminationStatus ?? t, r = e.values || {}, i = e.boolValues || {};
|
|
1720
2739
|
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"));
|
|
1721
2740
|
}
|
|
2741
|
+
normalizePrimalValue(e, t, n, r) {
|
|
2742
|
+
return (r.relax ?? n.options?.relax) !== !0 && (e.type === "Integer" || e.type === "Binary") && Math.abs(t - Math.round(t)) <= 1e-5 ? Math.round(t) + 0 : t;
|
|
2743
|
+
}
|
|
1722
2744
|
resolveSolverAndOptions(e, t) {
|
|
1723
2745
|
if (e && typeof e == "object" && "solve" in e && typeof e.solve == "function") {
|
|
1724
2746
|
let { solver: n, ...r } = t || {};
|
|
@@ -1737,27 +2759,44 @@ var Re = class {
|
|
|
1737
2759
|
if (typeof e == "string") {
|
|
1738
2760
|
let { solver: n, ...r } = t || {};
|
|
1739
2761
|
return {
|
|
1740
|
-
activeSolver:
|
|
2762
|
+
activeSolver: E(e, r),
|
|
1741
2763
|
activeOptions: r
|
|
1742
2764
|
};
|
|
1743
2765
|
}
|
|
1744
2766
|
let { solver: n, ...r } = e || {};
|
|
1745
2767
|
return n ? {
|
|
1746
|
-
activeSolver:
|
|
2768
|
+
activeSolver: E(n, r),
|
|
1747
2769
|
activeOptions: r
|
|
1748
2770
|
} : {
|
|
1749
|
-
activeSolver: this.solver ||
|
|
2771
|
+
activeSolver: this.solver || E(),
|
|
1750
2772
|
activeOptions: r
|
|
1751
2773
|
};
|
|
1752
2774
|
}
|
|
2775
|
+
async relax(e, t) {
|
|
2776
|
+
let n = typeof e == "object" && !!e && !("solve" in e), r = n ? {
|
|
2777
|
+
...e,
|
|
2778
|
+
relax: !0
|
|
2779
|
+
} : {
|
|
2780
|
+
...t || {},
|
|
2781
|
+
relax: !0
|
|
2782
|
+
}, i = n ? void 0 : e;
|
|
2783
|
+
return i ? this.solve(i, r) : this.solve(r);
|
|
2784
|
+
}
|
|
1753
2785
|
async solve(e, t) {
|
|
1754
2786
|
let n = ++this.activeOperationId, r = this.modelRevision;
|
|
1755
2787
|
this.clearSolutionFields(), this.validateIntegrity();
|
|
1756
2788
|
let { activeSolver: i, activeOptions: a } = this.resolveSolverAndOptions(e, t);
|
|
1757
|
-
if (this._objectiveExpr instanceof
|
|
1758
|
-
|
|
1759
|
-
if (this.
|
|
1760
|
-
|
|
2789
|
+
if (this._objectiveExpr instanceof k && 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.`);
|
|
2790
|
+
let o, s = null;
|
|
2791
|
+
if (this.logicalConstraints.length > 0 && i.capabilities?.supportsSMT !== !0 ? (s = st(this.variables, this.boolVars, this.constraints, this.logicalConstraints), o = {
|
|
2792
|
+
name: this.name,
|
|
2793
|
+
sense: this.sense,
|
|
2794
|
+
objective: this._objectiveExpr,
|
|
2795
|
+
constraints: s.constraints,
|
|
2796
|
+
variables: s.variables,
|
|
2797
|
+
logicalConstraints: [],
|
|
2798
|
+
boolVars: []
|
|
2799
|
+
}) : o = {
|
|
1761
2800
|
name: this.name,
|
|
1762
2801
|
sense: this.sense,
|
|
1763
2802
|
objective: this._objectiveExpr,
|
|
@@ -1765,53 +2804,68 @@ var Re = class {
|
|
|
1765
2804
|
variables: this.variables,
|
|
1766
2805
|
logicalConstraints: this.logicalConstraints,
|
|
1767
2806
|
boolVars: this.boolVars
|
|
1768
|
-
},
|
|
2807
|
+
}, 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.`);
|
|
2808
|
+
let c = this.wrapSolveOptions(a, r, n), l;
|
|
1769
2809
|
try {
|
|
1770
|
-
|
|
2810
|
+
l = await i.solve(o, c);
|
|
1771
2811
|
} catch (e) {
|
|
1772
2812
|
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
1773
2813
|
}
|
|
1774
|
-
this.ensureExecutionValid(r, n, "solve"), this.runTime =
|
|
1775
|
-
let
|
|
1776
|
-
this.hasPrimalSolution =
|
|
1777
|
-
let
|
|
1778
|
-
this.relGap =
|
|
1779
|
-
let
|
|
2814
|
+
this.ensureExecutionValid(r, n, "solve"), this.runTime = l.runTime ?? 0, this.status = l.status, this.terminationStatus = l.terminationStatus ?? l.status;
|
|
2815
|
+
let u = this.hasPrimalFromResult(l);
|
|
2816
|
+
this.hasPrimalSolution = u, this.objectiveValue = u && typeof l.objectiveValue == "number" && Number.isFinite(l.objectiveValue) ? l.objectiveValue : null, this.objectiveBound = typeof l.objectiveBound == "number" && Number.isFinite(l.objectiveBound) ? l.objectiveBound : void 0;
|
|
2817
|
+
let d = typeof l.relGap == "number" && Number.isFinite(l.relGap) ? l.relGap : typeof l.mipGap == "number" && Number.isFinite(l.mipGap) ? l.mipGap : void 0;
|
|
2818
|
+
this.relGap = d, this.mipGap = d, this.absGap = typeof l.absGap == "number" && Number.isFinite(l.absGap) ? l.absGap : this.objectiveValue !== null && this.objectiveBound !== void 0 ? Math.abs(this.objectiveValue - this.objectiveBound) : void 0;
|
|
2819
|
+
let f = (e, t, n) => {
|
|
1780
2820
|
Object.defineProperty(e, t, {
|
|
1781
2821
|
value: n,
|
|
1782
2822
|
enumerable: !0,
|
|
1783
2823
|
writable: !0,
|
|
1784
2824
|
configurable: !0
|
|
1785
2825
|
});
|
|
1786
|
-
},
|
|
1787
|
-
if (this.values.clear(),
|
|
1788
|
-
for (let [e, t] of Object.entries(
|
|
2826
|
+
}, p = {}, m = {}, h = {}, g = {};
|
|
2827
|
+
if (this.values.clear(), u && l.values) {
|
|
2828
|
+
for (let [e, t] of Object.entries(l.values)) if (typeof t == "number" && Number.isFinite(t)) {
|
|
1789
2829
|
let n = this.getVarByName(e), r = this.getBoolVarByName(e);
|
|
1790
|
-
|
|
2830
|
+
if (n) {
|
|
2831
|
+
let e = this.normalizePrimalValue(n, t, i, a);
|
|
2832
|
+
n.value = e, f(p, n.name, e), this.values.set(n.name, e);
|
|
2833
|
+
}
|
|
2834
|
+
r && (r.value = !!t, this.values.set(r.name, t)), !n && !r && this.values.set(e, t);
|
|
1791
2835
|
} else if (typeof t == "boolean") {
|
|
1792
2836
|
let n = t, r = this.getBoolVarByName(e);
|
|
1793
|
-
r ? (r.value = n,
|
|
2837
|
+
r ? (r.value = n, f(p, r.name, +!!n), this.values.set(r.name, n)) : this.values.set(e, n);
|
|
2838
|
+
}
|
|
2839
|
+
if (s) for (let e of this.boolVars) {
|
|
2840
|
+
let t = s.boolVarToBinary.get(e);
|
|
2841
|
+
if (t && l.values) {
|
|
2842
|
+
let n = l.values[t.name];
|
|
2843
|
+
if (typeof n == "number" && Number.isFinite(n)) {
|
|
2844
|
+
let t = Math.round(n) === 1;
|
|
2845
|
+
e.value = t, f(p, e.name, +!!t), this.values.set(e.name, t);
|
|
2846
|
+
}
|
|
2847
|
+
}
|
|
1794
2848
|
}
|
|
1795
2849
|
}
|
|
1796
|
-
if (
|
|
2850
|
+
if (u && l.boolValues) for (let [e, t] of Object.entries(l.boolValues)) {
|
|
1797
2851
|
if (typeof t != "boolean") continue;
|
|
1798
2852
|
let n = this.getBoolVarByName(e);
|
|
1799
2853
|
n ? (n.value = t, this.values.has(n.name) || this.values.set(n.name, t)) : this.values.has(e) || this.values.set(e, t);
|
|
1800
2854
|
}
|
|
1801
|
-
if (
|
|
2855
|
+
if (u && l.reducedCosts) for (let [e, t] of Object.entries(l.reducedCosts)) {
|
|
1802
2856
|
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
1803
2857
|
let n = this.getVarByName(e);
|
|
1804
|
-
n && (n.reducedCost = t,
|
|
2858
|
+
n && (n.reducedCost = t, f(h, n.name, t));
|
|
1805
2859
|
}
|
|
1806
|
-
if (
|
|
2860
|
+
if (l.duals) for (let [e, t] of Object.entries(l.duals)) {
|
|
1807
2861
|
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
1808
2862
|
let n = this.getConstraintByName(e);
|
|
1809
|
-
n && (n.dual = t,
|
|
2863
|
+
n && (n.dual = t, f(m, n.name, t));
|
|
1810
2864
|
}
|
|
1811
|
-
if (
|
|
2865
|
+
if (l.slacks) for (let [e, t] of Object.entries(l.slacks)) {
|
|
1812
2866
|
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
1813
2867
|
let n = this.getConstraintByName(e);
|
|
1814
|
-
n && (n.slack = t,
|
|
2868
|
+
n && (n.slack = t, f(g, n.name, t));
|
|
1815
2869
|
}
|
|
1816
2870
|
return this.solution = {
|
|
1817
2871
|
status: this.status,
|
|
@@ -1824,19 +2878,18 @@ var Re = class {
|
|
|
1824
2878
|
mipGap: this.mipGap
|
|
1825
2879
|
},
|
|
1826
2880
|
...this.absGap === void 0 ? {} : { absGap: this.absGap },
|
|
1827
|
-
values:
|
|
1828
|
-
duals:
|
|
1829
|
-
reducedCosts:
|
|
1830
|
-
slacks:
|
|
2881
|
+
values: p,
|
|
2882
|
+
duals: m,
|
|
2883
|
+
reducedCosts: h,
|
|
2884
|
+
slacks: g,
|
|
1831
2885
|
runTime: this.runTime,
|
|
1832
|
-
raw:
|
|
2886
|
+
raw: l.raw
|
|
1833
2887
|
}, this.hasSolutionState = !0, this.status;
|
|
1834
2888
|
}
|
|
1835
2889
|
async check(e, t) {
|
|
1836
2890
|
let n = ++this.activeOperationId, r = this.modelRevision;
|
|
1837
2891
|
this.clearSolutionFields(), this.validateIntegrity();
|
|
1838
2892
|
let { activeSolver: i, activeOptions: a } = this.resolveSolverAndOptions(e, t);
|
|
1839
|
-
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.`);
|
|
1840
2893
|
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.`);
|
|
1841
2894
|
let o = this.wrapSolveOptions(a, r, n), s = (e, t, n) => {
|
|
1842
2895
|
Object.defineProperty(e, t, {
|
|
@@ -1845,7 +2898,7 @@ var Re = class {
|
|
|
1845
2898
|
writable: !0,
|
|
1846
2899
|
configurable: !0
|
|
1847
2900
|
});
|
|
1848
|
-
},
|
|
2901
|
+
}, l = {
|
|
1849
2902
|
name: this.name,
|
|
1850
2903
|
variables: this.variables,
|
|
1851
2904
|
boolVars: this.boolVars,
|
|
@@ -1855,17 +2908,21 @@ var Re = class {
|
|
|
1855
2908
|
if (typeof i.check == "function") {
|
|
1856
2909
|
let e;
|
|
1857
2910
|
try {
|
|
1858
|
-
e = await i.check(
|
|
2911
|
+
e = await i.check(l, o);
|
|
1859
2912
|
} catch (e) {
|
|
1860
2913
|
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
1861
2914
|
}
|
|
1862
|
-
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]);
|
|
2915
|
+
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]), this.conflicts = e.conflicts === void 0 ? this.unsatCore : Object.freeze([...e.conflicts]);
|
|
1863
2916
|
let t = {};
|
|
1864
2917
|
if (e.values && e.status === "Sat") {
|
|
1865
2918
|
for (let [n, r] of Object.entries(e.values)) if (typeof r == "number") {
|
|
1866
2919
|
if (!Number.isFinite(r)) continue;
|
|
1867
|
-
let e = this.getVarByName(n),
|
|
1868
|
-
|
|
2920
|
+
let e = this.getVarByName(n), o = this.getBoolVarByName(n);
|
|
2921
|
+
if (e) {
|
|
2922
|
+
let n = this.normalizePrimalValue(e, r, i, a);
|
|
2923
|
+
e.value = n, this.values.set(e.name, n), s(t, e.name, n);
|
|
2924
|
+
}
|
|
2925
|
+
o && (o.value = !!r, this.values.set(o.name, o.value), s(t, o.name, o.value)), !e && !o && (this.values.set(n, r), s(t, n, r));
|
|
1869
2926
|
} else if (typeof r == "boolean") {
|
|
1870
2927
|
let e = this.getBoolVarByName(n);
|
|
1871
2928
|
e ? (e.value = r, this.values.set(e.name, r), s(t, e.name, r)) : (this.values.set(n, r), s(t, n, r));
|
|
@@ -1875,133 +2932,187 @@ var Re = class {
|
|
|
1875
2932
|
status: e.status,
|
|
1876
2933
|
values: t,
|
|
1877
2934
|
unsatCore: this.unsatCore,
|
|
1878
|
-
conflicts: this.
|
|
2935
|
+
conflicts: this.conflicts,
|
|
1879
2936
|
runTime: this.runTime
|
|
1880
2937
|
};
|
|
1881
2938
|
}
|
|
1882
|
-
let
|
|
1883
|
-
|
|
2939
|
+
let u = this.logicalConstraints.length > 0 || this.boolVars.length > 0 ? st(this.variables, this.boolVars, this.constraints, this.logicalConstraints) : {
|
|
2940
|
+
variables: [...this.variables],
|
|
2941
|
+
constraints: [...this.constraints],
|
|
2942
|
+
boolVarToBinary: /* @__PURE__ */ new Map(),
|
|
2943
|
+
constraintToOriginalName: new Map(this.constraints.map((e) => [e, e.name]))
|
|
2944
|
+
}, d = [], f = [], p = [], m = /* @__PURE__ */ new Map(), h = 0;
|
|
2945
|
+
for (let e of u.constraints) {
|
|
2946
|
+
let t = u.constraintToOriginalName.get(e) ?? e.name, { lhs: n, sense: r, rhs: i } = e;
|
|
2947
|
+
if (r === "<=") {
|
|
2948
|
+
let r = new b({
|
|
2949
|
+
name: `__slack_${++h}`,
|
|
2950
|
+
type: "Continuous",
|
|
2951
|
+
lb: 0,
|
|
2952
|
+
ub: Infinity
|
|
2953
|
+
});
|
|
2954
|
+
f.push(r), p.push([r, 1]), m.set(r, t);
|
|
2955
|
+
let a = n.clone().add(new A(/* @__PURE__ */ new Map([[r, -1]]), 0));
|
|
2956
|
+
d.push(new c(a, "<=", i, `${e.name}_slack`));
|
|
2957
|
+
} else if (r === ">=") {
|
|
2958
|
+
let r = new b({
|
|
2959
|
+
name: `__slack_${++h}`,
|
|
2960
|
+
type: "Continuous",
|
|
2961
|
+
lb: 0,
|
|
2962
|
+
ub: Infinity
|
|
2963
|
+
});
|
|
2964
|
+
f.push(r), p.push([r, 1]), m.set(r, t);
|
|
2965
|
+
let a = n.clone().add(new A(/* @__PURE__ */ new Map([[r, 1]]), 0));
|
|
2966
|
+
d.push(new c(a, ">=", i, `${e.name}_slack`));
|
|
2967
|
+
} else {
|
|
2968
|
+
let r = new b({
|
|
2969
|
+
name: `__slack_${++h}_p`,
|
|
2970
|
+
type: "Continuous",
|
|
2971
|
+
lb: 0,
|
|
2972
|
+
ub: Infinity
|
|
2973
|
+
}), a = new b({
|
|
2974
|
+
name: `__slack_${++h}_n`,
|
|
2975
|
+
type: "Continuous",
|
|
2976
|
+
lb: 0,
|
|
2977
|
+
ub: Infinity
|
|
2978
|
+
});
|
|
2979
|
+
f.push(r, a), p.push([r, 1], [a, 1]), m.set(r, t), m.set(a, t);
|
|
2980
|
+
let o = n.clone().add(new A(/* @__PURE__ */ new Map([[r, -1], [a, 1]]), 0));
|
|
2981
|
+
d.push(new c(o, "==", i, `${e.name}_slack`));
|
|
2982
|
+
}
|
|
2983
|
+
}
|
|
2984
|
+
let g = {
|
|
2985
|
+
name: `${this.name}_elastic_check`,
|
|
1884
2986
|
sense: "Minimize",
|
|
1885
|
-
objective: new
|
|
1886
|
-
constraints:
|
|
1887
|
-
variables:
|
|
1888
|
-
|
|
1889
|
-
boolVars: this.boolVars
|
|
1890
|
-
}, u;
|
|
2987
|
+
objective: new A(new Map(p), 0),
|
|
2988
|
+
constraints: d,
|
|
2989
|
+
variables: [...u.variables, ...f]
|
|
2990
|
+
}, _;
|
|
1891
2991
|
try {
|
|
1892
|
-
|
|
2992
|
+
_ = await i.solve(g, o);
|
|
1893
2993
|
} catch (e) {
|
|
1894
2994
|
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
1895
2995
|
}
|
|
1896
|
-
this.ensureExecutionValid(r, n, "check"), this.runTime =
|
|
1897
|
-
let
|
|
1898
|
-
this.status =
|
|
1899
|
-
let
|
|
1900
|
-
if (
|
|
1901
|
-
for (let
|
|
1902
|
-
let
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
2996
|
+
this.ensureExecutionValid(r, n, "check"), this.runTime = _.runTime ?? 0;
|
|
2997
|
+
let v = _.status, y = _.terminationStatus ?? v, x = this.hasPrimalFromResult(_), S = typeof _.objectiveValue == "number" && Number.isFinite(_.objectiveValue) ? _.objectiveValue : Infinity, C = (v === "Optimal" || v === "Feasible" || x) && S <= 1e-5, ee = typeof _.objectiveBound == "number" && Number.isFinite(_.objectiveBound) && _.objectiveBound > 1e-5, w = !C && (v === "Infeasible" || v === "Optimal" && S > 1e-5 || ee), T = C ? "Sat" : w ? "Unsat" : "Unknown";
|
|
2998
|
+
this.status = T, this.terminationStatus = a.signal?.aborted || y === "Interrupted" ? "Interrupted" : y === "Optimal" || y === "Feasible" || y === "Infeasible" ? T : y, this.hasPrimalSolution = C, 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();
|
|
2999
|
+
let E = {};
|
|
3000
|
+
if (C && _.values) {
|
|
3001
|
+
for (let e of this.variables) {
|
|
3002
|
+
let t = _.values[e.name];
|
|
3003
|
+
if (typeof t == "number" && Number.isFinite(t)) {
|
|
3004
|
+
let n = this.normalizePrimalValue(e, t, i, a);
|
|
3005
|
+
e.value = n, this.values.set(e.name, n), s(E, e.name, n);
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
3008
|
+
for (let e of this.boolVars) {
|
|
3009
|
+
let t = u.boolVarToBinary.get(e), n = t ? _.values[t.name] : _.values[e.name];
|
|
3010
|
+
if (typeof n == "number" && Number.isFinite(n)) {
|
|
3011
|
+
let t = Math.round(n) === 1;
|
|
3012
|
+
e.value = t, this.values.set(e.name, t), s(E, e.name, t);
|
|
3013
|
+
}
|
|
1907
3014
|
}
|
|
1908
3015
|
}
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
let n =
|
|
1912
|
-
n
|
|
1913
|
-
}
|
|
1914
|
-
if (u.slacks) for (let [e, t] of Object.entries(u.slacks)) {
|
|
1915
|
-
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
1916
|
-
let n = this.getConstraintByName(e);
|
|
1917
|
-
n && (n.slack = t);
|
|
3016
|
+
let D = /* @__PURE__ */ new Set();
|
|
3017
|
+
if (w && _.values) for (let [e, t] of m.entries()) {
|
|
3018
|
+
let n = _.values[e.name];
|
|
3019
|
+
typeof n == "number" && n > 1e-5 && D.add(t);
|
|
1918
3020
|
}
|
|
1919
|
-
return this.hasSolutionState = !0, {
|
|
1920
|
-
status:
|
|
1921
|
-
values:
|
|
3021
|
+
return this.conflicts = w ? Object.freeze(Array.from(D)) : void 0, this.unsatCore = void 0, this.hasSolutionState = !0, {
|
|
3022
|
+
status: T,
|
|
3023
|
+
values: E,
|
|
3024
|
+
conflicts: this.conflicts,
|
|
3025
|
+
unsatCore: this.unsatCore,
|
|
1922
3026
|
runTime: this.runTime
|
|
1923
3027
|
};
|
|
1924
3028
|
}
|
|
1925
3029
|
validateSolution(e = {}) {
|
|
1926
|
-
return
|
|
3030
|
+
return nt(this, e);
|
|
3031
|
+
}
|
|
3032
|
+
link(e) {
|
|
3033
|
+
if (e instanceof k || typeof e == "object" && e && "quadTerms" in e) throw Error("Linking constraint cannot be a quadratic expression.");
|
|
3034
|
+
if (!(e instanceof c) && (typeof e != "object" || !e || !("sense" in e) || !("lhs" in e) || !("rhs" in e))) throw Error("Linking constraint must contain a comparison operator (<=, >=, ==). Use expr`... <= ...` or .le(), .ge(), .eq().");
|
|
3035
|
+
this._linkingConstraints ||= [];
|
|
3036
|
+
let t = e;
|
|
3037
|
+
return this._linkingConstraints.push(t), t;
|
|
3038
|
+
}
|
|
3039
|
+
get linkingConstraints() {
|
|
3040
|
+
return this._linkingConstraints ?? [];
|
|
3041
|
+
}
|
|
3042
|
+
async solveBenders(e) {
|
|
3043
|
+
let t = await ht({
|
|
3044
|
+
master: this,
|
|
3045
|
+
...e
|
|
3046
|
+
});
|
|
3047
|
+
return this.decomposition = t, t;
|
|
1927
3048
|
}
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
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}().`);
|
|
1935
|
-
if (typeof n == "number") {
|
|
1936
|
-
if (!Number.isFinite(n)) throw Error(`Invalid non-finite objective constant "${n}" passed to ${t}().`);
|
|
1937
|
-
return n;
|
|
3049
|
+
async solveColumnGeneration(e) {
|
|
3050
|
+
let t = await lt({
|
|
3051
|
+
master: this,
|
|
3052
|
+
...e
|
|
3053
|
+
});
|
|
3054
|
+
return this.decomposition = t, t;
|
|
1938
3055
|
}
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
}
|
|
1942
|
-
function Be(e) {
|
|
1943
|
-
return {
|
|
1944
|
-
expr: ze(e, "maximize"),
|
|
1945
|
-
sense: "Maximize"
|
|
1946
|
-
};
|
|
1947
|
-
}
|
|
1948
|
-
function Ve(e) {
|
|
1949
|
-
return {
|
|
1950
|
-
expr: ze(e, "minimize"),
|
|
1951
|
-
sense: "Minimize"
|
|
1952
|
-
};
|
|
1953
|
-
}
|
|
1954
|
-
z(/* @__PURE__ */ se({
|
|
3056
|
+
};
|
|
3057
|
+
I(/* @__PURE__ */ _e({
|
|
1955
3058
|
BoolExpr: () => r,
|
|
1956
3059
|
BoolOp: () => n,
|
|
1957
3060
|
BoolVar: () => o,
|
|
1958
3061
|
Constraint: () => c,
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
3062
|
+
HIGHS_CONSTANTS: () => oe,
|
|
3063
|
+
HIGHS_STATUS_NAMES: () => de,
|
|
3064
|
+
HiGHS: () => Ke,
|
|
3065
|
+
Highs: () => ne,
|
|
3066
|
+
HighsError: () => re,
|
|
3067
|
+
HighsModel: () => le,
|
|
3068
|
+
HighsSolver: () => J,
|
|
3069
|
+
HighsUnsupportedOptionError: () => se,
|
|
3070
|
+
LinExpr: () => A,
|
|
3071
|
+
MockSolver: () => Qe,
|
|
3072
|
+
Model: () => _t,
|
|
3073
|
+
OFFICIAL_HIGHS_CDN_WASM_URL: () => ue,
|
|
3074
|
+
QuadExpr: () => k,
|
|
1966
3075
|
Var: () => b,
|
|
1967
3076
|
and: () => y,
|
|
1968
|
-
|
|
3077
|
+
bindHighsFunctions: () => ie,
|
|
3078
|
+
buildIndicatorLinearization: () => Y,
|
|
1969
3079
|
buildLpSymbolMaps: () => u,
|
|
1970
|
-
deriveBigMForGe: () =>
|
|
1971
|
-
deriveBigMForLe: () =>
|
|
3080
|
+
deriveBigMForGe: () => ot,
|
|
3081
|
+
deriveBigMForLe: () => at,
|
|
1972
3082
|
dot: () => s,
|
|
1973
|
-
expr: () =>
|
|
3083
|
+
expr: () => Re,
|
|
1974
3084
|
generateLpString: () => C,
|
|
1975
|
-
getHighs: () =>
|
|
1976
|
-
getHighsWasmUrl: () =>
|
|
1977
|
-
getSolver: () =>
|
|
3085
|
+
getHighs: () => ce,
|
|
3086
|
+
getHighsWasmUrl: () => P,
|
|
3087
|
+
getSolver: () => E,
|
|
1978
3088
|
implies: () => e,
|
|
1979
|
-
isLpExportResult: () =>
|
|
1980
|
-
isValidWasmHeader: () =>
|
|
3089
|
+
isLpExportResult: () => T,
|
|
3090
|
+
isValidWasmHeader: () => ae,
|
|
3091
|
+
linearizeModelForMip: () => st,
|
|
1981
3092
|
listAvailableSolvers: () => S,
|
|
1982
|
-
mapHighsStatus: () =>
|
|
1983
|
-
mapHighsTerminationStatus: () =>
|
|
1984
|
-
maximize: () =>
|
|
1985
|
-
minimize: () =>
|
|
3093
|
+
mapHighsStatus: () => Ge,
|
|
3094
|
+
mapHighsTerminationStatus: () => q,
|
|
3095
|
+
maximize: () => dt,
|
|
3096
|
+
minimize: () => ft,
|
|
1986
3097
|
not: () => v,
|
|
1987
3098
|
or: () => i,
|
|
1988
|
-
parseConstraint: () =>
|
|
1989
|
-
parseExpr: () =>
|
|
1990
|
-
probeWasmUrl: () =>
|
|
1991
|
-
registerHighsSolver: () =>
|
|
1992
|
-
registerMockSolver: () =>
|
|
1993
|
-
registerSolver: () =>
|
|
1994
|
-
resolveBrowserWasmUrl: () =>
|
|
3099
|
+
parseConstraint: () => Ie,
|
|
3100
|
+
parseExpr: () => Ne,
|
|
3101
|
+
probeWasmUrl: () => j,
|
|
3102
|
+
registerHighsSolver: () => qe,
|
|
3103
|
+
registerMockSolver: () => $e,
|
|
3104
|
+
registerSolver: () => w,
|
|
3105
|
+
resolveBrowserWasmUrl: () => N,
|
|
1995
3106
|
sanitizeIdentifier: () => f,
|
|
1996
3107
|
setDefaultSolver: () => _,
|
|
1997
|
-
setHighsWasmUrl: () =>
|
|
1998
|
-
solveLp: () =>
|
|
1999
|
-
solveLpWithHighs: () =>
|
|
3108
|
+
setHighsWasmUrl: () => F,
|
|
3109
|
+
solveLp: () => We,
|
|
3110
|
+
solveLpWithHighs: () => M,
|
|
2000
3111
|
sum: () => t,
|
|
2001
|
-
validateModelIntegrity: () =>
|
|
2002
|
-
validateModelSolution: () =>
|
|
2003
|
-
validateUserBigM: () =>
|
|
3112
|
+
validateModelIntegrity: () => O,
|
|
3113
|
+
validateModelSolution: () => nt,
|
|
3114
|
+
validateUserBigM: () => rt,
|
|
2004
3115
|
xor: () => a
|
|
2005
|
-
}),
|
|
3116
|
+
}), et);
|
|
2006
3117
|
//#endregion
|
|
2007
|
-
export { r as BoolExpr, n as BoolOp, o as BoolVar, c as Constraint,
|
|
3118
|
+
export { r as BoolExpr, n as BoolOp, o as BoolVar, c as Constraint, Ke as HiGHS, ne as Highs, J as HighsSolver, A as LinExpr, Qe as MockSolver, _t as Model, k as QuadExpr, b as Var, y as and, Y as buildIndicatorLinearization, u as buildLpSymbolMaps, ot as deriveBigMForGe, at as deriveBigMForLe, s as dot, Re as expr, C as generateLpString, ce as getHighs, P as getHighsWasmUrl, E as getSolver, e as implies, T as isLpExportResult, st as linearizeModelForMip, S as listAvailableSolvers, dt as maximize, ft as minimize, ye as normalizeSense, v as not, i as or, Ie as parseConstraint, Ne as parseExpr, w as registerSolver, f as sanitizeIdentifier, _ as setDefaultSolver, F as setHighsWasmUrl, ht as solveBenders, lt as solveColumnGeneration, M as solveLpWithHighs, t as sum, O as validateModelIntegrity, nt as validateModelSolution, rt as validateUserBigM, a as xor };
|