@ohtaman/washi 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +111 -118
- package/README.md +109 -116
- package/README.zh-CN.md +112 -119
- package/dist/browser/highs-worker.js +21 -3
- package/dist/browser/loader-CtaDHef_.js +273 -0
- package/dist/browser/solvers/glpk.js +433 -286
- package/dist/browser/solvers/glpk.min.js +1 -1
- package/dist/browser/solvers/z3.js +1002 -981
- package/dist/browser/solvers/z3.min.js +2 -2
- package/dist/browser/washi.js +2178 -622
- package/dist/browser/washi.min.js +4 -4
- package/dist/lib/highs-worker.js +21 -3
- package/dist/lib/loader-DmNC_UNk.js +279 -0
- package/dist/lib/registry-BEfvpZW3.js +951 -0
- package/dist/lib/solvers/glpk.js +201 -90
- package/dist/lib/solvers/z3.js +399 -259
- package/dist/lib/washi.js +1674 -932
- package/dist/types/index.d.ts +4 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/modeler/big-m.d.ts +75 -0
- package/dist/types/modeler/big-m.d.ts.map +1 -0
- package/dist/types/modeler/boolean-expr.d.ts +103 -14
- package/dist/types/modeler/boolean-expr.d.ts.map +1 -1
- package/dist/types/modeler/constraint.d.ts +36 -9
- package/dist/types/modeler/constraint.d.ts.map +1 -1
- package/dist/types/modeler/expression.d.ts +117 -27
- package/dist/types/modeler/expression.d.ts.map +1 -1
- package/dist/types/modeler/index.d.ts +10 -6
- package/dist/types/modeler/index.d.ts.map +1 -1
- package/dist/types/modeler/lp-writer.d.ts +27 -2
- package/dist/types/modeler/lp-writer.d.ts.map +1 -1
- package/dist/types/modeler/model.d.ts +491 -140
- package/dist/types/modeler/model.d.ts.map +1 -1
- package/dist/types/modeler/objective.d.ts +59 -0
- package/dist/types/modeler/objective.d.ts.map +1 -0
- package/dist/types/modeler/parser.d.ts +39 -14
- package/dist/types/modeler/parser.d.ts.map +1 -1
- package/dist/types/modeler/quad-expr.d.ts +28 -7
- package/dist/types/modeler/quad-expr.d.ts.map +1 -1
- package/dist/types/modeler/solution-validator.d.ts +93 -0
- package/dist/types/modeler/solution-validator.d.ts.map +1 -0
- package/dist/types/modeler/solvers/glpk/solver.d.ts +26 -2
- package/dist/types/modeler/solvers/glpk/solver.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/loader.d.ts +36 -11
- package/dist/types/modeler/solvers/highs/loader.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/solver.d.ts +11 -4
- package/dist/types/modeler/solvers/highs/solver.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/worker-client.d.ts.map +1 -1
- package/dist/types/modeler/solvers/mock.d.ts +14 -5
- package/dist/types/modeler/solvers/mock.d.ts.map +1 -1
- package/dist/types/modeler/solvers/types.d.ts +71 -11
- package/dist/types/modeler/solvers/types.d.ts.map +1 -1
- package/dist/types/modeler/solvers/z3/loader.d.ts +2 -3
- package/dist/types/modeler/solvers/z3/loader.d.ts.map +1 -1
- package/dist/types/modeler/solvers/z3/solver.d.ts +15 -5
- package/dist/types/modeler/solvers/z3/solver.d.ts.map +1 -1
- package/dist/types/modeler/types.d.ts +60 -2
- package/dist/types/modeler/types.d.ts.map +1 -1
- package/dist/types/modeler/validation.d.ts +56 -0
- package/dist/types/modeler/validation.d.ts.map +1 -0
- package/dist/types/modeler/variable.d.ts +53 -13
- package/dist/types/modeler/variable.d.ts.map +1 -1
- package/docs/examples/diet-sensitivity.md +90 -0
- package/docs/examples/ecommerce-coupons.md +106 -0
- package/docs/examples/index.md +53 -0
- package/docs/examples/knapsack.md +60 -0
- package/docs/examples/portfolio-qp.md +83 -0
- package/docs/examples/production.md +51 -0
- package/docs/examples/shift-scheduling.md +175 -0
- package/docs/examples/smt-security.md +74 -0
- package/docs/examples/transportation.md +90 -0
- package/docs/examples/unsat-core.md +64 -0
- package/docs/getting-started/ai-agents.md +267 -0
- package/docs/getting-started/cross-origin.md +87 -0
- package/docs/getting-started/index.md +116 -0
- package/docs/getting-started/runtimes.md +227 -0
- package/docs/guide/constraints.md +177 -0
- package/docs/guide/expressions.md +204 -0
- package/docs/guide/objectives.md +170 -0
- package/docs/guide/unsat-core.md +147 -0
- package/docs/guide/variables.md +188 -0
- package/docs/ja/getting-started/ai-agents.md +266 -0
- package/docs/solvers/custom-solver.md +525 -0
- package/docs/solvers/glpk.md +66 -0
- package/docs/solvers/highs.md +93 -0
- package/docs/solvers/index.md +42 -0
- package/docs/solvers/z3.md +78 -0
- package/docs/zh/getting-started/ai-agents.md +266 -0
- package/llms-full.txt +3249 -0
- package/llms.txt +197 -0
- package/package.json +19 -6
- package/skills/washi/SKILL.md +197 -0
- package/dist/browser/loader-CVt4CloI.js +0 -58
- package/dist/lib/async-mutex-Duo4jwzn.js +0 -195
- package/dist/lib/constraint-BRuB3ooC.js +0 -90
- package/dist/lib/loader-Dti0v9yC.js +0 -50
- package/dist/lib/registry-DksqCSjI.js +0 -32
package/dist/lib/washi.js
CHANGED
|
@@ -1,441 +1,119 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { i as
|
|
3
|
-
import {
|
|
4
|
-
import { createHighsWorker as ee } from "./highs-worker-factory.js";
|
|
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 w, r as T, s as E, t as D, u as O, v as k, w as A, x as j, y as ee } from "./registry-BEfvpZW3.js";
|
|
2
|
+
import { a as M, c as N, i as P, n as F, o as I, r as L, s as R, t as te } from "./loader-DmNC_UNk.js";
|
|
3
|
+
import { createHighsWorker as ne } from "./highs-worker-factory.js";
|
|
5
4
|
//#region \0rolldown/runtime.js
|
|
6
|
-
var
|
|
5
|
+
var re = Object.defineProperty, ie = Object.getOwnPropertyDescriptor, ae = Object.getOwnPropertyNames, oe = Object.prototype.hasOwnProperty, se = (e, t) => {
|
|
7
6
|
let n = {};
|
|
8
|
-
for (var r in e)
|
|
7
|
+
for (var r in e) re(n, r, {
|
|
9
8
|
get: e[r],
|
|
10
9
|
enumerable: !0
|
|
11
10
|
});
|
|
12
|
-
return t ||
|
|
13
|
-
},
|
|
14
|
-
if (t && typeof t == "object" || typeof t == "function") for (var i =
|
|
11
|
+
return t || re(n, Symbol.toStringTag, { value: "Module" }), n;
|
|
12
|
+
}, ce = (e, t, n, r) => {
|
|
13
|
+
if (t && typeof t == "object" || typeof t == "function") for (var i = ae(t), a = 0, o = i.length, s; a < o; a++) s = i[a], !oe.call(e, s) && s !== n && re(e, s, {
|
|
15
14
|
get: ((e) => t[e]).bind(null, s),
|
|
16
|
-
enumerable: !(r =
|
|
15
|
+
enumerable: !(r = ie(t, s)) || r.enumerable
|
|
17
16
|
});
|
|
18
17
|
return e;
|
|
19
|
-
},
|
|
18
|
+
}, z = (e, t, n) => (ce(e, t, "default"), n && ce(n, t, "default"));
|
|
20
19
|
//#endregion
|
|
21
20
|
//#region src/modeler/types.ts
|
|
22
|
-
function
|
|
23
|
-
|
|
21
|
+
function le(e) {
|
|
22
|
+
if (e === void 0) return "Minimize";
|
|
23
|
+
if (typeof e == "string") {
|
|
24
|
+
let t = e.toLowerCase();
|
|
25
|
+
if (t === "maximize") return "Maximize";
|
|
26
|
+
if (t === "minimize") return "Minimize";
|
|
27
|
+
}
|
|
28
|
+
throw Error(`Invalid optimization sense "${String(e)}": expected "Maximize", "Minimize", "maximize", or "minimize".`);
|
|
24
29
|
}
|
|
25
30
|
//#endregion
|
|
26
|
-
//#region src/modeler/quad-expr.ts
|
|
27
|
-
function E(e, t) {
|
|
28
|
-
let n = e.id, r = t.id;
|
|
29
|
-
return n <= r ? `${n}:${r}` : `${r}:${n}`;
|
|
30
|
-
}
|
|
31
|
-
var D = class e {
|
|
32
|
-
linearTerms;
|
|
33
|
-
quadTerms;
|
|
34
|
-
constant;
|
|
35
|
-
constructor(e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map(), n = 0) {
|
|
36
|
-
this.linearTerms = new Map(e), this.quadTerms = /* @__PURE__ */ new Map();
|
|
37
|
-
for (let [e, n] of t) this.quadTerms.set(e, { ...n });
|
|
38
|
-
this.constant = n;
|
|
39
|
-
}
|
|
40
|
-
clone() {
|
|
41
|
-
return new e(this.linearTerms, this.quadTerms, this.constant);
|
|
42
|
-
}
|
|
43
|
-
getQuadCoeff(e, t) {
|
|
44
|
-
let n = E(e, t), r = this.quadTerms.get(n);
|
|
45
|
-
return r ? r.coeff : 0;
|
|
46
|
-
}
|
|
47
|
-
add(t) {
|
|
48
|
-
let n = this.clone();
|
|
49
|
-
if (typeof t == "number") return n.constant += t, n;
|
|
50
|
-
if (t instanceof e) {
|
|
51
|
-
for (let [e, r] of t.quadTerms) {
|
|
52
|
-
let t = n.quadTerms.get(e), i = (t ? t.coeff : 0) + r.coeff;
|
|
53
|
-
Math.abs(i) < 1e-12 ? n.quadTerms.delete(e) : n.quadTerms.set(e, {
|
|
54
|
-
var1: r.var1,
|
|
55
|
-
var2: r.var2,
|
|
56
|
-
coeff: i
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
for (let [e, r] of t.linearTerms) {
|
|
60
|
-
let t = (n.linearTerms.get(e) || 0) + r;
|
|
61
|
-
Math.abs(t) < 1e-12 ? n.linearTerms.delete(e) : n.linearTerms.set(e, t);
|
|
62
|
-
}
|
|
63
|
-
return n.constant += t.constant, n;
|
|
64
|
-
}
|
|
65
|
-
if ("terms" in t && t.terms instanceof Map) {
|
|
66
|
-
for (let [e, r] of t.terms) {
|
|
67
|
-
let t = (n.linearTerms.get(e) || 0) + r;
|
|
68
|
-
Math.abs(t) < 1e-12 ? n.linearTerms.delete(e) : n.linearTerms.set(e, t);
|
|
69
|
-
}
|
|
70
|
-
return n.constant += t.constant, n;
|
|
71
|
-
}
|
|
72
|
-
let r = t, i = (n.linearTerms.get(r) || 0) + 1;
|
|
73
|
-
return Math.abs(i) < 1e-12 ? n.linearTerms.delete(r) : n.linearTerms.set(r, i), n;
|
|
74
|
-
}
|
|
75
|
-
sub(t) {
|
|
76
|
-
return typeof t == "number" ? this.add(-t) : t instanceof e ? this.add(t.neg()) : ("terms" in t && t.terms instanceof Map, this.add(t.mul(-1)));
|
|
77
|
-
}
|
|
78
|
-
mul(t) {
|
|
79
|
-
let n = new e(/* @__PURE__ */ new Map(), /* @__PURE__ */ new Map(), this.constant * t);
|
|
80
|
-
for (let [e, r] of this.linearTerms) {
|
|
81
|
-
let i = r * t;
|
|
82
|
-
Math.abs(i) >= 1e-12 && n.linearTerms.set(e, i);
|
|
83
|
-
}
|
|
84
|
-
for (let [e, r] of this.quadTerms) {
|
|
85
|
-
let i = r.coeff * t;
|
|
86
|
-
Math.abs(i) >= 1e-12 && n.quadTerms.set(e, {
|
|
87
|
-
var1: r.var1,
|
|
88
|
-
var2: r.var2,
|
|
89
|
-
coeff: i
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
return n;
|
|
93
|
-
}
|
|
94
|
-
div(e) {
|
|
95
|
-
if (Math.abs(e) < 1e-12) throw Error("Division by zero in QuadExpr.div()");
|
|
96
|
-
return this.mul(1 / e);
|
|
97
|
-
}
|
|
98
|
-
neg() {
|
|
99
|
-
return this.mul(-1);
|
|
100
|
-
}
|
|
101
|
-
get value() {
|
|
102
|
-
let e = this.constant;
|
|
103
|
-
for (let [t, n] of this.linearTerms) {
|
|
104
|
-
if (t.value === null) return null;
|
|
105
|
-
e += n * t.value;
|
|
106
|
-
}
|
|
107
|
-
for (let t of this.quadTerms.values()) {
|
|
108
|
-
if (t.var1.value === null || t.var2.value === null) return null;
|
|
109
|
-
e += t.coeff * t.var1.value * t.var2.value;
|
|
110
|
-
}
|
|
111
|
-
return e;
|
|
112
|
-
}
|
|
113
|
-
getValue() {
|
|
114
|
-
return this.value;
|
|
115
|
-
}
|
|
116
|
-
static fromProduct(t, n, r = 1) {
|
|
117
|
-
let i = new e(), a = E(t, n);
|
|
118
|
-
return i.quadTerms.set(a, {
|
|
119
|
-
var1: t.id <= n.id ? t : n,
|
|
120
|
-
var2: t.id <= n.id ? n : t,
|
|
121
|
-
coeff: r
|
|
122
|
-
}), i;
|
|
123
|
-
}
|
|
124
|
-
}, O = class e {
|
|
125
|
-
terms;
|
|
126
|
-
constant;
|
|
127
|
-
constructor(e = /* @__PURE__ */ new Map(), t = 0) {
|
|
128
|
-
this.terms = new Map(e), this.constant = t;
|
|
129
|
-
}
|
|
130
|
-
clone() {
|
|
131
|
-
return new e(this.terms, this.constant);
|
|
132
|
-
}
|
|
133
|
-
add(e) {
|
|
134
|
-
if (e instanceof D) return e.add(this);
|
|
135
|
-
let t = this.clone();
|
|
136
|
-
if (typeof e == "number") t.constant += e;
|
|
137
|
-
else if ("terms" in e) {
|
|
138
|
-
for (let [n, r] of e.terms) {
|
|
139
|
-
let e = (t.terms.get(n) || 0) + r;
|
|
140
|
-
Math.abs(e) < 1e-12 ? t.terms.delete(n) : t.terms.set(n, e);
|
|
141
|
-
}
|
|
142
|
-
t.constant += e.constant;
|
|
143
|
-
} else {
|
|
144
|
-
let n = (t.terms.get(e) || 0) + 1;
|
|
145
|
-
Math.abs(n) < 1e-12 ? t.terms.delete(e) : t.terms.set(e, n);
|
|
146
|
-
}
|
|
147
|
-
return t;
|
|
148
|
-
}
|
|
149
|
-
sub(e) {
|
|
150
|
-
return e instanceof D ? e.neg().add(this) : typeof e == "number" ? this.add(-e) : ("terms" in e, this.add(e.mul(-1)));
|
|
151
|
-
}
|
|
152
|
-
mul(t) {
|
|
153
|
-
if (typeof t == "number") {
|
|
154
|
-
let n = new e(/* @__PURE__ */ new Map(), this.constant * t);
|
|
155
|
-
for (let [e, r] of this.terms) {
|
|
156
|
-
let i = r * t;
|
|
157
|
-
Math.abs(i) >= 1e-12 && n.terms.set(e, i);
|
|
158
|
-
}
|
|
159
|
-
return n;
|
|
160
|
-
}
|
|
161
|
-
let n = new D();
|
|
162
|
-
Math.abs(this.constant) >= 1e-12 && n.linearTerms.set(t, this.constant);
|
|
163
|
-
for (let [e, r] of this.terms) n = n.add(D.fromProduct(e, t, r));
|
|
164
|
-
return n;
|
|
165
|
-
}
|
|
166
|
-
div(e) {
|
|
167
|
-
if (Math.abs(e) < 1e-12) throw Error("Division by zero in LinExpr.div()");
|
|
168
|
-
return this.mul(1 / e);
|
|
169
|
-
}
|
|
170
|
-
neg() {
|
|
171
|
-
return this.mul(-1);
|
|
172
|
-
}
|
|
173
|
-
get value() {
|
|
174
|
-
let e = this.constant;
|
|
175
|
-
for (let [t, n] of this.terms) {
|
|
176
|
-
if (t.value === null) return null;
|
|
177
|
-
e += n * t.value;
|
|
178
|
-
}
|
|
179
|
-
return e;
|
|
180
|
-
}
|
|
181
|
-
getValue() {
|
|
182
|
-
return this.value;
|
|
183
|
-
}
|
|
184
|
-
le(e, t) {
|
|
185
|
-
return this.toConstraint("<=", e, t);
|
|
186
|
-
}
|
|
187
|
-
lessThanOrEqual(e, t) {
|
|
188
|
-
return this.le(e, t);
|
|
189
|
-
}
|
|
190
|
-
ge(e, t) {
|
|
191
|
-
return this.toConstraint(">=", e, t);
|
|
192
|
-
}
|
|
193
|
-
greaterThanOrEqual(e, t) {
|
|
194
|
-
return this.ge(e, t);
|
|
195
|
-
}
|
|
196
|
-
eq(e, t) {
|
|
197
|
-
return this.toConstraint("==", e, t);
|
|
198
|
-
}
|
|
199
|
-
equalTo(e, t) {
|
|
200
|
-
return this.eq(e, t);
|
|
201
|
-
}
|
|
202
|
-
toConstraint(t, n, r) {
|
|
203
|
-
let i = this.clone(), a = 0;
|
|
204
|
-
typeof n == "number" ? a = n : "terms" in n ? (i = i.sub(new e(n.terms, 0)), a = n.constant) : i = i.sub(n);
|
|
205
|
-
let o = a - i.constant;
|
|
206
|
-
return i.constant = 0, new c(i, t, o, r);
|
|
207
|
-
}
|
|
208
|
-
toString() {
|
|
209
|
-
let e = [], t = !0;
|
|
210
|
-
for (let [n, r] of this.terms) {
|
|
211
|
-
let i = r >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(r), o = a === 1 ? "" : `${a} `;
|
|
212
|
-
e.push(`${i}${o}${n.name}`), t = !1;
|
|
213
|
-
}
|
|
214
|
-
if (this.constant !== 0 || e.length === 0) {
|
|
215
|
-
let n = this.constant >= 0 ? t ? "" : "+ " : "- ";
|
|
216
|
-
e.push(`${n}${Math.abs(this.constant)}`);
|
|
217
|
-
}
|
|
218
|
-
return e.join(" ") || "0";
|
|
219
|
-
}
|
|
220
|
-
};
|
|
221
|
-
function k(e, t) {
|
|
222
|
-
let n = /* @__PURE__ */ new Map(), r = 0;
|
|
223
|
-
function i(e) {
|
|
224
|
-
if (e != null) {
|
|
225
|
-
if (typeof e == "number") r += e;
|
|
226
|
-
else if (typeof e == "object" && "terms" in e) {
|
|
227
|
-
let t = e;
|
|
228
|
-
for (let [e, r] of t.terms) {
|
|
229
|
-
let t = n.get(e) || 0;
|
|
230
|
-
n.set(e, t + r);
|
|
231
|
-
}
|
|
232
|
-
r += t.constant;
|
|
233
|
-
} else {
|
|
234
|
-
let t = e, r = n.get(t) || 0;
|
|
235
|
-
n.set(t, r + 1);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
if (typeof e == "number") {
|
|
240
|
-
let n = e, r = t;
|
|
241
|
-
for (let e = 0; e < n; e++) i(r(e, e));
|
|
242
|
-
} else {
|
|
243
|
-
let n = 0;
|
|
244
|
-
for (let r of e) i(t ? t(r, n++) : r);
|
|
245
|
-
}
|
|
246
|
-
for (let [e, t] of n) Math.abs(t) < 1e-12 && n.delete(e);
|
|
247
|
-
return new O(n, r);
|
|
248
|
-
}
|
|
249
|
-
function A(e, t) {
|
|
250
|
-
let n = /* @__PURE__ */ new Map(), r = 0;
|
|
251
|
-
function i(e) {
|
|
252
|
-
return typeof e == "object" && !!e && typeof e.id == "number" && typeof e.name == "string" && typeof e.mul == "function" && typeof e.le == "function";
|
|
253
|
-
}
|
|
254
|
-
function a(e) {
|
|
255
|
-
return i(e) || e instanceof O || e instanceof D;
|
|
256
|
-
}
|
|
257
|
-
function o(e, t) {
|
|
258
|
-
if (typeof t == "number") r += e * t;
|
|
259
|
-
else if (t instanceof O) {
|
|
260
|
-
for (let [r, i] of t.terms) {
|
|
261
|
-
let t = n.get(r) || 0;
|
|
262
|
-
n.set(r, t + e * i);
|
|
263
|
-
}
|
|
264
|
-
r += e * t.constant;
|
|
265
|
-
} else if (i(t)) {
|
|
266
|
-
let r = t, i = n.get(r) || 0;
|
|
267
|
-
n.set(r, i + e);
|
|
268
|
-
} else throw Error("Cannot multiply number by non-variable/expression operand in dot().");
|
|
269
|
-
}
|
|
270
|
-
function s(e) {
|
|
271
|
-
return typeof e == "object" && !!e && !Array.isArray(e) && !a(e);
|
|
272
|
-
}
|
|
273
|
-
function c(e, t, n = "") {
|
|
274
|
-
if (e === void 0 || t === void 0 || e === null || t === null) throw Error(`Nullish or undefined operand encountered in dot() at '${n || "root"}'.`);
|
|
275
|
-
if (typeof e == "number") {
|
|
276
|
-
o(e, t);
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
if (typeof t == "number") {
|
|
280
|
-
o(t, e);
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
if (Array.isArray(e) || Array.isArray(t)) {
|
|
284
|
-
if (Array.isArray(e) && Array.isArray(t)) {
|
|
285
|
-
if (e.length !== t.length) throw Error(`Array length mismatch in dot() at '${n || "root"}': received lengths ${e.length} and ${t.length}.`);
|
|
286
|
-
for (let r = 0; r < e.length; r++) c(e[r], t[r], n ? `${n}[${r}]` : `[${r}]`);
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
let r = Array.isArray(e) ? e : t, i = Array.isArray(e) ? t : e;
|
|
290
|
-
if (s(i)) {
|
|
291
|
-
let a = Object.keys(i);
|
|
292
|
-
if (a.length > 0 && a.every((e) => /^\d+$/.test(e))) {
|
|
293
|
-
if (a.length !== r.length) throw Error(`Array length mismatch in dot() at '${n || "root"}': array has length ${r.length}, but object has ${a.length} indices.`);
|
|
294
|
-
let o = [];
|
|
295
|
-
for (let e = 0; e < r.length; e++) !(e in i) && !(String(e) in i) && o.push(e);
|
|
296
|
-
if (o.length > 0) throw Error(`Key mismatch in dot() at '${n || "root"}': missing indices [${o.join(", ")}] in numeric record.`);
|
|
297
|
-
for (let i = 0; i < r.length; i++) c(e[i], t[i], n ? `${n}[${i}]` : `[${i}]`);
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
throw Error(`Type mismatch in dot() at '${n || "root"}': one operand is an Array while the other is an Object with keys [${a.slice(0, 5).join(", ")}].`);
|
|
301
|
-
}
|
|
302
|
-
throw Error(`Type mismatch in dot() at '${n || "root"}': one operand is an Array while the other is not.`);
|
|
303
|
-
}
|
|
304
|
-
if (s(e) && s(t)) {
|
|
305
|
-
let r = Object.keys(e), i = Object.keys(t), a = r.filter((e) => !(e in t)), o = i.filter((t) => !(t in e));
|
|
306
|
-
if (a.length > 0 || o.length > 0) {
|
|
307
|
-
let e = [];
|
|
308
|
-
throw a.length > 0 && e.push(`missing in second operand: [${a.join(", ")}]`), o.length > 0 && e.push(`missing in first operand: [${o.join(", ")}]`), Error(`Key mismatch in dot() at '${n || "root"}': ${e.join("; ")}.`);
|
|
309
|
-
}
|
|
310
|
-
for (let i of r) c(e[i], t[i], n ? `${n}.${i}` : i);
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
throw Error(`Unsupported operand types in dot() at '${n || "root"}'.`);
|
|
314
|
-
}
|
|
315
|
-
c(e, t);
|
|
316
|
-
for (let [e, t] of n) Math.abs(t) < 1e-12 && n.delete(e);
|
|
317
|
-
return new O(n, r);
|
|
318
|
-
}
|
|
319
|
-
//#endregion
|
|
320
|
-
//#region src/modeler/variable.ts
|
|
321
|
-
var ie = 0;
|
|
322
|
-
function ae(e) {
|
|
323
|
-
if (!e) return "Continuous";
|
|
324
|
-
let t = e.toLowerCase();
|
|
325
|
-
return t === "binary" || t === "bin" ? "Binary" : t === "integer" || t === "int" ? "Integer" : "Continuous";
|
|
326
|
-
}
|
|
327
|
-
var j = class e {
|
|
328
|
-
id;
|
|
329
|
-
name;
|
|
330
|
-
type;
|
|
331
|
-
lb;
|
|
332
|
-
ub;
|
|
333
|
-
value = null;
|
|
334
|
-
reducedCost = null;
|
|
335
|
-
constructor(e = {}) {
|
|
336
|
-
this.id = ++ie, this.name = e.name || `x_${this.id}`, this.type = ae(e.type), this.type === "Binary" ? (this.lb = 0, this.ub = 1) : (this.lb = e.lb === void 0 ? 0 : e.lb, this.ub = e.ub === void 0 ? Infinity : e.ub);
|
|
337
|
-
}
|
|
338
|
-
mul(t) {
|
|
339
|
-
if (typeof t == "number") return new O(/* @__PURE__ */ new Map([[this, t]]), 0);
|
|
340
|
-
if (t instanceof e) return D.fromProduct(this, t, 1);
|
|
341
|
-
let n = new D();
|
|
342
|
-
Math.abs(t.constant) >= 1e-12 && n.linearTerms.set(this, t.constant);
|
|
343
|
-
for (let [e, r] of t.terms) {
|
|
344
|
-
let t = D.fromProduct(this, e, r);
|
|
345
|
-
n = n.add(t);
|
|
346
|
-
}
|
|
347
|
-
return n;
|
|
348
|
-
}
|
|
349
|
-
add(e) {
|
|
350
|
-
return e instanceof D ? e.add(this) : new O(/* @__PURE__ */ new Map([[this, 1]]), 0).add(e);
|
|
351
|
-
}
|
|
352
|
-
sub(e) {
|
|
353
|
-
return e instanceof D ? e.neg().add(this) : new O(/* @__PURE__ */ new Map([[this, 1]]), 0).sub(e);
|
|
354
|
-
}
|
|
355
|
-
neg() {
|
|
356
|
-
return this.mul(-1);
|
|
357
|
-
}
|
|
358
|
-
le(e, t) {
|
|
359
|
-
return new O(/* @__PURE__ */ new Map([[this, 1]]), 0).le(e, t);
|
|
360
|
-
}
|
|
361
|
-
lessThanOrEqual(e, t) {
|
|
362
|
-
return this.le(e, t);
|
|
363
|
-
}
|
|
364
|
-
ge(e, t) {
|
|
365
|
-
return new O(/* @__PURE__ */ new Map([[this, 1]]), 0).ge(e, t);
|
|
366
|
-
}
|
|
367
|
-
greaterThanOrEqual(e, t) {
|
|
368
|
-
return this.ge(e, t);
|
|
369
|
-
}
|
|
370
|
-
eq(e, t) {
|
|
371
|
-
return new O(/* @__PURE__ */ new Map([[this, 1]]), 0).eq(e, t);
|
|
372
|
-
}
|
|
373
|
-
equalTo(e, t) {
|
|
374
|
-
return this.eq(e, t);
|
|
375
|
-
}
|
|
376
|
-
toString() {
|
|
377
|
-
return this.name;
|
|
378
|
-
}
|
|
379
|
-
};
|
|
380
|
-
//#endregion
|
|
381
31
|
//#region src/modeler/parser.ts
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
32
|
+
var ue = /^(?:[0-9]+(?:\.[0-9]+)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;
|
|
33
|
+
function de(e, t) {
|
|
34
|
+
let n = [], r = 0, i = e.length;
|
|
35
|
+
for (; r < i;) {
|
|
36
|
+
let a = e[r];
|
|
37
|
+
if (/\s/.test(a)) {
|
|
38
|
+
r++;
|
|
388
39
|
continue;
|
|
389
40
|
}
|
|
390
|
-
if (
|
|
41
|
+
if (a === "+") n.push({
|
|
391
42
|
type: "PLUS",
|
|
392
43
|
value: "+"
|
|
393
|
-
}),
|
|
394
|
-
else if (
|
|
44
|
+
}), r++;
|
|
45
|
+
else if (a === "-") n.push({
|
|
395
46
|
type: "MINUS",
|
|
396
47
|
value: "-"
|
|
397
|
-
}),
|
|
398
|
-
else if (
|
|
48
|
+
}), r++;
|
|
49
|
+
else if (a === "*") r + 1 < i && e[r + 1] === "*" ? (n.push({
|
|
50
|
+
type: "CARET",
|
|
51
|
+
value: "**"
|
|
52
|
+
}), r += 2) : (n.push({
|
|
399
53
|
type: "STAR",
|
|
400
54
|
value: "*"
|
|
401
|
-
}),
|
|
402
|
-
else if (
|
|
55
|
+
}), r++);
|
|
56
|
+
else if (a === "^") n.push({
|
|
57
|
+
type: "CARET",
|
|
58
|
+
value: "^"
|
|
59
|
+
}), r++;
|
|
60
|
+
else if (a === "/") n.push({
|
|
403
61
|
type: "SLASH",
|
|
404
62
|
value: "/"
|
|
405
|
-
}),
|
|
406
|
-
else if (
|
|
63
|
+
}), r++;
|
|
64
|
+
else if (a === "(") n.push({
|
|
407
65
|
type: "LPAREN",
|
|
408
66
|
value: "("
|
|
409
|
-
}),
|
|
410
|
-
else if (
|
|
67
|
+
}), r++;
|
|
68
|
+
else if (a === ")") n.push({
|
|
411
69
|
type: "RPAREN",
|
|
412
70
|
value: ")"
|
|
413
|
-
}),
|
|
414
|
-
else if (
|
|
415
|
-
let
|
|
416
|
-
|
|
71
|
+
}), r++;
|
|
72
|
+
else if (a === "<" || a === ">" || a === "=") {
|
|
73
|
+
let t = a;
|
|
74
|
+
r + 1 < i && (e[r + 1] === "=" || e[r + 1] === "<" || e[r + 1] === ">") ? (t += e[r + 1], r += 2) : r++, n.push({
|
|
417
75
|
type: "COMP",
|
|
418
|
-
value:
|
|
76
|
+
value: t
|
|
419
77
|
});
|
|
420
|
-
} else if (/[0-9.]/.test(
|
|
421
|
-
let
|
|
422
|
-
for (;
|
|
423
|
-
|
|
78
|
+
} else if (/[0-9.]/.test(a)) {
|
|
79
|
+
let t = r, a = "";
|
|
80
|
+
for (; r < i && /[0-9]/.test(e[r]);) a += e[r++];
|
|
81
|
+
if (r < i && e[r] === ".") for (a += e[r++]; r < i && /[0-9]/.test(e[r]);) a += e[r++];
|
|
82
|
+
if (r < i && (e[r] === "e" || e[r] === "E")) {
|
|
83
|
+
let t = r + 1 < i ? e[r + 1] : "";
|
|
84
|
+
if (!/[a-zA-Z_]/.test(t)) {
|
|
85
|
+
for (a += e[r++], r < i && (e[r] === "+" || e[r] === "-") && (a += e[r++]); r < i && /[0-9]/.test(e[r]);) a += e[r++];
|
|
86
|
+
for (; r < i && (e[r] === "." || e[r] === "e" || e[r] === "E" || /[0-9]/.test(e[r]));) a += e[r++];
|
|
87
|
+
}
|
|
88
|
+
} else for (; r < i && (e[r] === "." || /[0-9]/.test(e[r]));) a += e[r++];
|
|
89
|
+
if (!ue.test(a)) throw Error(`Invalid numeric literal '${a}' at position ${t} in: "${e}"`);
|
|
90
|
+
let o = Number(a);
|
|
91
|
+
if (!Number.isFinite(o)) throw Error(`Numeric literal '${a}' overflows finite floating-point range in: "${e}"`);
|
|
92
|
+
if (o === 0 && !/^[0.]+(?:[eE][+-]?\d+)?$/.test(a)) throw Error(`Numeric literal '${a}' underflows to zero at position ${t} in: "${e}"`);
|
|
93
|
+
n.push({
|
|
424
94
|
type: "NUMBER",
|
|
425
|
-
value:
|
|
95
|
+
value: a,
|
|
96
|
+
numericValue: o
|
|
426
97
|
});
|
|
427
|
-
} else if (/[a-zA-Z_]/.test(
|
|
428
|
-
let
|
|
429
|
-
for (;
|
|
430
|
-
t.
|
|
98
|
+
} else if (/[a-zA-Z_]/.test(a)) {
|
|
99
|
+
let a = "";
|
|
100
|
+
for (; r < i && /[a-zA-Z0-9_]/.test(e[r]);) a += e[r], r++;
|
|
101
|
+
if (t && t.has(a)) {
|
|
102
|
+
let e = t.get(a);
|
|
103
|
+
n.push({
|
|
104
|
+
type: "NUMBER",
|
|
105
|
+
value: String(e),
|
|
106
|
+
numericValue: e
|
|
107
|
+
});
|
|
108
|
+
} else n.push({
|
|
431
109
|
type: "IDENT",
|
|
432
|
-
value:
|
|
110
|
+
value: a
|
|
433
111
|
});
|
|
434
|
-
} else throw Error(`Unexpected character '${
|
|
112
|
+
} else throw Error(`Unexpected character '${a}' at position ${r} in: "${e}"`);
|
|
435
113
|
}
|
|
436
|
-
return
|
|
114
|
+
return n;
|
|
437
115
|
}
|
|
438
|
-
var
|
|
116
|
+
var fe = class {
|
|
439
117
|
tokens;
|
|
440
118
|
pos = 0;
|
|
441
119
|
resolver;
|
|
@@ -460,199 +138,246 @@ var N = class {
|
|
|
460
138
|
else if (t.type === "MINUS") this.consume(), e = e.sub(this.parseTerm());
|
|
461
139
|
else break;
|
|
462
140
|
}
|
|
463
|
-
return e;
|
|
141
|
+
return e instanceof A && e.quadTerms.size === 0 ? new j(e.linearTerms, e.constant) : e;
|
|
464
142
|
}
|
|
465
143
|
parseTerm() {
|
|
466
144
|
let e = this.parseFactor();
|
|
467
145
|
for (; this.pos < this.tokens.length;) {
|
|
468
146
|
let t = this.peek();
|
|
469
147
|
if (!t) break;
|
|
470
|
-
if (t.type === "STAR")
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
e = this.multiplyExpressions(e, t);
|
|
474
|
-
} else if (t.type === "SLASH") {
|
|
475
|
-
this.consume();
|
|
476
|
-
let t = this.parseFactor();
|
|
477
|
-
if (t.terms.size > 0) throw Error("Cannot divide by variable in linear expression");
|
|
478
|
-
if (Math.abs(t.constant) < 1e-12) throw Error("Division by zero in expression");
|
|
479
|
-
e = e.div(t.constant);
|
|
480
|
-
} else break;
|
|
148
|
+
if (t.type === "STAR") this.consume(), e = e.mul(this.parseFactor());
|
|
149
|
+
else if (t.type === "SLASH") this.consume(), e = e.div(this.parseFactor());
|
|
150
|
+
else break;
|
|
481
151
|
}
|
|
482
152
|
return e;
|
|
483
153
|
}
|
|
484
|
-
multiplyExpressions(e, t) {
|
|
485
|
-
if (e.terms.size > 0 && t.terms.size > 0) throw Error("Multiplication of two variables creates a non-linear term (not allowed in MILP/LP)");
|
|
486
|
-
return e.terms.size === 0 ? t.mul(e.constant) : e.mul(t.constant);
|
|
487
|
-
}
|
|
488
154
|
parseFactor() {
|
|
489
155
|
let e = this.peek();
|
|
490
156
|
if (!e) throw Error("Unexpected end of expression");
|
|
491
157
|
if (e.type === "PLUS") return this.consume(), this.parseFactor();
|
|
492
158
|
if (e.type === "MINUS") return this.consume(), this.parseFactor().neg();
|
|
159
|
+
let t;
|
|
493
160
|
if (e.type === "NUMBER") {
|
|
494
161
|
this.consume();
|
|
495
|
-
let
|
|
496
|
-
if (this.peek()?.type === "IDENT") {
|
|
497
|
-
let e
|
|
498
|
-
|
|
162
|
+
let n = e.numericValue ?? Number(e.value);
|
|
163
|
+
if (this.peek()?.type === "IDENT" || this.peek()?.type === "LPAREN") {
|
|
164
|
+
let e;
|
|
165
|
+
if (this.peek()?.type === "IDENT") {
|
|
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);
|
|
499
170
|
}
|
|
500
|
-
|
|
501
|
-
}
|
|
502
|
-
if (e.type === "IDENT") {
|
|
171
|
+
t = new j(/* @__PURE__ */ new Map(), n);
|
|
172
|
+
} else if (e.type === "IDENT") {
|
|
503
173
|
this.consume();
|
|
504
|
-
let
|
|
505
|
-
|
|
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");
|
|
177
|
+
else throw Error(`Unexpected token '${e.value}' in expression`);
|
|
178
|
+
return this.applyPower(t);
|
|
179
|
+
}
|
|
180
|
+
applyPower(e) {
|
|
181
|
+
if (this.peek()?.type !== "CARET") return e;
|
|
182
|
+
let t = [];
|
|
183
|
+
for (; this.peek()?.type === "CARET";) {
|
|
184
|
+
this.consume();
|
|
185
|
+
let e = this.tokens[this.pos]?.type === "LPAREN" && this.tokens[this.pos + 1]?.type === "NUMBER" && this.tokens[this.pos + 2]?.type === "RPAREN";
|
|
186
|
+
e && this.consume("LPAREN");
|
|
187
|
+
let n = this.peek();
|
|
188
|
+
if (!n || n.type !== "NUMBER") throw Error("Exponent must be a non-negative integer number");
|
|
189
|
+
this.consume(), e && this.consume("RPAREN");
|
|
190
|
+
let r = n.numericValue ?? Number(n.value);
|
|
191
|
+
if (!Number.isInteger(r) || r < 0) throw Error("Exponent must be a non-negative integer");
|
|
192
|
+
t.push(r);
|
|
506
193
|
}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
194
|
+
let n = t[t.length - 1];
|
|
195
|
+
for (let e = t.length - 2; e >= 0; e--) n = t[e] ** +n;
|
|
196
|
+
if (!Number.isFinite(n) || n < 0) throw Error("Exponent creates an invalid or out-of-range power");
|
|
197
|
+
let r = e instanceof A, i = r ? e.quadTerms.size : 0, a = r ? e.linearTerms.size : e.terms.size;
|
|
198
|
+
if (i === 0 && a === 0) {
|
|
199
|
+
let t = e.constant ** +n;
|
|
200
|
+
if (e.constant !== 0 && n > 0 && t === 0) throw Error("Constant exponentiation underflows to zero.");
|
|
201
|
+
return new j(/* @__PURE__ */ new Map(), t);
|
|
511
202
|
}
|
|
512
|
-
|
|
203
|
+
if (n === 0) return new j(/* @__PURE__ */ new Map(), 1);
|
|
204
|
+
if (n === 1) return e;
|
|
205
|
+
if (n === 2) return e.mul(e);
|
|
206
|
+
throw Error(`Exponent ${n} creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)`);
|
|
207
|
+
}
|
|
208
|
+
getRemainingToken() {
|
|
209
|
+
return this.peek();
|
|
513
210
|
}
|
|
514
|
-
|
|
211
|
+
resolve(e) {
|
|
515
212
|
let t = this.resolver(e);
|
|
516
213
|
if (!t) throw Error(`Unknown variable '${e}' in expression`);
|
|
517
214
|
return t;
|
|
518
215
|
}
|
|
519
216
|
};
|
|
520
|
-
function
|
|
521
|
-
|
|
217
|
+
function B(e, t, n) {
|
|
218
|
+
let r = new fe(de(e, n), t), i = r.parseExpression(), a = r.getRemainingToken();
|
|
219
|
+
if (a) throw Error(`Unexpected token '${a.value}' after expression in "${e}"`);
|
|
220
|
+
return _e(i), i;
|
|
221
|
+
}
|
|
222
|
+
function pe(e, t) {
|
|
223
|
+
return B(e, t);
|
|
224
|
+
}
|
|
225
|
+
function me(e, t, n, r) {
|
|
226
|
+
let i = e.match(/(<=|>=|==|=<|=>|=)/);
|
|
227
|
+
if (!i) throw Error(`Constraint must contain a comparison operator (<=, >=, ==, =): "${e}"`);
|
|
228
|
+
let a = i[0], o = i.index, s = e.substring(0, o).trim(), c = e.substring(o + a.length).trim(), l;
|
|
229
|
+
if (a === "<=" || a === "=<") l = "<=";
|
|
230
|
+
else if (a === ">=" || a === "=>") l = ">=";
|
|
231
|
+
else if (a === "==" || a === "=") l = "==";
|
|
232
|
+
else throw Error(`Unsupported operator "${a}"`);
|
|
233
|
+
let u = B(s, t, r), d = B(c, t, r);
|
|
234
|
+
if (u instanceof A && u.quadTerms.size > 0 || d instanceof A && d.quadTerms.size > 0) throw Error("Quadratic constraints are not supported (only linear constraints are allowed in MILP/LP/QP)");
|
|
235
|
+
let f = u instanceof A ? new j(u.linearTerms, u.constant) : u, p = d instanceof A ? new j(d.linearTerms, d.constant) : d, m;
|
|
236
|
+
if (m = l === "<=" ? f.le(p, n) : l === ">=" ? f.ge(p, n) : f.eq(p, n), _e(m.lhs), !Number.isFinite(m.rhs)) throw Error(`Invalid non-finite right-hand side "${m.rhs}" in constraint.`);
|
|
237
|
+
return m;
|
|
522
238
|
}
|
|
523
|
-
function
|
|
524
|
-
|
|
525
|
-
if (!r) throw Error(`Constraint must contain a comparison operator (<=, >=, ==, =): "${e}"`);
|
|
526
|
-
let i = r[0], a = r.index, o = e.substring(0, a).trim(), s = e.substring(a + i.length).trim(), c;
|
|
527
|
-
if (i === "<=" || i === "=<") c = "<=";
|
|
528
|
-
else if (i === ">=" || i === "=>") c = ">=";
|
|
529
|
-
else if (i === "==" || i === "=") c = "==";
|
|
530
|
-
else throw Error(`Unsupported operator "${i}"`);
|
|
531
|
-
let l = P(o, t), u = P(s, t);
|
|
532
|
-
return c === "<=" ? l.le(u, n) : c === ">=" ? l.ge(u, n) : l.eq(u, n);
|
|
239
|
+
function he(e, t, n) {
|
|
240
|
+
return me(e, t, n);
|
|
533
241
|
}
|
|
534
|
-
function
|
|
535
|
-
|
|
536
|
-
|
|
242
|
+
function ge(e) {
|
|
243
|
+
return e instanceof b || e instanceof j || e instanceof A ? !0 : typeof e != "object" || !e ? !1 : "terms" in e && e.terms instanceof Map || "quadTerms" in e && e.quadTerms instanceof Map || "id" in e && "name" in e && "lb" in e && "ub" in e && "type" in e && typeof e.mul == "function";
|
|
244
|
+
}
|
|
245
|
+
function _e(e) {
|
|
246
|
+
if ("constant" in e && !Number.isFinite(e.constant)) throw Error(`Invalid non-finite constant "${e.constant}" in expression.`);
|
|
247
|
+
if ("terms" in e && e.terms instanceof Map) {
|
|
248
|
+
for (let [, t] of e.terms) if (!Number.isFinite(t)) throw Error(`Invalid non-finite coefficient "${t}" in expression.`);
|
|
249
|
+
}
|
|
250
|
+
if ("linearTerms" in e && e.linearTerms instanceof Map) {
|
|
251
|
+
for (let [, t] of e.linearTerms) if (!Number.isFinite(t)) throw Error(`Invalid non-finite coefficient "${t}" in expression.`);
|
|
252
|
+
}
|
|
253
|
+
if ("quadTerms" in e && e.quadTerms instanceof Map) {
|
|
254
|
+
for (let [, t] of e.quadTerms) if (!Number.isFinite(t.coeff)) throw Error(`Invalid non-finite quadratic coefficient "${t.coeff}" in expression.`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
function ve(e) {
|
|
258
|
+
return e instanceof c || typeof e == "object" && !!e && "sense" in e && "lhs" in e && "rhs" in e;
|
|
259
|
+
}
|
|
260
|
+
function ye(e, t) {
|
|
261
|
+
let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), i = e.join(""), a = "__washi_";
|
|
262
|
+
for (; i.includes(a);) a += "_";
|
|
263
|
+
let o = "";
|
|
264
|
+
for (let i = 0; i < e.length; i++) if (o += e[i], i < t.length) {
|
|
537
265
|
let e = t[i];
|
|
538
|
-
if (typeof e == "number")
|
|
539
|
-
|
|
540
|
-
let t =
|
|
541
|
-
|
|
542
|
-
} else if (e
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
266
|
+
if (typeof e == "number") {
|
|
267
|
+
if (!Number.isFinite(e)) throw Error(`Invalid numeric value "${e}" in template expression: interpolated numbers must be finite.`);
|
|
268
|
+
let t = `${a}num_${i}__`;
|
|
269
|
+
r.set(t, e), o += `(${t})`;
|
|
270
|
+
} else if (ve(e)) throw Error("Cannot interpolate a constraint comparison (<=, >=, ==) inside a template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
271
|
+
else if (ge(e)) {
|
|
272
|
+
_e(e);
|
|
273
|
+
let t = `${a}ph_${i}__`;
|
|
274
|
+
n.set(t, e), o += ` ${t} `;
|
|
275
|
+
} else throw Error("Unsupported interpolation value in template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
546
276
|
}
|
|
547
277
|
return {
|
|
548
|
-
fullText:
|
|
549
|
-
resolver: (e) => n.get(e)
|
|
278
|
+
fullText: o,
|
|
279
|
+
resolver: (e) => n.get(e),
|
|
280
|
+
numberMap: r
|
|
550
281
|
};
|
|
551
282
|
}
|
|
552
|
-
function
|
|
553
|
-
let { fullText: n, resolver: r } =
|
|
554
|
-
return
|
|
555
|
-
}
|
|
556
|
-
function R(e, ...t) {
|
|
557
|
-
let { fullText: n, resolver: r } = I(e, t);
|
|
558
|
-
return /(<=|>=|==|=<|=>|=)/.test(n) ? F(n, r) : P(n, r);
|
|
283
|
+
function be(e, ...t) {
|
|
284
|
+
let { fullText: n, resolver: r, numberMap: i } = ye(e, t);
|
|
285
|
+
return /(<=|>=|==|=<|=>|=)/.test(n) ? me(n, r, void 0, i) : B(n, r, i);
|
|
559
286
|
}
|
|
560
287
|
//#endregion
|
|
561
|
-
//#region src/modeler/
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
return
|
|
288
|
+
//#region src/modeler/solvers/highs/worker-client.ts
|
|
289
|
+
var V = null, xe = 0, H = /* @__PURE__ */ new Map();
|
|
290
|
+
function Se(e, t) {
|
|
291
|
+
return e ? {
|
|
292
|
+
Status: "Interrupted",
|
|
293
|
+
StatusCode: 17,
|
|
294
|
+
HasPrimalSolution: !0,
|
|
295
|
+
IsMip: !0,
|
|
296
|
+
ObjectiveValue: e.objectiveValue,
|
|
297
|
+
ObjectiveOffsetApplied: !0,
|
|
298
|
+
...t?.objectiveBound === void 0 ? e.mipDualBound === void 0 ? {} : { MipDualBound: e.mipDualBound } : { MipDualBound: t.objectiveBound },
|
|
299
|
+
...t?.relGap === void 0 ? e.mipGap === void 0 ? {} : { MipGap: e.mipGap } : { MipGap: t.relGap },
|
|
300
|
+
Columns: e.columns,
|
|
301
|
+
Rows: []
|
|
302
|
+
} : {
|
|
303
|
+
Status: "Interrupted",
|
|
304
|
+
StatusCode: 17,
|
|
305
|
+
HasPrimalSolution: !1,
|
|
306
|
+
ObjectiveValue: NaN,
|
|
307
|
+
ObjectiveOffsetApplied: !0,
|
|
308
|
+
...t?.objectiveBound === void 0 ? {} : { MipDualBound: t.objectiveBound },
|
|
309
|
+
...t?.relGap === void 0 ? {} : { MipGap: t.relGap },
|
|
310
|
+
Columns: {},
|
|
311
|
+
Rows: []
|
|
312
|
+
};
|
|
565
313
|
}
|
|
566
|
-
function
|
|
567
|
-
let
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
d.push(t && t.toLowerCase() === "maximize" ? "Maximize" : "Minimize");
|
|
581
|
-
let f = [], p = !0, m = n instanceof D ? n.linearTerms : n.terms;
|
|
582
|
-
if (m) for (let [e, t] of m) {
|
|
583
|
-
if (Math.abs(t) < 1e-12) continue;
|
|
584
|
-
let n = o.get(e), r = t >= 0 ? p ? "" : "+ " : "- ", i = Math.abs(t), a = i === 1 ? "" : `${i} `;
|
|
585
|
-
f.push(`${r}${a}${n}`), p = !1;
|
|
586
|
-
}
|
|
587
|
-
if (n instanceof D && n.quadTerms.size > 0) {
|
|
588
|
-
let e = [], t = !0;
|
|
589
|
-
for (let r of n.quadTerms.values()) {
|
|
590
|
-
if (Math.abs(r.coeff) < 1e-12) continue;
|
|
591
|
-
let n = 2 * r.coeff, i = n >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(n), s = a === 1 ? "" : `${a} `, c = o.get(r.var1), l = o.get(r.var2);
|
|
592
|
-
r.var1 === r.var2 ? e.push(`${i}${s}${c} ^ 2`) : e.push(`${i}${s}${c} * ${l}`), t = !1;
|
|
593
|
-
}
|
|
594
|
-
if (e.length > 0) {
|
|
595
|
-
let t = `[ ${e.join(" ")} ] / 2`;
|
|
596
|
-
f.length > 0 ? f.push("+", t) : f.push(t);
|
|
314
|
+
function U(e) {
|
|
315
|
+
let t = H.values().next().value;
|
|
316
|
+
if (t && !t.dispatched) {
|
|
317
|
+
t.dispatched = !0;
|
|
318
|
+
try {
|
|
319
|
+
e.postMessage({
|
|
320
|
+
type: "SOLVE",
|
|
321
|
+
id: t.id,
|
|
322
|
+
lpString: t.lpString,
|
|
323
|
+
options: t.workerOptions,
|
|
324
|
+
...t.reportProgress ? { reportProgress: !0 } : {}
|
|
325
|
+
});
|
|
326
|
+
} catch (n) {
|
|
327
|
+
H.delete(t.id), t.cleanupAbort?.(), t.reject(n), U(e);
|
|
597
328
|
}
|
|
598
329
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
}
|
|
611
|
-
d.push("Bounds");
|
|
612
|
-
let g = [], _ = [];
|
|
613
|
-
for (let e of i) {
|
|
614
|
-
let t = o.get(e);
|
|
615
|
-
if (e.type === "Binary") {
|
|
616
|
-
_.push(t);
|
|
617
|
-
continue;
|
|
330
|
+
}
|
|
331
|
+
function Ce() {
|
|
332
|
+
let e = V;
|
|
333
|
+
e && (V = null, e.terminate());
|
|
334
|
+
for (let e of H.values()) e.dispatched = !1;
|
|
335
|
+
if (H.size > 0) {
|
|
336
|
+
let e = we();
|
|
337
|
+
if (e) U(e);
|
|
338
|
+
else {
|
|
339
|
+
let e = /* @__PURE__ */ Error("[WaSHI] Failed to recreate HiGHS Worker after interruption.");
|
|
340
|
+
for (let t of Array.from(H.values())) H.delete(t.id), t.cleanupAbort?.(), t.reject(e);
|
|
618
341
|
}
|
|
619
|
-
|
|
620
|
-
let n = e.lb === -Infinity, r = e.ub === Infinity;
|
|
621
|
-
n && r ? d.push(` ${t} free`) : n && !r ? d.push(` -infinity <= ${t} <= ${e.ub}`) : !n && r ? e.lb !== 0 && d.push(` ${t} >= ${e.lb}`) : d.push(` ${e.lb} <= ${t} <= ${e.ub}`);
|
|
622
|
-
}
|
|
623
|
-
if (g.length > 0) {
|
|
624
|
-
d.push("Generals");
|
|
625
|
-
for (let e = 0; e < g.length; e += 10) d.push(" " + g.slice(e, e + 10).join(" "));
|
|
626
|
-
}
|
|
627
|
-
if (_.length > 0) {
|
|
628
|
-
d.push("Binary");
|
|
629
|
-
for (let e = 0; e < _.length; e += 10) d.push(" " + _.slice(e, e + 10).join(" "));
|
|
630
|
-
}
|
|
631
|
-
return d.push("End"), {
|
|
632
|
-
lpString: d.join("\n") + "\n",
|
|
633
|
-
nameToVar: a,
|
|
634
|
-
nameToConstraint: s
|
|
635
|
-
};
|
|
342
|
+
}
|
|
636
343
|
}
|
|
637
|
-
|
|
638
|
-
//#region src/modeler/solvers/highs/worker-client.ts
|
|
639
|
-
var V = null, oe = 0, H = /* @__PURE__ */ new Map();
|
|
640
|
-
function se() {
|
|
344
|
+
function we() {
|
|
641
345
|
if (typeof window > "u" || typeof Worker > "u") return null;
|
|
642
346
|
if (!V) try {
|
|
643
|
-
V =
|
|
347
|
+
V = ne();
|
|
644
348
|
let e = V;
|
|
645
|
-
V.onmessage = (
|
|
646
|
-
let { type:
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
349
|
+
V.onmessage = (t) => {
|
|
350
|
+
let { type: n, id: r, result: i, runTime: a, error: o, progress: s, incumbent: c } = t.data, l = H.get(r);
|
|
351
|
+
if (l) {
|
|
352
|
+
if (n === "SOLVE_PROGRESS") {
|
|
353
|
+
if (s) {
|
|
354
|
+
l.lastProgress = s;
|
|
355
|
+
try {
|
|
356
|
+
l.onProgress?.(s);
|
|
357
|
+
} catch (e) {
|
|
358
|
+
let t = H.get(r);
|
|
359
|
+
if (t) {
|
|
360
|
+
let n = H.keys().next().value;
|
|
361
|
+
H.delete(r), t.cleanupAbort?.(), n === r && Ce(), t.reject(e);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
if (n === "SOLVE_INCUMBENT") {
|
|
368
|
+
c && (l.lastIncumbent = c);
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
H.delete(r), l.cleanupAbort?.(), n === "SOLVE_SUCCESS" ? l.resolve({
|
|
372
|
+
result: i,
|
|
373
|
+
runTime: a
|
|
374
|
+
}) : l.reject(Error(o || "Worker solve failed")), V === e && U(e);
|
|
375
|
+
}
|
|
651
376
|
};
|
|
652
377
|
let t = (t) => {
|
|
653
378
|
if (V === e) {
|
|
654
379
|
V = null, e.terminate();
|
|
655
|
-
for (let e of H.values()) e.reject(t);
|
|
380
|
+
for (let e of H.values()) e.cleanupAbort?.(), e.reject(t);
|
|
656
381
|
H.clear();
|
|
657
382
|
}
|
|
658
383
|
};
|
|
@@ -662,47 +387,97 @@ function se() {
|
|
|
662
387
|
}
|
|
663
388
|
return V;
|
|
664
389
|
}
|
|
665
|
-
async function
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
390
|
+
async function W(e, t = {}) {
|
|
391
|
+
if (t.signal?.aborted) return {
|
|
392
|
+
result: Se(),
|
|
393
|
+
runTime: 0
|
|
394
|
+
};
|
|
395
|
+
let n = await I(t.wasmUrl);
|
|
396
|
+
if (t.signal?.aborted) return {
|
|
397
|
+
result: Se(),
|
|
398
|
+
runTime: 0
|
|
399
|
+
};
|
|
400
|
+
let r = t.useWorker ?? typeof window < "u" ? we() : null;
|
|
401
|
+
if (!r) return N(e, t);
|
|
402
|
+
let { signal: i, onProgress: a, ...o } = t, s = {};
|
|
403
|
+
for (let [e, t] of Object.entries(o)) typeof t != "function" && (s[e] = t);
|
|
404
|
+
s.wasmUrl = n;
|
|
405
|
+
let c = !!(a || i), l = `req_${++xe}`, u = performance.now();
|
|
672
406
|
return new Promise((t, n) => {
|
|
673
|
-
|
|
407
|
+
let o = {
|
|
408
|
+
id: l,
|
|
409
|
+
lpString: e,
|
|
410
|
+
workerOptions: s,
|
|
411
|
+
reportProgress: c,
|
|
412
|
+
startTime: u,
|
|
413
|
+
onProgress: a,
|
|
674
414
|
resolve: t,
|
|
675
415
|
reject: n
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
416
|
+
};
|
|
417
|
+
if (i) {
|
|
418
|
+
let e = () => {
|
|
419
|
+
let e = H.get(l);
|
|
420
|
+
if (!e) return;
|
|
421
|
+
let t = H.keys().next().value;
|
|
422
|
+
H.delete(l), e.cleanupAbort?.(), t === l && Ce();
|
|
423
|
+
let n = (performance.now() - e.startTime) / 1e3;
|
|
424
|
+
e.resolve({
|
|
425
|
+
result: Se(e.lastIncumbent, e.lastProgress),
|
|
426
|
+
runTime: n
|
|
427
|
+
});
|
|
428
|
+
};
|
|
429
|
+
i.addEventListener("abort", e, { once: !0 }), o.cleanupAbort = () => i.removeEventListener("abort", e);
|
|
686
430
|
}
|
|
431
|
+
H.set(l, o), U(r);
|
|
687
432
|
});
|
|
688
433
|
}
|
|
689
434
|
//#endregion
|
|
690
435
|
//#region src/modeler/solvers/highs/solver.ts
|
|
691
|
-
function
|
|
436
|
+
function G(e, t) {
|
|
437
|
+
if (typeof t == "number") switch (t) {
|
|
438
|
+
case 0: return "NotSolved";
|
|
439
|
+
case 1:
|
|
440
|
+
case 2:
|
|
441
|
+
case 3:
|
|
442
|
+
case 4:
|
|
443
|
+
case 5: return "Error";
|
|
444
|
+
case 6: return "Unknown";
|
|
445
|
+
case 7: return "Optimal";
|
|
446
|
+
case 8: return "Infeasible";
|
|
447
|
+
case 9: return "InfeasibleOrUnbounded";
|
|
448
|
+
case 10: return "Unbounded";
|
|
449
|
+
case 11: return "ObjectiveBound";
|
|
450
|
+
case 12: return "ObjectiveTarget";
|
|
451
|
+
case 13: return "TimeLimit";
|
|
452
|
+
case 14: return "IterationLimit";
|
|
453
|
+
case 15: return "Unknown";
|
|
454
|
+
case 16: return "SolutionLimit";
|
|
455
|
+
case 17: return "Interrupted";
|
|
456
|
+
case 18: return "MemoryLimit";
|
|
457
|
+
}
|
|
692
458
|
if (typeof e != "string") return "Unknown";
|
|
693
|
-
let
|
|
694
|
-
if (!
|
|
695
|
-
switch (
|
|
459
|
+
let n = e.trim();
|
|
460
|
+
if (!n) return "Unknown";
|
|
461
|
+
switch (n) {
|
|
696
462
|
case "Optimal": return "Optimal";
|
|
697
463
|
case "Infeasible": return "Infeasible";
|
|
698
464
|
case "Unbounded": return "Unbounded";
|
|
699
|
-
case "Primal infeasible or unbounded":
|
|
465
|
+
case "Primal infeasible or unbounded":
|
|
466
|
+
case "InfeasibleOrUnbounded": return "InfeasibleOrUnbounded";
|
|
700
467
|
case "Time limit reached":
|
|
701
468
|
case "TimeLimit": return "TimeLimit";
|
|
702
469
|
case "Iteration limit reached":
|
|
703
470
|
case "IterationLimit": return "IterationLimit";
|
|
471
|
+
case "Solution limit reached":
|
|
472
|
+
case "SolutionLimit": return "SolutionLimit";
|
|
473
|
+
case "Memory limit reached":
|
|
474
|
+
case "MemoryLimit": return "MemoryLimit";
|
|
704
475
|
case "Bound on objective reached":
|
|
476
|
+
case "ObjectiveBound": return "ObjectiveBound";
|
|
705
477
|
case "Target for objective reached":
|
|
478
|
+
case "ObjectiveTarget": return "ObjectiveTarget";
|
|
479
|
+
case "Interrupted":
|
|
480
|
+
case "User interrupt": return "Interrupted";
|
|
706
481
|
case "Feasible": return "Feasible";
|
|
707
482
|
case "Not Set": return "NotSolved";
|
|
708
483
|
case "Load error":
|
|
@@ -714,13 +489,32 @@ function W(e) {
|
|
|
714
489
|
case "Empty":
|
|
715
490
|
case "Unknown": return "Unknown";
|
|
716
491
|
}
|
|
717
|
-
let
|
|
718
|
-
return
|
|
492
|
+
let r = n.toLowerCase();
|
|
493
|
+
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
|
+
}
|
|
495
|
+
function K(e, t, n) {
|
|
496
|
+
switch (G(e, t)) {
|
|
497
|
+
case "Optimal": return "Optimal";
|
|
498
|
+
case "Infeasible": return "Infeasible";
|
|
499
|
+
case "Unbounded": return "Unbounded";
|
|
500
|
+
case "TimeLimit": return "TimeLimit";
|
|
501
|
+
case "IterationLimit": return "IterationLimit";
|
|
502
|
+
case "Feasible": return "Feasible";
|
|
503
|
+
case "ObjectiveBound":
|
|
504
|
+
case "ObjectiveTarget":
|
|
505
|
+
case "SolutionLimit": return n === !1 ? "Unknown" : "Feasible";
|
|
506
|
+
case "MemoryLimit":
|
|
507
|
+
case "Interrupted": return n ? "Feasible" : "Unknown";
|
|
508
|
+
case "NotSolved": return "NotSolved";
|
|
509
|
+
case "Error": return "Error";
|
|
510
|
+
default: return "Unknown";
|
|
511
|
+
}
|
|
719
512
|
}
|
|
720
|
-
var
|
|
513
|
+
var q = class e {
|
|
721
514
|
static capabilities = {
|
|
722
515
|
supportsMIP: !0,
|
|
723
|
-
supportsQP: !0
|
|
516
|
+
supportsQP: !0,
|
|
517
|
+
supportsWarmStart: !0
|
|
724
518
|
};
|
|
725
519
|
name = "HiGHS";
|
|
726
520
|
version = "1.15.3";
|
|
@@ -729,182 +523,816 @@ var G = class e {
|
|
|
729
523
|
constructor(e = {}) {
|
|
730
524
|
this.options = e;
|
|
731
525
|
}
|
|
732
|
-
async solve(e, t, n = {}) {
|
|
733
|
-
let r = {
|
|
526
|
+
async solve(e, t = {}, n = {}) {
|
|
527
|
+
let r = E(t), i = r ? n : t, a = {
|
|
734
528
|
...this.options,
|
|
735
|
-
...
|
|
736
|
-
},
|
|
737
|
-
|
|
738
|
-
|
|
529
|
+
...i
|
|
530
|
+
}, o = e.objective.constant || 0;
|
|
531
|
+
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();
|
|
533
|
+
for (let [e, t] of c.entries()) {
|
|
534
|
+
m.add(t);
|
|
535
|
+
let n = w(t);
|
|
536
|
+
n !== void 0 && (u[e] = n, p = !0);
|
|
537
|
+
}
|
|
538
|
+
for (let t = 0; t < e.variables.length; t++) {
|
|
539
|
+
let n = e.variables[t];
|
|
540
|
+
if (!m.has(n)) {
|
|
541
|
+
let e = w(n);
|
|
542
|
+
if (e !== void 0) {
|
|
543
|
+
let r = f(n.name, "x", t);
|
|
544
|
+
Object.prototype.hasOwnProperty.call(u, r) || (u[r] = e, p = !0);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
let h = a;
|
|
549
|
+
(o !== 0 || p || h.initialValues !== void 0) && (h = {
|
|
550
|
+
...h,
|
|
551
|
+
...o === 0 ? {} : { objectiveOffset: o },
|
|
552
|
+
initialValues: p ? u : void 0
|
|
553
|
+
});
|
|
554
|
+
let { result: g, runTime: _ } = await W(s, h), v = g?.ObjectiveOffsetApplied ? 0 : o, y = G(g?.Status, g?.StatusCode), b = typeof g?.IsMip == "boolean" ? g.IsMip : e.variables.some((e) => e.type === "Integer" || e.type === "Binary"), x;
|
|
555
|
+
if (typeof g?.HasPrimalSolution == "boolean") x = g.HasPrimalSolution;
|
|
556
|
+
else {
|
|
557
|
+
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
|
+
x = y === "Infeasible" || y === "Unbounded" || y === "InfeasibleOrUnbounded" || y === "Error" || y === "NotSolved" ? !1 : y === "Optimal" || y === "Feasible" ? n || t : n && (e.length === 0 || t);
|
|
559
|
+
}
|
|
560
|
+
let S = K(g?.Status, g?.StatusCode, x), T = null;
|
|
561
|
+
x && typeof g?.ObjectiveValue == "number" && Number.isFinite(g.ObjectiveValue) && (T = g.ObjectiveValue + v);
|
|
562
|
+
let D, O, k;
|
|
563
|
+
if (typeof g?.MipDualBound == "number" && Number.isFinite(g.MipDualBound) ? D = g.MipDualBound + v : !b && y === "Optimal" && T !== null && (D = T), T !== null && D !== void 0 && Number.isFinite(D) && (k = Math.abs(T - D)), v !== 0 && b && T !== null && D !== void 0 && k !== void 0) {
|
|
564
|
+
if (k === 0) O = 0;
|
|
565
|
+
else if (Math.abs(T) > 0) {
|
|
566
|
+
let e = k / Math.abs(T);
|
|
567
|
+
O = Number.isFinite(e) ? e : void 0;
|
|
568
|
+
} else O = void 0;
|
|
569
|
+
} else typeof g?.MipGap == "number" && Number.isFinite(g.MipGap) ? O = g.MipGap : b && y === "Optimal" && x && (k === void 0 || k === 0) && (O = 0);
|
|
570
|
+
if (!x) return {
|
|
571
|
+
status: S,
|
|
572
|
+
terminationStatus: y,
|
|
573
|
+
hasPrimalSolution: !1,
|
|
739
574
|
objectiveValue: null,
|
|
575
|
+
...D === void 0 ? {} : { objectiveBound: D },
|
|
576
|
+
...O === void 0 ? {} : {
|
|
577
|
+
relGap: O,
|
|
578
|
+
mipGap: O
|
|
579
|
+
},
|
|
580
|
+
...k === void 0 ? {} : { absGap: k },
|
|
740
581
|
values: {},
|
|
741
582
|
reducedCosts: {},
|
|
742
583
|
duals: {},
|
|
743
584
|
slacks: {},
|
|
744
|
-
runTime:
|
|
745
|
-
raw:
|
|
585
|
+
runTime: _,
|
|
586
|
+
raw: g
|
|
746
587
|
};
|
|
747
|
-
let
|
|
748
|
-
|
|
749
|
-
|
|
588
|
+
let A = (e, t, n) => {
|
|
589
|
+
Object.defineProperty(e, t, {
|
|
590
|
+
value: n,
|
|
591
|
+
enumerable: !0,
|
|
592
|
+
writable: !0,
|
|
593
|
+
configurable: !0
|
|
594
|
+
});
|
|
595
|
+
}, j = {}, ee = {}, M = {}, N = {};
|
|
596
|
+
if (g.Columns) for (let [e, t] of Object.entries(g.Columns)) {
|
|
597
|
+
let n = c.get(e);
|
|
750
598
|
if (n) {
|
|
751
|
-
|
|
752
|
-
|
|
599
|
+
if (typeof t.Primal == "number" && Number.isFinite(t.Primal)) {
|
|
600
|
+
let e = Math.abs(t.Primal) < 1e-9 ? 0 : t.Primal;
|
|
601
|
+
A(j, n.name, e);
|
|
602
|
+
}
|
|
603
|
+
typeof t.Dual == "number" && Number.isFinite(t.Dual) && A(M, n.name, Math.abs(t.Dual) < 1e-9 ? 0 : t.Dual);
|
|
753
604
|
}
|
|
754
605
|
}
|
|
755
|
-
if (
|
|
756
|
-
let e = Array.isArray(
|
|
606
|
+
if (g.Rows) {
|
|
607
|
+
let e = Array.isArray(g.Rows) ? g.Rows : Object.values(g.Rows);
|
|
757
608
|
for (let t of e) {
|
|
758
|
-
let e = t.Name, n =
|
|
759
|
-
if (n && (t.Dual
|
|
609
|
+
let e = t.Name, n = e ? l.get(e) : void 0;
|
|
610
|
+
if (n && (typeof t.Dual == "number" && Number.isFinite(t.Dual) && A(ee, n.name, Math.abs(t.Dual) < 1e-9 ? 0 : t.Dual), typeof t.Primal == "number" && Number.isFinite(t.Primal))) {
|
|
760
611
|
let e = n.rhs - t.Primal;
|
|
761
|
-
|
|
612
|
+
A(N, n.name, Math.abs(e) < 1e-9 ? 0 : e);
|
|
762
613
|
}
|
|
763
614
|
}
|
|
764
615
|
}
|
|
765
616
|
return {
|
|
766
|
-
status:
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
617
|
+
status: S,
|
|
618
|
+
terminationStatus: y,
|
|
619
|
+
hasPrimalSolution: !0,
|
|
620
|
+
objectiveValue: T,
|
|
621
|
+
...D === void 0 ? {} : { objectiveBound: D },
|
|
622
|
+
...O === void 0 ? {} : {
|
|
623
|
+
relGap: O,
|
|
624
|
+
mipGap: O
|
|
625
|
+
},
|
|
626
|
+
...k === void 0 ? {} : { absGap: k },
|
|
627
|
+
values: j,
|
|
628
|
+
reducedCosts: M,
|
|
629
|
+
duals: ee,
|
|
630
|
+
slacks: N,
|
|
631
|
+
runTime: _,
|
|
632
|
+
raw: g
|
|
774
633
|
};
|
|
775
634
|
}
|
|
776
|
-
},
|
|
777
|
-
function
|
|
778
|
-
|
|
635
|
+
}, J = q;
|
|
636
|
+
function Y() {
|
|
637
|
+
T("highs", (e) => new q(e)), _((e) => new q(e));
|
|
779
638
|
}
|
|
780
|
-
|
|
639
|
+
Y();
|
|
781
640
|
//#endregion
|
|
782
641
|
//#region src/modeler/solvers/highs/index.ts
|
|
783
|
-
var
|
|
784
|
-
HiGHS: () =>
|
|
785
|
-
HighsSolver: () =>
|
|
786
|
-
OFFICIAL_HIGHS_CDN_WASM_URL: () =>
|
|
787
|
-
getHighs: () =>
|
|
788
|
-
getHighsWasmUrl: () =>
|
|
789
|
-
isValidWasmHeader: () =>
|
|
790
|
-
mapHighsStatus: () =>
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
642
|
+
var Te = /* @__PURE__ */ se({
|
|
643
|
+
HiGHS: () => J,
|
|
644
|
+
HighsSolver: () => q,
|
|
645
|
+
OFFICIAL_HIGHS_CDN_WASM_URL: () => te,
|
|
646
|
+
getHighs: () => F,
|
|
647
|
+
getHighsWasmUrl: () => L,
|
|
648
|
+
isValidWasmHeader: () => P,
|
|
649
|
+
mapHighsStatus: () => K,
|
|
650
|
+
mapHighsTerminationStatus: () => G,
|
|
651
|
+
probeWasmUrl: () => M,
|
|
652
|
+
registerHighsSolver: () => Y,
|
|
653
|
+
resolveBrowserWasmUrl: () => I,
|
|
654
|
+
setHighsWasmUrl: () => R,
|
|
655
|
+
solveLp: () => W,
|
|
656
|
+
solveLpWithHighs: () => N
|
|
797
657
|
});
|
|
798
|
-
import * as
|
|
799
|
-
|
|
800
|
-
import * as
|
|
801
|
-
|
|
658
|
+
import * as Ee from "./highs-worker-factory.js";
|
|
659
|
+
z(Te, Ee);
|
|
660
|
+
import * as De from "./highs-assets.js";
|
|
661
|
+
z(Te, De);
|
|
802
662
|
//#endregion
|
|
803
663
|
//#region src/modeler/solvers/highs.ts
|
|
804
|
-
var
|
|
805
|
-
HiGHS: () =>
|
|
806
|
-
HighsSolver: () =>
|
|
807
|
-
OFFICIAL_HIGHS_CDN_WASM_URL: () =>
|
|
808
|
-
getHighs: () =>
|
|
809
|
-
getHighsWasmUrl: () =>
|
|
810
|
-
isValidWasmHeader: () =>
|
|
811
|
-
mapHighsStatus: () =>
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
664
|
+
var Oe = /* @__PURE__ */ se({
|
|
665
|
+
HiGHS: () => J,
|
|
666
|
+
HighsSolver: () => q,
|
|
667
|
+
OFFICIAL_HIGHS_CDN_WASM_URL: () => te,
|
|
668
|
+
getHighs: () => F,
|
|
669
|
+
getHighsWasmUrl: () => L,
|
|
670
|
+
isValidWasmHeader: () => P,
|
|
671
|
+
mapHighsStatus: () => K,
|
|
672
|
+
mapHighsTerminationStatus: () => G,
|
|
673
|
+
probeWasmUrl: () => M,
|
|
674
|
+
registerHighsSolver: () => Y,
|
|
675
|
+
resolveBrowserWasmUrl: () => I,
|
|
676
|
+
setHighsWasmUrl: () => R,
|
|
677
|
+
solveLp: () => W,
|
|
678
|
+
solveLpWithHighs: () => N
|
|
818
679
|
});
|
|
819
|
-
|
|
680
|
+
z(Oe, Te);
|
|
820
681
|
//#endregion
|
|
821
682
|
//#region src/modeler/solvers/mock.ts
|
|
822
|
-
var
|
|
683
|
+
var ke = class {
|
|
823
684
|
name;
|
|
824
685
|
capabilities;
|
|
825
686
|
options;
|
|
826
687
|
constructor(e = {}) {
|
|
827
688
|
this.name = e.name || "MockSolver", this.capabilities = e.capabilities || {
|
|
828
689
|
supportsMIP: !0,
|
|
829
|
-
supportsQP: !0
|
|
690
|
+
supportsQP: !0,
|
|
691
|
+
supportsWarmStart: !0
|
|
830
692
|
}, this.options = e;
|
|
831
693
|
}
|
|
832
|
-
async solve(e, t, n = {}) {
|
|
833
|
-
let r = {
|
|
694
|
+
async solve(e, t = {}, n = {}) {
|
|
695
|
+
let r = E(t) ? n : t, i = {
|
|
834
696
|
...this.options,
|
|
835
|
-
...
|
|
697
|
+
...r
|
|
698
|
+
}, a = !!(i.values && Object.keys(i.values).length > 0 || i.boolValues && Object.keys(i.boolValues).length > 0);
|
|
699
|
+
if (i.signal?.aborted) return {
|
|
700
|
+
status: "Unknown",
|
|
701
|
+
terminationStatus: "Interrupted",
|
|
702
|
+
hasPrimalSolution: !1,
|
|
703
|
+
objectiveValue: null,
|
|
704
|
+
values: {},
|
|
705
|
+
runTime: 0,
|
|
706
|
+
raw: { mock: !0 }
|
|
836
707
|
};
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
708
|
+
if (i.delayMs && i.delayMs > 0 && (await new Promise((e) => {
|
|
709
|
+
let t = setTimeout(() => {
|
|
710
|
+
i.signal?.removeEventListener("abort", n), e();
|
|
711
|
+
}, i.delayMs), n = () => {
|
|
712
|
+
clearTimeout(t), e();
|
|
713
|
+
};
|
|
714
|
+
i.signal?.addEventListener("abort", n, { once: !0 });
|
|
715
|
+
}), i.signal?.aborted)) {
|
|
716
|
+
let e = !!(i.hasPrimalSolution ?? a);
|
|
717
|
+
return {
|
|
718
|
+
status: e ? "Feasible" : "Unknown",
|
|
719
|
+
terminationStatus: "Interrupted",
|
|
720
|
+
hasPrimalSolution: e,
|
|
721
|
+
objectiveValue: e ? i.objectiveValue ?? 0 : null,
|
|
722
|
+
...i.objectiveBound === void 0 ? {} : { objectiveBound: i.objectiveBound },
|
|
723
|
+
...i.relGap === void 0 ? i.mipGap === void 0 ? {} : {
|
|
724
|
+
relGap: i.mipGap,
|
|
725
|
+
mipGap: i.mipGap
|
|
726
|
+
} : {
|
|
727
|
+
relGap: i.relGap,
|
|
728
|
+
mipGap: i.relGap
|
|
729
|
+
},
|
|
730
|
+
...i.absGap === void 0 ? {} : { absGap: i.absGap },
|
|
731
|
+
values: e && i.values || {},
|
|
732
|
+
...e && i.boolValues !== void 0 ? { boolValues: i.boolValues } : {},
|
|
733
|
+
runTime: .001,
|
|
734
|
+
raw: { mock: !0 }
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
if (i.onProgress && Array.isArray(i.progressEvents)) for (let e of i.progressEvents) {
|
|
738
|
+
if (i.signal?.aborted) break;
|
|
739
|
+
i.onProgress(e);
|
|
740
|
+
}
|
|
741
|
+
let o = i.status || "Optimal", s = i.terminationStatus ?? o, c = i.hasPrimalSolution === void 0 ? o === "Optimal" || o === "Feasible" || o === "Sat" || (o === "TimeLimit" || o === "IterationLimit" || s === "Interrupted") && a : i.hasPrimalSolution;
|
|
742
|
+
if (i.onProgress && !Array.isArray(i.progressEvents) && !i.signal?.aborted) {
|
|
743
|
+
let e = c ? i.objectiveValue ?? 0 : void 0;
|
|
744
|
+
i.onProgress({
|
|
745
|
+
elapsedTime: .001,
|
|
746
|
+
elapsedSeconds: .001,
|
|
747
|
+
...typeof e == "number" && Number.isFinite(e) ? { objectiveValue: e } : {},
|
|
748
|
+
...i.objectiveBound === void 0 ? {} : { objectiveBound: i.objectiveBound },
|
|
749
|
+
...i.relGap === void 0 ? i.mipGap === void 0 ? {} : {
|
|
750
|
+
relGap: i.mipGap,
|
|
751
|
+
mipGap: i.mipGap
|
|
752
|
+
} : {
|
|
753
|
+
relGap: i.relGap,
|
|
754
|
+
mipGap: i.relGap
|
|
755
|
+
},
|
|
756
|
+
...i.absGap === void 0 ? {} : { absGap: i.absGap }
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
return i.signal?.aborted && (s = "Interrupted", c = i.hasPrimalSolution === void 0 ? a : i.hasPrimalSolution, o = c ? "Feasible" : "Unknown"), {
|
|
760
|
+
status: o,
|
|
761
|
+
terminationStatus: s,
|
|
762
|
+
hasPrimalSolution: c,
|
|
763
|
+
objectiveValue: c ? i.objectiveValue ?? 0 : null,
|
|
764
|
+
...i.objectiveBound === void 0 ? {} : { objectiveBound: i.objectiveBound },
|
|
765
|
+
...i.relGap === void 0 ? i.mipGap === void 0 ? {} : {
|
|
766
|
+
relGap: i.mipGap,
|
|
767
|
+
mipGap: i.mipGap
|
|
768
|
+
} : {
|
|
769
|
+
relGap: i.relGap,
|
|
770
|
+
mipGap: i.relGap
|
|
771
|
+
},
|
|
772
|
+
...i.absGap === void 0 ? {} : { absGap: i.absGap },
|
|
773
|
+
values: c && i.values || {},
|
|
774
|
+
...c && i.boolValues !== void 0 ? { boolValues: i.boolValues } : {},
|
|
775
|
+
reducedCosts: i.reducedCosts,
|
|
776
|
+
duals: i.duals,
|
|
777
|
+
slacks: i.slacks,
|
|
844
778
|
runTime: .001,
|
|
845
779
|
raw: { mock: !0 }
|
|
846
780
|
};
|
|
847
781
|
}
|
|
848
782
|
};
|
|
849
|
-
function
|
|
850
|
-
|
|
783
|
+
function Ae() {
|
|
784
|
+
T("mock", (e) => new ke(e));
|
|
851
785
|
}
|
|
852
|
-
|
|
786
|
+
Ae();
|
|
853
787
|
//#endregion
|
|
854
788
|
//#region src/modeler/solvers/index.ts
|
|
855
|
-
var
|
|
856
|
-
HiGHS: () =>
|
|
857
|
-
HighsSolver: () =>
|
|
858
|
-
MockSolver: () =>
|
|
859
|
-
OFFICIAL_HIGHS_CDN_WASM_URL: () =>
|
|
860
|
-
getHighs: () =>
|
|
861
|
-
getHighsWasmUrl: () =>
|
|
862
|
-
getSolver: () =>
|
|
863
|
-
isValidWasmHeader: () =>
|
|
864
|
-
listAvailableSolvers: () =>
|
|
865
|
-
mapHighsStatus: () =>
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
789
|
+
var je = /* @__PURE__ */ se({
|
|
790
|
+
HiGHS: () => J,
|
|
791
|
+
HighsSolver: () => q,
|
|
792
|
+
MockSolver: () => ke,
|
|
793
|
+
OFFICIAL_HIGHS_CDN_WASM_URL: () => te,
|
|
794
|
+
getHighs: () => F,
|
|
795
|
+
getHighsWasmUrl: () => L,
|
|
796
|
+
getSolver: () => D,
|
|
797
|
+
isValidWasmHeader: () => P,
|
|
798
|
+
listAvailableSolvers: () => S,
|
|
799
|
+
mapHighsStatus: () => K,
|
|
800
|
+
mapHighsTerminationStatus: () => G,
|
|
801
|
+
probeWasmUrl: () => M,
|
|
802
|
+
registerHighsSolver: () => Y,
|
|
803
|
+
registerMockSolver: () => Ae,
|
|
804
|
+
registerSolver: () => T,
|
|
805
|
+
resolveBrowserWasmUrl: () => I,
|
|
806
|
+
setDefaultSolver: () => _,
|
|
807
|
+
setHighsWasmUrl: () => R,
|
|
808
|
+
solveLp: () => W,
|
|
809
|
+
solveLpWithHighs: () => N
|
|
875
810
|
});
|
|
876
|
-
|
|
811
|
+
z(je, Oe);
|
|
812
|
+
//#endregion
|
|
813
|
+
//#region src/modeler/solution-validator.ts
|
|
814
|
+
function Me(e, t) {
|
|
815
|
+
if (e === void 0) return 1e-6;
|
|
816
|
+
if (typeof e != "number" || !Number.isFinite(e) || e < 0) throw Error(`Invalid ${t}: expected a finite non-negative number, received ${String(e)}.`);
|
|
817
|
+
return e;
|
|
818
|
+
}
|
|
819
|
+
function Ne(e, t = {}) {
|
|
820
|
+
let r = Me(t.feasibilityTolerance, "feasibilityTolerance"), i = Me(t.integralityTolerance, "integralityTolerance"), a = t.evaluateLogicalConstraints === void 0 || !!t.evaluateLogicalConstraints, s = t.values !== void 0 && t.values !== null;
|
|
821
|
+
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
|
+
let l = t.values, u = [], d = Object.create(null), f = [], p = [], m = 0, h = (e) => {
|
|
823
|
+
typeof e == "number" && !Number.isNaN(e) && e > m && (m = e);
|
|
824
|
+
}, g = (e) => {
|
|
825
|
+
u.push(e), Object.prototype.hasOwnProperty.call(d, e.name) || (d[e.name] = []), d[e.name].push(e), e.type !== "missing_value" && e.type !== "unchecked_constraint" && h(e.violation);
|
|
826
|
+
}, _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), y = 0, b = 0, x = 0, S = 0;
|
|
827
|
+
for (let t of e.variables) {
|
|
828
|
+
let e = s ? Object.prototype.hasOwnProperty.call(l, t.name) ? l[t.name] : void 0 : t.value;
|
|
829
|
+
if (e == null) {
|
|
830
|
+
p.push(t.name), g({
|
|
831
|
+
type: "missing_value",
|
|
832
|
+
target: "variable",
|
|
833
|
+
name: t.name,
|
|
834
|
+
actual: e ?? null,
|
|
835
|
+
violation: Infinity,
|
|
836
|
+
message: `Variable "${t.name}" has no assigned solution value.`
|
|
837
|
+
});
|
|
838
|
+
continue;
|
|
839
|
+
}
|
|
840
|
+
if (typeof e != "number" || !Number.isFinite(e)) {
|
|
841
|
+
g({
|
|
842
|
+
type: "non_finite_value",
|
|
843
|
+
target: "variable",
|
|
844
|
+
name: t.name,
|
|
845
|
+
actual: e,
|
|
846
|
+
violation: Infinity,
|
|
847
|
+
message: `Variable "${t.name}" has non-finite or non-numeric value: ${String(e)}.`
|
|
848
|
+
});
|
|
849
|
+
continue;
|
|
850
|
+
}
|
|
851
|
+
_.set(t, e), y++;
|
|
852
|
+
let n = t.type === "Binary" || t.type === "BINARY", a = n || t.type === "Integer" || t.type === "INTEGER", o = n ? Math.max(0, t.lb) : t.lb, c = n ? Math.min(1, t.ub) : t.ub, u = typeof t.lb == "number" && !Number.isNaN(t.lb) && t.lb !== Infinity, d = typeof t.ub == "number" && !Number.isNaN(t.ub) && t.ub !== -Infinity;
|
|
853
|
+
if (!u) g({
|
|
854
|
+
type: "lower_bound",
|
|
855
|
+
target: "variable",
|
|
856
|
+
name: t.name,
|
|
857
|
+
actual: e,
|
|
858
|
+
limit: t.lb,
|
|
859
|
+
violation: Infinity,
|
|
860
|
+
message: `Variable "${t.name}" has invalid lower bound (${String(t.lb)}).`
|
|
861
|
+
});
|
|
862
|
+
else if (o !== -Infinity) {
|
|
863
|
+
let n = e - o, i = Math.max(0, o - e);
|
|
864
|
+
h(i), i > r && g({
|
|
865
|
+
type: "lower_bound",
|
|
866
|
+
target: "variable",
|
|
867
|
+
name: t.name,
|
|
868
|
+
actual: e,
|
|
869
|
+
limit: o,
|
|
870
|
+
violation: i,
|
|
871
|
+
signedViolation: n,
|
|
872
|
+
message: `Variable "${t.name}" value (${e}) violates lower bound (${o}) by ${i}.`
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
if (!d) g({
|
|
876
|
+
type: "upper_bound",
|
|
877
|
+
target: "variable",
|
|
878
|
+
name: t.name,
|
|
879
|
+
actual: e,
|
|
880
|
+
limit: t.ub,
|
|
881
|
+
violation: Infinity,
|
|
882
|
+
message: `Variable "${t.name}" has invalid upper bound (${String(t.ub)}).`
|
|
883
|
+
});
|
|
884
|
+
else if (c !== Infinity) {
|
|
885
|
+
let n = e - c, i = Math.max(0, e - c);
|
|
886
|
+
h(i), i > r && g({
|
|
887
|
+
type: "upper_bound",
|
|
888
|
+
target: "variable",
|
|
889
|
+
name: t.name,
|
|
890
|
+
actual: e,
|
|
891
|
+
limit: c,
|
|
892
|
+
violation: i,
|
|
893
|
+
signedViolation: n,
|
|
894
|
+
message: `Variable "${t.name}" value (${e}) violates upper bound (${c}) by ${i}.`
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
if (u && d && o > c && o - e <= r && e - c <= r) {
|
|
898
|
+
let n = o - c;
|
|
899
|
+
g({
|
|
900
|
+
type: "lower_bound",
|
|
901
|
+
target: "variable",
|
|
902
|
+
name: t.name,
|
|
903
|
+
actual: e,
|
|
904
|
+
limit: o,
|
|
905
|
+
violation: n,
|
|
906
|
+
signedViolation: e - o,
|
|
907
|
+
message: `Variable "${t.name}" has inverted bounds [${o}, ${c}].`
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
if (a) {
|
|
911
|
+
let r = Math.round(e), a = e - r, o = Math.abs(a);
|
|
912
|
+
h(o), o > i && g({
|
|
913
|
+
type: "integrality",
|
|
914
|
+
target: "variable",
|
|
915
|
+
name: t.name,
|
|
916
|
+
varType: n ? "Binary" : "Integer",
|
|
917
|
+
actual: e,
|
|
918
|
+
nearestInteger: r,
|
|
919
|
+
violation: o,
|
|
920
|
+
signedViolation: a,
|
|
921
|
+
message: `${n ? "Binary" : "Integer"} variable "${t.name}" value (${e}) violates integrality by ${o} (nearest integer: ${r}).`
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
for (let t of e.boolVars) {
|
|
926
|
+
let e = s ? Object.prototype.hasOwnProperty.call(l, t.name) ? l[t.name] : void 0 : t.value;
|
|
927
|
+
if (e == null) {
|
|
928
|
+
p.push(t.name), g({
|
|
929
|
+
type: "missing_value",
|
|
930
|
+
target: "bool_variable",
|
|
931
|
+
name: t.name,
|
|
932
|
+
actual: e ?? null,
|
|
933
|
+
violation: Infinity,
|
|
934
|
+
message: `Boolean variable "${t.name}" has no assigned solution value.`
|
|
935
|
+
});
|
|
936
|
+
continue;
|
|
937
|
+
}
|
|
938
|
+
if (typeof e != "boolean") {
|
|
939
|
+
g({
|
|
940
|
+
type: "invalid_boolean_value",
|
|
941
|
+
target: "bool_variable",
|
|
942
|
+
name: t.name,
|
|
943
|
+
actual: e,
|
|
944
|
+
violation: Infinity,
|
|
945
|
+
message: `Boolean variable "${t.name}" has non-boolean value: ${String(e)}.`
|
|
946
|
+
});
|
|
947
|
+
continue;
|
|
948
|
+
}
|
|
949
|
+
v.set(t, e), b++;
|
|
950
|
+
}
|
|
951
|
+
let C = (e) => {
|
|
952
|
+
let t = e.constant === void 0 ? 0 : e.constant;
|
|
953
|
+
if (typeof t != "number" || !Number.isFinite(t)) return {
|
|
954
|
+
ok: !1,
|
|
955
|
+
reason: `non-finite constant (${String(t)})`
|
|
956
|
+
};
|
|
957
|
+
let n = t;
|
|
958
|
+
for (let [t, r] of e.terms) {
|
|
959
|
+
if (typeof r != "number" || !Number.isFinite(r)) return {
|
|
960
|
+
ok: !1,
|
|
961
|
+
reason: `non-finite coefficient (${String(r)}) for variable "${t.name}"`
|
|
962
|
+
};
|
|
963
|
+
if (r !== 0) {
|
|
964
|
+
if (!_.has(t)) return {
|
|
965
|
+
ok: !1,
|
|
966
|
+
reason: `missing or invalid value for variable "${t.name}"`
|
|
967
|
+
};
|
|
968
|
+
if (n += r * _.get(t), !Number.isFinite(n)) return {
|
|
969
|
+
ok: !1,
|
|
970
|
+
reason: "linear expression evaluation overflowed finite range"
|
|
971
|
+
};
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
return {
|
|
975
|
+
ok: !0,
|
|
976
|
+
value: n
|
|
977
|
+
};
|
|
978
|
+
}, w = (e, t = r) => {
|
|
979
|
+
if (typeof e.rhs != "number" || !Number.isFinite(e.rhs)) return {
|
|
980
|
+
status: "unchecked",
|
|
981
|
+
reason: `non-finite right-hand side (${String(e.rhs)})`
|
|
982
|
+
};
|
|
983
|
+
let n = C(e.lhs);
|
|
984
|
+
if (!n.ok) return {
|
|
985
|
+
status: "unchecked",
|
|
986
|
+
reason: n.reason
|
|
987
|
+
};
|
|
988
|
+
let i = n.value, a = i - e.rhs;
|
|
989
|
+
if (!Number.isFinite(a)) return {
|
|
990
|
+
status: "unchecked",
|
|
991
|
+
reason: "constraint residual overflowed finite range"
|
|
992
|
+
};
|
|
993
|
+
let o = e.sense === "<=" ? Math.max(0, a) : e.sense === ">=" ? Math.max(0, -a) : Math.abs(a);
|
|
994
|
+
return o > t ? {
|
|
995
|
+
status: "violated",
|
|
996
|
+
lhsVal: i,
|
|
997
|
+
signed: a,
|
|
998
|
+
violation: o,
|
|
999
|
+
message: `Constraint "${e.name}" (${i} ${e.sense} ${e.rhs}) violated by ${o}.`
|
|
1000
|
+
} : {
|
|
1001
|
+
status: "satisfied",
|
|
1002
|
+
lhsVal: i,
|
|
1003
|
+
signed: a,
|
|
1004
|
+
violation: o
|
|
1005
|
+
};
|
|
1006
|
+
};
|
|
1007
|
+
for (let t of e.constraints) {
|
|
1008
|
+
let e = w(t);
|
|
1009
|
+
e.status === "unchecked" ? (f.push(t.name), g({
|
|
1010
|
+
type: "unchecked_constraint",
|
|
1011
|
+
target: "constraint",
|
|
1012
|
+
name: t.name,
|
|
1013
|
+
sense: t.sense,
|
|
1014
|
+
limit: t.rhs,
|
|
1015
|
+
rhs: t.rhs,
|
|
1016
|
+
violation: Infinity,
|
|
1017
|
+
message: `Constraint "${t.name}" could not be evaluated: ${e.reason}.`
|
|
1018
|
+
})) : e.status === "violated" ? (x++, g({
|
|
1019
|
+
type: "linear_constraint",
|
|
1020
|
+
target: "constraint",
|
|
1021
|
+
name: t.name,
|
|
1022
|
+
sense: t.sense,
|
|
1023
|
+
actual: e.lhsVal,
|
|
1024
|
+
limit: t.rhs,
|
|
1025
|
+
rhs: t.rhs,
|
|
1026
|
+
violation: e.violation,
|
|
1027
|
+
signedViolation: e.signed,
|
|
1028
|
+
message: e.message
|
|
1029
|
+
})) : (x++, h(e.violation));
|
|
1030
|
+
}
|
|
1031
|
+
let T = (e) => {
|
|
1032
|
+
if (e instanceof o) return v.has(e) ? {
|
|
1033
|
+
ok: !0,
|
|
1034
|
+
value: v.get(e),
|
|
1035
|
+
violation: 0
|
|
1036
|
+
} : {
|
|
1037
|
+
ok: !1,
|
|
1038
|
+
reason: `missing or invalid value for Boolean variable "${e.name}"`
|
|
1039
|
+
};
|
|
1040
|
+
if (e instanceof c) {
|
|
1041
|
+
let t = w(e, 0);
|
|
1042
|
+
if (t.status === "unchecked") return {
|
|
1043
|
+
ok: !1,
|
|
1044
|
+
reason: t.reason
|
|
1045
|
+
};
|
|
1046
|
+
if (r > 0) {
|
|
1047
|
+
let n = Math.abs(t.lhsVal - e.rhs);
|
|
1048
|
+
if (n > 0 && n <= r) return {
|
|
1049
|
+
ok: !1,
|
|
1050
|
+
reason: `numeric comparison "${e.name}" lies within feasibilityTolerance (${r}) of boundary (${t.lhsVal} vs ${e.rhs})`
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
return {
|
|
1054
|
+
ok: !0,
|
|
1055
|
+
value: t.status === "satisfied",
|
|
1056
|
+
violation: 0
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
if (e instanceof n) switch (e.op) {
|
|
1060
|
+
case "not": {
|
|
1061
|
+
let t = T(e.children[0]);
|
|
1062
|
+
return t.ok ? {
|
|
1063
|
+
ok: !0,
|
|
1064
|
+
value: !t.value,
|
|
1065
|
+
violation: 0
|
|
1066
|
+
} : t;
|
|
1067
|
+
}
|
|
1068
|
+
case "and": {
|
|
1069
|
+
let t = 0;
|
|
1070
|
+
for (let n of e.children) {
|
|
1071
|
+
let e = T(n);
|
|
1072
|
+
if (!e.ok) return e;
|
|
1073
|
+
if (!e.value) return {
|
|
1074
|
+
ok: !0,
|
|
1075
|
+
value: !1,
|
|
1076
|
+
violation: 0
|
|
1077
|
+
};
|
|
1078
|
+
e.violation > t && (t = e.violation);
|
|
1079
|
+
}
|
|
1080
|
+
return {
|
|
1081
|
+
ok: !0,
|
|
1082
|
+
value: !0,
|
|
1083
|
+
violation: t
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1086
|
+
case "or": {
|
|
1087
|
+
let t = !1, n = Infinity;
|
|
1088
|
+
for (let r of e.children) {
|
|
1089
|
+
let e = T(r);
|
|
1090
|
+
if (!e.ok) return e;
|
|
1091
|
+
e.value && (t = !0, e.violation < n && (n = e.violation));
|
|
1092
|
+
}
|
|
1093
|
+
return {
|
|
1094
|
+
ok: !0,
|
|
1095
|
+
value: t,
|
|
1096
|
+
violation: t ? n : 0
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1099
|
+
case "implies": {
|
|
1100
|
+
let t = T(e.children[0]);
|
|
1101
|
+
if (!t.ok) return t;
|
|
1102
|
+
if (!t.value) return {
|
|
1103
|
+
ok: !0,
|
|
1104
|
+
value: !0,
|
|
1105
|
+
violation: 0
|
|
1106
|
+
};
|
|
1107
|
+
let n = T(e.children[1]);
|
|
1108
|
+
return n.ok ? {
|
|
1109
|
+
ok: !0,
|
|
1110
|
+
value: n.value,
|
|
1111
|
+
violation: n.value ? n.violation : 0
|
|
1112
|
+
} : n;
|
|
1113
|
+
}
|
|
1114
|
+
case "xor": {
|
|
1115
|
+
let t = !1, n = 0;
|
|
1116
|
+
for (let r of e.children) {
|
|
1117
|
+
let e = T(r);
|
|
1118
|
+
if (!e.ok) return e;
|
|
1119
|
+
e.value && (t = !t, e.violation > n && (n = e.violation));
|
|
1120
|
+
}
|
|
1121
|
+
return {
|
|
1122
|
+
ok: !0,
|
|
1123
|
+
value: t,
|
|
1124
|
+
violation: t ? n : 0
|
|
1125
|
+
};
|
|
1126
|
+
}
|
|
1127
|
+
default: return {
|
|
1128
|
+
ok: !1,
|
|
1129
|
+
reason: `unsupported logical operator "${String(e.op)}"`
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
return {
|
|
1133
|
+
ok: !1,
|
|
1134
|
+
reason: "unsupported logical expression node"
|
|
1135
|
+
};
|
|
1136
|
+
};
|
|
1137
|
+
for (let t = 0; t < e.logicalConstraints.length; t++) {
|
|
1138
|
+
let n = e.logicalConstraints[t], r = n.name || `lc_${t + 1}`;
|
|
1139
|
+
if (!a) {
|
|
1140
|
+
f.push(r), g({
|
|
1141
|
+
type: "unchecked_constraint",
|
|
1142
|
+
target: "logical_constraint",
|
|
1143
|
+
name: r,
|
|
1144
|
+
violation: Infinity,
|
|
1145
|
+
message: `Logical constraint "${r}" was not evaluated because evaluateLogicalConstraints is false.`
|
|
1146
|
+
});
|
|
1147
|
+
continue;
|
|
1148
|
+
}
|
|
1149
|
+
let i = T(n.expr);
|
|
1150
|
+
if (!i.ok) {
|
|
1151
|
+
f.push(r), g({
|
|
1152
|
+
type: "unchecked_constraint",
|
|
1153
|
+
target: "logical_constraint",
|
|
1154
|
+
name: r,
|
|
1155
|
+
violation: Infinity,
|
|
1156
|
+
message: `Logical constraint "${r}" could not be evaluated: ${i.reason}.`
|
|
1157
|
+
});
|
|
1158
|
+
continue;
|
|
1159
|
+
}
|
|
1160
|
+
S++, i.value ? h(i.violation) : g({
|
|
1161
|
+
type: "logical_constraint",
|
|
1162
|
+
target: "logical_constraint",
|
|
1163
|
+
name: r,
|
|
1164
|
+
actual: !1,
|
|
1165
|
+
limit: !0,
|
|
1166
|
+
violation: 1,
|
|
1167
|
+
signedViolation: -1,
|
|
1168
|
+
message: `Logical constraint "${r}" evaluated to false.`
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
1171
|
+
let E = y === e.variables.length && b === e.boolVars.length && x === e.constraints.length && S === e.logicalConstraints.length && f.length === 0 && p.length === 0;
|
|
1172
|
+
return {
|
|
1173
|
+
valid: E && u.length === 0,
|
|
1174
|
+
complete: E,
|
|
1175
|
+
violations: u,
|
|
1176
|
+
violationsByName: d,
|
|
1177
|
+
uncheckedConstraints: f,
|
|
1178
|
+
missingVariables: p,
|
|
1179
|
+
maxViolation: m,
|
|
1180
|
+
summary: {
|
|
1181
|
+
checkedVariables: y,
|
|
1182
|
+
totalVariables: e.variables.length,
|
|
1183
|
+
checkedBoolVariables: b,
|
|
1184
|
+
totalBoolVariables: e.boolVars.length,
|
|
1185
|
+
checkedLinearConstraints: x,
|
|
1186
|
+
totalLinearConstraints: e.constraints.length,
|
|
1187
|
+
checkedLogicalConstraints: S,
|
|
1188
|
+
totalLogicalConstraints: e.logicalConstraints.length
|
|
1189
|
+
}
|
|
1190
|
+
};
|
|
1191
|
+
}
|
|
1192
|
+
//#endregion
|
|
1193
|
+
//#region src/modeler/big-m.ts
|
|
1194
|
+
function Pe(e, t) {
|
|
1195
|
+
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
|
+
}
|
|
1197
|
+
function Fe(e, t, n) {
|
|
1198
|
+
let r = e.constant === void 0 ? 0 : e.constant;
|
|
1199
|
+
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
|
+
let i = t - r;
|
|
1201
|
+
if (!Number.isFinite(i)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": effective right-hand side (${t} - ${r}) overflows finite floating-point range. Please rescale coefficients/constants.`);
|
|
1202
|
+
for (let [t, r] of e.terms) {
|
|
1203
|
+
if (!Number.isFinite(r)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" has non-finite coefficient (${r}).`);
|
|
1204
|
+
if (Number.isNaN(t.lb) || Number.isNaN(t.ub) || t.lb === Infinity || t.ub === -Infinity || t.lb > t.ub) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" has invalid bounds [${t.lb}, ${t.ub}].`);
|
|
1205
|
+
}
|
|
1206
|
+
return i;
|
|
1207
|
+
}
|
|
1208
|
+
function Ie(e, t, n) {
|
|
1209
|
+
let r = Fe(e, t, n), i = 0;
|
|
1210
|
+
for (let [t, r] of e.terms) {
|
|
1211
|
+
if (r === 0) continue;
|
|
1212
|
+
let e;
|
|
1213
|
+
if (r > 0) {
|
|
1214
|
+
if (!Number.isFinite(t.ub)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite upper bound (required because coefficient ${r} is positive in <= constraint). Please set an explicit finite upper bound on the variable or specify { M } explicitly in indicator options.`);
|
|
1215
|
+
e = t.ub;
|
|
1216
|
+
} else {
|
|
1217
|
+
if (!Number.isFinite(t.lb)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite lower bound (required because coefficient ${r} is negative in <= constraint). Please set an explicit finite lower bound on the variable or specify { M } explicitly in indicator options.`);
|
|
1218
|
+
e = t.lb;
|
|
1219
|
+
}
|
|
1220
|
+
let a = r * e;
|
|
1221
|
+
if (i += a, !Number.isFinite(a) || !Number.isFinite(i)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while bounding contribution of variable "${t.name}". Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
1222
|
+
}
|
|
1223
|
+
let a = i - r;
|
|
1224
|
+
if (!Number.isFinite(a)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while computing Big-M (${i} - ${r}). Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
1225
|
+
let o = Math.max(0, a);
|
|
1226
|
+
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
|
+
return o;
|
|
1228
|
+
}
|
|
1229
|
+
function Le(e, t, n) {
|
|
1230
|
+
let r = Fe(e, t, n), i = 0;
|
|
1231
|
+
for (let [t, r] of e.terms) {
|
|
1232
|
+
if (r === 0) continue;
|
|
1233
|
+
let e;
|
|
1234
|
+
if (r > 0) {
|
|
1235
|
+
if (!Number.isFinite(t.lb)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite lower bound (required because coefficient ${r} is positive in >= constraint). Please set an explicit finite lower bound on the variable or specify { M } explicitly in indicator options.`);
|
|
1236
|
+
e = t.lb;
|
|
1237
|
+
} else {
|
|
1238
|
+
if (!Number.isFinite(t.ub)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite upper bound (required because coefficient ${r} is negative in >= constraint). Please set an explicit finite upper bound on the variable or specify { M } explicitly in indicator options.`);
|
|
1239
|
+
e = t.ub;
|
|
1240
|
+
}
|
|
1241
|
+
let a = r * e;
|
|
1242
|
+
if (i += a, !Number.isFinite(a) || !Number.isFinite(i)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while bounding contribution of variable "${t.name}". Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
1243
|
+
}
|
|
1244
|
+
let a = r - i;
|
|
1245
|
+
if (!Number.isFinite(a)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while computing Big-M (${r} - ${i}). Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
1246
|
+
let o = Math.max(0, a);
|
|
1247
|
+
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
|
+
return o;
|
|
1249
|
+
}
|
|
1250
|
+
function X(e, t, n, r, i, a, o) {
|
|
1251
|
+
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
|
+
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 = Fe(t, r, o);
|
|
1254
|
+
if (i !== 0 && i !== 1) throw Error(`Invalid activeValue: ${i}. Indicator activation value must be 0 or 1.`);
|
|
1255
|
+
if (n !== "<=" && n !== ">=") throw Error(`Invalid indicator sense for "${o}": expected "<=" or ">=", received "${String(n)}".`);
|
|
1256
|
+
if (!Number.isFinite(a) || a < 0) throw Error(`Invalid Big-M value for indicator constraint "${o}": expected a finite non-negative number, received ${a}.`);
|
|
1257
|
+
let c = t.terms.get(e);
|
|
1258
|
+
if (c !== void 0 && c !== 0) throw Error(`Indicator constraint "${o}" cannot include its own binary activation variable "${e.name}" in the linear expression.`);
|
|
1259
|
+
let l, u;
|
|
1260
|
+
if (i === 1 ? n === "<=" ? (l = a, u = s + a) : (l = -a, u = s - a) : n === "<=" ? (l = -a, u = s) : (l = a, u = s), !Number.isFinite(u)) throw Error(`Cannot construct finite indicator constraint "${o}": shifted right-hand side overflows finite floating-point range. Please rescale coefficients/bounds or specify a smaller finite { M }.`);
|
|
1261
|
+
let d = /* @__PURE__ */ new Map();
|
|
1262
|
+
for (let [e, n] of t.terms) n !== 0 && d.set(e, n);
|
|
1263
|
+
return l !== 0 && d.set(e, l), {
|
|
1264
|
+
lhs: new j(d, 0),
|
|
1265
|
+
rhs: u
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
877
1268
|
//#endregion
|
|
878
1269
|
//#region src/modeler/model.ts
|
|
879
|
-
|
|
1270
|
+
function Z(e) {
|
|
1271
|
+
return Array.isArray(e) || typeof e == "object" && !!e && !(e instanceof String) && typeof e[Symbol.iterator] == "function";
|
|
1272
|
+
}
|
|
1273
|
+
function Q(e) {
|
|
1274
|
+
return typeof e == "object" && !!e && !Array.isArray(e) && !(e instanceof String) && typeof e[Symbol.iterator] != "function";
|
|
1275
|
+
}
|
|
1276
|
+
function $(e, t) {
|
|
1277
|
+
if (!Number.isInteger(e) || e < 0) throw Error(`Invalid count (${e}) for ${t} variable creation: count must be a non-negative integer.`);
|
|
1278
|
+
}
|
|
1279
|
+
var Re = class {
|
|
880
1280
|
name;
|
|
881
|
-
|
|
882
|
-
|
|
1281
|
+
_sense;
|
|
1282
|
+
_objectiveExpr;
|
|
883
1283
|
variables = [];
|
|
884
1284
|
constraints = [];
|
|
885
1285
|
boolVars = [];
|
|
886
1286
|
logicalConstraints = [];
|
|
887
|
-
unsatCore =
|
|
1287
|
+
unsatCore = void 0;
|
|
888
1288
|
values = /* @__PURE__ */ new Map();
|
|
889
1289
|
varMapByName = /* @__PURE__ */ new Map();
|
|
1290
|
+
varPrefixCounters = /* @__PURE__ */ new Map();
|
|
1291
|
+
boolVarMapByName = /* @__PURE__ */ new Map();
|
|
1292
|
+
boolVarPrefixCounters = /* @__PURE__ */ new Map();
|
|
890
1293
|
constrMapByName = /* @__PURE__ */ new Map();
|
|
1294
|
+
constrPrefixCounters = /* @__PURE__ */ new Map();
|
|
1295
|
+
logicalConstrMapByName = /* @__PURE__ */ new Map();
|
|
1296
|
+
logicalConstrCounter = 0;
|
|
891
1297
|
status = "NotSolved";
|
|
1298
|
+
terminationStatus = "NotSolved";
|
|
1299
|
+
hasPrimalSolution = !1;
|
|
892
1300
|
objectiveValue = null;
|
|
1301
|
+
objectiveBound = void 0;
|
|
1302
|
+
relGap = void 0;
|
|
1303
|
+
mipGap = void 0;
|
|
1304
|
+
absGap = void 0;
|
|
893
1305
|
runTime = 0;
|
|
894
1306
|
solution = null;
|
|
895
1307
|
solver = null;
|
|
1308
|
+
hasSolutionState = !1;
|
|
1309
|
+
modelRevision = 0;
|
|
1310
|
+
activeOperationId = 0;
|
|
1311
|
+
batchDepth = 0;
|
|
1312
|
+
batchMutated = !1;
|
|
1313
|
+
batchUndoActions = [];
|
|
896
1314
|
constructor(e = {}, t) {
|
|
897
1315
|
let n;
|
|
898
1316
|
n = typeof e == "string" ? {
|
|
899
1317
|
...t,
|
|
900
1318
|
name: e
|
|
901
|
-
} : e, this.name = n.name || "OptimizationModel", this.
|
|
1319
|
+
} : e, this.name = n.name || "OptimizationModel", this._sense = le(n.sense), this._objectiveExpr = new j(), n.solver && (this.solver = D(n.solver));
|
|
1320
|
+
}
|
|
1321
|
+
get sense() {
|
|
1322
|
+
return this._sense;
|
|
902
1323
|
}
|
|
903
|
-
|
|
904
|
-
|
|
1324
|
+
set sense(e) {
|
|
1325
|
+
let t = le(e);
|
|
1326
|
+
this._sense !== t && (this._sense = t, this.recordModelMutation());
|
|
905
1327
|
}
|
|
906
|
-
get
|
|
907
|
-
return this.
|
|
1328
|
+
get objectiveExpr() {
|
|
1329
|
+
return this._objectiveExpr.clone();
|
|
1330
|
+
}
|
|
1331
|
+
set objectiveExpr(e) {
|
|
1332
|
+
this.applyObjective(e);
|
|
1333
|
+
}
|
|
1334
|
+
get conflicts() {
|
|
1335
|
+
return this.unsatCore;
|
|
908
1336
|
}
|
|
909
1337
|
get numVars() {
|
|
910
1338
|
return this.variables.length;
|
|
@@ -912,50 +1340,123 @@ var $ = class {
|
|
|
912
1340
|
get numConstrs() {
|
|
913
1341
|
return this.constraints.length;
|
|
914
1342
|
}
|
|
915
|
-
|
|
916
|
-
if (
|
|
917
|
-
|
|
918
|
-
for (let
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
1343
|
+
clearSolutionFields() {
|
|
1344
|
+
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();
|
|
1346
|
+
for (let e of this.variables) e.value = null, e.reducedCost = null;
|
|
1347
|
+
for (let e of this.boolVars) e.value = null;
|
|
1348
|
+
for (let e of this.constraints) e.dual = null, e.slack = null;
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
recordModelMutation() {
|
|
1352
|
+
if (this.batchDepth > 0) {
|
|
1353
|
+
this.batchMutated = !0;
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
this.modelRevision++, this.clearSolutionFields();
|
|
1357
|
+
}
|
|
1358
|
+
notifyMutation() {
|
|
1359
|
+
this.recordModelMutation();
|
|
1360
|
+
}
|
|
1361
|
+
resetSolutionState() {
|
|
1362
|
+
this.recordModelMutation();
|
|
1363
|
+
}
|
|
1364
|
+
runTransactionalBatch(e) {
|
|
1365
|
+
if (this.batchDepth > 0) return e();
|
|
1366
|
+
let t = this.variables.length, n = this.boolVars.length, r = this.constraints.length, i = this.logicalConstraints.length, a = new Map(this.varPrefixCounters), o = new Map(this.boolVarPrefixCounters), s = new Map(this.constrPrefixCounters), c = this.logicalConstrCounter;
|
|
1367
|
+
this.batchDepth = 1, this.batchMutated = !1, this.batchUndoActions = [];
|
|
1368
|
+
try {
|
|
1369
|
+
let t = e();
|
|
1370
|
+
this.batchDepth = 0;
|
|
1371
|
+
let n = this.batchMutated;
|
|
1372
|
+
return this.batchMutated = !1, this.batchUndoActions = [], n && this.recordModelMutation(), t;
|
|
1373
|
+
} catch (e) {
|
|
1374
|
+
this.batchDepth = 0, this.batchMutated = !1;
|
|
1375
|
+
for (let e = t; e < this.variables.length; e++) {
|
|
1376
|
+
let t = this.variables[e];
|
|
1377
|
+
this.varMapByName.delete(t.name), t.ownerModel = null, g(t, this);
|
|
925
1378
|
}
|
|
926
|
-
|
|
1379
|
+
this.variables.length = t;
|
|
1380
|
+
for (let e = n; e < this.boolVars.length; e++) {
|
|
1381
|
+
let t = this.boolVars[e];
|
|
1382
|
+
this.boolVarMapByName.delete(t.name);
|
|
1383
|
+
}
|
|
1384
|
+
this.boolVars.length = n;
|
|
1385
|
+
for (let e = r; e < this.constraints.length; e++) {
|
|
1386
|
+
let t = this.constraints[e];
|
|
1387
|
+
this.constrMapByName.delete(t.name);
|
|
1388
|
+
}
|
|
1389
|
+
this.constraints.length = r;
|
|
1390
|
+
for (let e = i; e < this.logicalConstraints.length; e++) {
|
|
1391
|
+
let t = this.logicalConstraints[e];
|
|
1392
|
+
this.logicalConstrMapByName.delete(t.name);
|
|
1393
|
+
}
|
|
1394
|
+
this.logicalConstraints.length = i;
|
|
1395
|
+
for (let e = this.batchUndoActions.length - 1; e >= 0; e--) this.batchUndoActions[e]();
|
|
1396
|
+
throw this.batchUndoActions = [], this.varPrefixCounters = a, this.boolVarPrefixCounters = o, this.constrPrefixCounters = s, this.logicalConstrCounter = c, e;
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
createDomainVars(e, t, n, r) {
|
|
1400
|
+
let i = e.toLowerCase(), a = typeof t == "number", o = typeof n == "number", s = Z(t), c = Z(n);
|
|
1401
|
+
if (o || c) {
|
|
1402
|
+
if (a && $(t, i), o && $(n, i), !a && !s || r !== void 0 && !Q(r)) throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
1403
|
+
let c = a ? Array.from({ length: t }, (e, t) => t) : Array.from(t), l = o ? Array.from({ length: n }, (e, t) => t) : n === t ? c : Array.from(n), u = r || {}, d = u.prefix || u.name || "x";
|
|
1404
|
+
return this.runTransactionalBatch(() => {
|
|
1405
|
+
let t = a ? [] : {};
|
|
1406
|
+
for (let n of c) {
|
|
1407
|
+
let r = o ? [] : {};
|
|
1408
|
+
for (let t of l) r[t] = this.addVar({
|
|
1409
|
+
...u,
|
|
1410
|
+
type: e,
|
|
1411
|
+
name: `${d}_${n}_${t}`
|
|
1412
|
+
});
|
|
1413
|
+
t[n] = r;
|
|
1414
|
+
}
|
|
1415
|
+
return t;
|
|
1416
|
+
});
|
|
927
1417
|
}
|
|
928
|
-
if (typeof t == "string") {
|
|
929
|
-
|
|
1418
|
+
if (typeof t == "string" || t === void 0) {
|
|
1419
|
+
if (n !== void 0 && !Q(n)) throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
1420
|
+
let r = n || {}, a = typeof t == "string" ? t : r.name;
|
|
930
1421
|
return this.addVar({
|
|
931
1422
|
...r,
|
|
932
1423
|
type: e,
|
|
933
|
-
name:
|
|
1424
|
+
name: a
|
|
1425
|
+
});
|
|
1426
|
+
}
|
|
1427
|
+
if (Q(t)) {
|
|
1428
|
+
if (n !== void 0) throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
1429
|
+
let r = t;
|
|
1430
|
+
return this.addVar({
|
|
1431
|
+
...r,
|
|
1432
|
+
type: e
|
|
934
1433
|
});
|
|
935
1434
|
}
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1435
|
+
if (n !== void 0 && !Q(n)) throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
1436
|
+
let l = n || {}, u = l.prefix || l.name;
|
|
1437
|
+
if (typeof t == "number") return $(t, i), this.runTransactionalBatch(() => {
|
|
1438
|
+
let n = [], r = u || "x";
|
|
1439
|
+
for (let i = 0; i < t; i++) n.push(this.addVar({
|
|
1440
|
+
...l,
|
|
941
1441
|
type: e,
|
|
942
|
-
name:
|
|
1442
|
+
name: void 0,
|
|
1443
|
+
prefix: r
|
|
943
1444
|
}));
|
|
944
1445
|
return n;
|
|
945
|
-
}
|
|
946
|
-
if (
|
|
1446
|
+
});
|
|
1447
|
+
if (Z(t)) return this.runTransactionalBatch(() => {
|
|
947
1448
|
let n = {};
|
|
948
1449
|
for (let r of t) {
|
|
949
|
-
let t =
|
|
1450
|
+
let t = u ? `${u}_${r}` : `${r}`;
|
|
950
1451
|
n[r] = this.addVar({
|
|
951
|
-
...
|
|
1452
|
+
...l,
|
|
952
1453
|
type: e,
|
|
953
1454
|
name: t
|
|
954
1455
|
});
|
|
955
1456
|
}
|
|
956
1457
|
return n;
|
|
957
|
-
}
|
|
958
|
-
throw Error(`Invalid arguments provided for ${
|
|
1458
|
+
});
|
|
1459
|
+
throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
959
1460
|
}
|
|
960
1461
|
binary(e, t, n) {
|
|
961
1462
|
return this.createDomainVars("Binary", e, t, n);
|
|
@@ -966,89 +1467,142 @@ var $ = class {
|
|
|
966
1467
|
continuous(e, t, n) {
|
|
967
1468
|
return this.createDomainVars("Continuous", e, t, n);
|
|
968
1469
|
}
|
|
969
|
-
|
|
970
|
-
let i;
|
|
971
|
-
i
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
let r = typeof e == "number" ? Array.from({ length: e }, (e, t) => t) : e, i = typeof t == "number" ? Array.from({ length: t }, (e, t) => t) : t, a = n || {}, o = a.prefix || a.name || "x", s = {};
|
|
984
|
-
for (let e of r) {
|
|
985
|
-
s[e] = {};
|
|
986
|
-
for (let t of i) s[e][t] = this.addVar({
|
|
987
|
-
...a,
|
|
988
|
-
name: `${o}_${e}_${t}`
|
|
989
|
-
});
|
|
990
|
-
}
|
|
991
|
-
return s;
|
|
1470
|
+
bool(e, t, n) {
|
|
1471
|
+
let r = typeof e == "number", i = typeof t == "number", a = Z(e), o = Z(t);
|
|
1472
|
+
if (i || o) {
|
|
1473
|
+
if (r && $(e, "boolean"), i && $(t, "boolean"), !r && !a || n !== void 0 && !Q(n)) throw Error("Invalid arguments provided for boolean variable creation");
|
|
1474
|
+
let o = r ? Array.from({ length: e }, (e, t) => t) : Array.from(e), s = i ? Array.from({ length: t }, (e, t) => t) : t === e ? o : Array.from(t), c = n || {}, l = c.prefix || c.name || "p";
|
|
1475
|
+
return this.runTransactionalBatch(() => {
|
|
1476
|
+
let e = r ? [] : {};
|
|
1477
|
+
for (let t of o) {
|
|
1478
|
+
let n = i ? [] : {};
|
|
1479
|
+
for (let e of s) n[e] = this.createBoolVar(`${l}_${t}_${e}`);
|
|
1480
|
+
e[t] = n;
|
|
1481
|
+
}
|
|
1482
|
+
return e;
|
|
1483
|
+
});
|
|
992
1484
|
}
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
let
|
|
996
|
-
|
|
997
|
-
...r,
|
|
998
|
-
name: `${n}_${i}`
|
|
999
|
-
}));
|
|
1000
|
-
return t;
|
|
1485
|
+
if (typeof e == "string" || e === void 0) {
|
|
1486
|
+
if (t !== void 0 && !Q(t)) throw Error("Invalid arguments provided for boolean variable creation");
|
|
1487
|
+
let n = t || {}, r = typeof e == "string" ? e : n.name;
|
|
1488
|
+
return this.createBoolVar(r, n.prefix);
|
|
1001
1489
|
}
|
|
1002
|
-
{
|
|
1490
|
+
if (Q(e)) {
|
|
1491
|
+
if (t !== void 0) throw Error("Invalid arguments provided for boolean variable creation");
|
|
1492
|
+
let n = e;
|
|
1493
|
+
return this.createBoolVar(n.name, n.prefix);
|
|
1494
|
+
}
|
|
1495
|
+
if (t !== void 0 && !Q(t)) throw Error("Invalid arguments provided for boolean variable creation");
|
|
1496
|
+
let s = t || {}, c = s.prefix || s.name;
|
|
1497
|
+
if (typeof e == "number") return $(e, "boolean"), this.runTransactionalBatch(() => {
|
|
1498
|
+
let t = [], n = c || "p";
|
|
1499
|
+
for (let r = 0; r < e; r++) t.push(this.createBoolVar(void 0, n));
|
|
1500
|
+
return t;
|
|
1501
|
+
});
|
|
1502
|
+
if (Z(e)) return this.runTransactionalBatch(() => {
|
|
1003
1503
|
let t = {};
|
|
1004
1504
|
for (let n of e) {
|
|
1005
|
-
let e =
|
|
1006
|
-
t[n] = this.
|
|
1007
|
-
...r,
|
|
1008
|
-
name: e
|
|
1009
|
-
});
|
|
1505
|
+
let e = c ? `${c}_${n}` : `${n}`;
|
|
1506
|
+
t[n] = this.createBoolVar(e);
|
|
1010
1507
|
}
|
|
1011
1508
|
return t;
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1509
|
+
});
|
|
1510
|
+
throw Error("Invalid arguments provided for boolean variable creation");
|
|
1511
|
+
}
|
|
1512
|
+
hasVarName(e) {
|
|
1513
|
+
return this.varMapByName.has(e) || this.boolVarMapByName.has(e);
|
|
1514
|
+
}
|
|
1515
|
+
getNextVarName(e) {
|
|
1516
|
+
let t = this.varPrefixCounters.get(e) ?? 0, n = `${e}_${t}`;
|
|
1517
|
+
for (; this.hasVarName(n);) t++, n = `${e}_${t}`;
|
|
1518
|
+
return this.varPrefixCounters.set(e, t + 1), n;
|
|
1519
|
+
}
|
|
1520
|
+
getNextBoolVarName(e) {
|
|
1521
|
+
let t = this.boolVarPrefixCounters.get(e) ?? 0, n = `${e}_${t}`;
|
|
1522
|
+
for (; this.hasVarName(n) || this.hasConstraintName(n);) t++, n = `${e}_${t}`;
|
|
1523
|
+
return this.boolVarPrefixCounters.set(e, t + 1), n;
|
|
1524
|
+
}
|
|
1525
|
+
hasConstraintName(e) {
|
|
1526
|
+
return this.constrMapByName.has(e) || this.logicalConstrMapByName.has(e);
|
|
1527
|
+
}
|
|
1528
|
+
hasBoolVarName(e) {
|
|
1529
|
+
return this.boolVarMapByName.has(e);
|
|
1530
|
+
}
|
|
1531
|
+
getNextConstrName(e = "c") {
|
|
1532
|
+
let t = this.constrPrefixCounters.get(e) ?? 1, n = `${e}_${t}`;
|
|
1533
|
+
for (; this.hasConstraintName(n) || this.hasBoolVarName(n);) t++, n = `${e}_${t}`;
|
|
1534
|
+
return this.constrPrefixCounters.set(e, t + 1), n;
|
|
1535
|
+
}
|
|
1536
|
+
getNextLogicalConstrName() {
|
|
1537
|
+
let e = this.logicalConstrCounter + 1, t = `lc_${e}`;
|
|
1538
|
+
for (; this.hasConstraintName(t) || this.hasBoolVarName(t);) e++, t = `lc_${e}`;
|
|
1539
|
+
return this.logicalConstrCounter = e, t;
|
|
1540
|
+
}
|
|
1541
|
+
createBoolVar(e, t) {
|
|
1542
|
+
let n = typeof e == "string" ? e.trim() : void 0, r = typeof t == "string" ? t.trim() : "", i = r.length > 0 ? r : "p", a = n && n.length > 0 ? n : this.getNextBoolVarName(i);
|
|
1543
|
+
if (this.hasVarName(a)) throw Error(`Variable with name '${a}' already exists in model`);
|
|
1544
|
+
if (this.hasConstraintName(a)) throw Error(`Boolean variable name '${a}' conflicts with an existing constraint in model`);
|
|
1545
|
+
let s = new o(a);
|
|
1546
|
+
return this.boolVars.push(s), this.boolVarMapByName.set(s.name, s), this.recordModelMutation(), s;
|
|
1547
|
+
}
|
|
1548
|
+
addVar(e) {
|
|
1549
|
+
let t = e || {}, n = typeof t.name == "string" ? t.name.trim() : void 0, r = n && n.length > 0 ? n : void 0, i = typeof t.prefix == "string" ? t.prefix.trim() : "", a = i.length > 0 ? i : "x", o = this.varPrefixCounters.get(a), s = r ?? this.getNextVarName(a);
|
|
1550
|
+
try {
|
|
1551
|
+
if (this.hasVarName(s)) throw Error(`Variable with name '${s}' already exists in model`);
|
|
1552
|
+
let e = new b({
|
|
1553
|
+
...t,
|
|
1554
|
+
name: s,
|
|
1555
|
+
prefix: a
|
|
1021
1556
|
});
|
|
1557
|
+
return e.hasExplicitName = r !== void 0, d(e), m(e, this), e.ownerModel = this, this.variables.push(e), this.varMapByName.set(e.name, e), this.recordModelMutation(), e;
|
|
1558
|
+
} catch (e) {
|
|
1559
|
+
throw r === void 0 && (o === void 0 ? this.varPrefixCounters.delete(a) : this.varPrefixCounters.set(a, o)), e;
|
|
1022
1560
|
}
|
|
1023
|
-
return r;
|
|
1024
1561
|
}
|
|
1025
1562
|
getVarByName(e) {
|
|
1026
1563
|
return this.varMapByName.get(e);
|
|
1027
1564
|
}
|
|
1565
|
+
getBoolVarByName(e) {
|
|
1566
|
+
return this.boolVarMapByName.get(e);
|
|
1567
|
+
}
|
|
1028
1568
|
getConstraintByName(e) {
|
|
1029
1569
|
return this.constrMapByName.get(e);
|
|
1030
1570
|
}
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
this.
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
if (
|
|
1043
|
-
|
|
1571
|
+
getLogicalConstraintByName(e) {
|
|
1572
|
+
return this.logicalConstrMapByName.get(e);
|
|
1573
|
+
}
|
|
1574
|
+
objective(e) {
|
|
1575
|
+
return e ? (this.applyObjective(e.expr, e.sense), this) : this.objectiveExpr;
|
|
1576
|
+
}
|
|
1577
|
+
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`... <= ...`)? For objectives, supply an unconstrained expression like expr`45 * ${x} + 80 * ${y}`.");
|
|
1579
|
+
let n = t === void 0 ? this.sense : le(t), r;
|
|
1580
|
+
if (typeof e == "string") r = pe(e, (e) => this.getVarByName(e));
|
|
1581
|
+
else if (typeof e == "number") r = new j(/* @__PURE__ */ new Map(), e);
|
|
1582
|
+
else if (e instanceof A) r = e.clone();
|
|
1583
|
+
else if (e instanceof j) r = e.clone();
|
|
1584
|
+
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
|
+
let t = e;
|
|
1586
|
+
r = new A(t.linearTerms, t.quadTerms, t.constant);
|
|
1587
|
+
} else if (typeof e == "object" && e && "terms" in e && e.terms instanceof Map && typeof e.constant == "number") {
|
|
1588
|
+
let t = e;
|
|
1589
|
+
r = new j(t.terms, t.constant);
|
|
1590
|
+
} else if (e instanceof b || typeof e == "object" && e && "id" in e && "name" in e && "lb" in e && "ub" in e) r = new j(/* @__PURE__ */ new Map([[e, 1]]), 0);
|
|
1591
|
+
else throw Error("Invalid objective expression: expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.");
|
|
1592
|
+
ee(r, this.name, (e) => this.varMapByName.get(e.name) === e), this._sense = n, this._objectiveExpr = r, this.recordModelMutation();
|
|
1593
|
+
}
|
|
1594
|
+
constraint(e, t) {
|
|
1595
|
+
if (Array.isArray(e)) return this.runTransactionalBatch(() => {
|
|
1596
|
+
for (let t of e) this.constraint(t);
|
|
1044
1597
|
return this;
|
|
1045
|
-
}
|
|
1046
|
-
if (e instanceof
|
|
1598
|
+
});
|
|
1599
|
+
if (e instanceof A || typeof e == "object" && e && "quadTerms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a quadratic expression as a constraint.");
|
|
1600
|
+
if (e instanceof j || 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().");
|
|
1047
1601
|
return this.addConstraint(e, t), this;
|
|
1048
1602
|
}
|
|
1049
1603
|
getValues(e) {
|
|
1050
1604
|
if (e == null) return null;
|
|
1051
|
-
if (e instanceof
|
|
1605
|
+
if (e instanceof b || e instanceof o) return e.value;
|
|
1052
1606
|
if (Array.isArray(e)) return e.map((e) => this.getValues(e));
|
|
1053
1607
|
if (typeof e == "object") {
|
|
1054
1608
|
let t = {};
|
|
@@ -1057,209 +1611,397 @@ var $ = class {
|
|
|
1057
1611
|
}
|
|
1058
1612
|
return null;
|
|
1059
1613
|
}
|
|
1060
|
-
addBoolVar(e) {
|
|
1061
|
-
let t = new n(e);
|
|
1062
|
-
return this.boolVars.push(t), t;
|
|
1063
|
-
}
|
|
1064
1614
|
addConstraint(e, t) {
|
|
1065
|
-
if (e instanceof
|
|
1066
|
-
if (e instanceof
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1615
|
+
if (e instanceof A || typeof e == "object" && e && "quadTerms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a quadratic expression as a constraint.");
|
|
1616
|
+
if (e instanceof j || 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().");
|
|
1617
|
+
if (e instanceof r) {
|
|
1618
|
+
let n = typeof t == "string" && t.trim().length > 0 ? t.trim() : void 0;
|
|
1619
|
+
if (n !== void 0) {
|
|
1620
|
+
if (this.hasConstraintName(n)) throw Error(`Constraint with name '${n}' already exists in model`);
|
|
1621
|
+
if (this.hasBoolVarName(n)) throw Error(`Constraint name '${n}' conflicts with an existing Boolean variable in model`);
|
|
1622
|
+
}
|
|
1623
|
+
let r = this.logicalConstrCounter, i = n ?? this.getNextLogicalConstrName();
|
|
1624
|
+
try {
|
|
1625
|
+
l(e, i, this.name, (e) => this.varMapByName.get(e.name) === e, (e) => this.boolVarMapByName.get(e.name) === e, this);
|
|
1626
|
+
} catch (e) {
|
|
1627
|
+
throw n === void 0 && (this.logicalConstrCounter = r), e;
|
|
1628
|
+
}
|
|
1629
|
+
O(e, this, this.batchDepth > 0 ? this.batchUndoActions : void 0);
|
|
1630
|
+
let a = {
|
|
1631
|
+
name: i,
|
|
1070
1632
|
expr: e
|
|
1071
|
-
}
|
|
1633
|
+
};
|
|
1634
|
+
return this.logicalConstraints.push(a), this.logicalConstrMapByName.set(i, a), this.recordModelMutation(), e;
|
|
1072
1635
|
}
|
|
1073
|
-
let n;
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
}
|
|
1080
|
-
addConstrs(e) {
|
|
1081
|
-
return e.map((e) => this.addConstraint(e));
|
|
1082
|
-
}
|
|
1083
|
-
add(e, t) {
|
|
1084
|
-
if (Array.isArray(e)) {
|
|
1085
|
-
for (let t of e) this.add(t);
|
|
1086
|
-
return this;
|
|
1636
|
+
let n = typeof e == "string" ? he(e, (e) => this.getVarByName(e), t) : e;
|
|
1637
|
+
n.ownerModel && n.ownerModel !== this && (h(n, this.name, (e) => this.varMapByName.get(e.name) === e, n.name), p(n, this));
|
|
1638
|
+
let i = typeof t == "string" && t.trim().length > 0 ? t.trim() : n.hasExplicitName ? n.name.trim() : void 0;
|
|
1639
|
+
if (i !== void 0) {
|
|
1640
|
+
if (this.hasConstraintName(i)) throw Error(`Constraint with name '${i}' already exists in model`);
|
|
1641
|
+
if (this.hasBoolVarName(i)) throw Error(`Constraint name '${i}' conflicts with an existing Boolean variable in model`);
|
|
1087
1642
|
}
|
|
1088
|
-
|
|
1643
|
+
let a = this.constrPrefixCounters.get("c"), o = i ?? this.getNextConstrName("c"), s;
|
|
1644
|
+
try {
|
|
1645
|
+
h(n, this.name, (e) => this.varMapByName.get(e.name) === e, o), s = p(n, this);
|
|
1646
|
+
} catch (e) {
|
|
1647
|
+
throw i === void 0 && (a === void 0 ? this.constrPrefixCounters.delete("c") : this.constrPrefixCounters.set("c", a)), e;
|
|
1648
|
+
}
|
|
1649
|
+
let c = n.name, u = n.hasExplicitName, d = n.ownerModel, f = s;
|
|
1650
|
+
return this.batchUndoActions.push(() => {
|
|
1651
|
+
n.ownerModel = d, n._assignModelName(c, u), x(n, this, f);
|
|
1652
|
+
}), 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;
|
|
1089
1653
|
}
|
|
1090
1654
|
indicator(e, t, n = {}) {
|
|
1655
|
+
if (!(e instanceof b)) throw Error("Invalid binary variable passed to indicator(). Expected a binary Var instance.");
|
|
1656
|
+
if (!(e.type === "Binary" || e.type === "Integer" && e.lb === 0 && e.ub === 1)) throw Error(`Invalid variable "${e.name}" passed to indicator(): variable has type "${e.type}" with bounds [${e.lb}, ${e.ub}]. Indicator activation variable must be a Binary variable (or Integer variable with bounds [0, 1]).`);
|
|
1657
|
+
if (t instanceof A) throw Error("Quadratic expressions or constraints are not supported in indicator constraints (only linear constraints are allowed).");
|
|
1091
1658
|
if (!("sense" in t) || !("lhs" in t)) throw Error("Invalid constraint expression passed to indicator(). Expression must include a comparison operator (<=, >=, ==).");
|
|
1092
|
-
let r = t, i = n.activeValue === void 0 ? 1 : n.activeValue
|
|
1093
|
-
if (i
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1659
|
+
let r = t, i = n.activeValue === void 0 ? 1 : n.activeValue;
|
|
1660
|
+
if (i !== 0 && i !== 1) throw Error(`Invalid activeValue: ${i}. Indicator activeValue must be 0 or 1.`);
|
|
1661
|
+
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 a = typeof n.name == "string" && n.name.trim().length > 0 ? n.name.trim() : void 0, o = this.constrPrefixCounters.get("c"), { lhs: s, sense: l, rhs: u } = r, d, f, p;
|
|
1663
|
+
if (a !== void 0) d = a, f = l === "==" ? `${d}_le` : d, p = l === "==" ? `${d}_ge` : d;
|
|
1664
|
+
else if (r.hasExplicitName) d = `ind_${e.name}_${r.name.trim()}`, f = l === "==" ? `${d}_le` : d, p = l === "==" ? `${d}_ge` : d;
|
|
1665
|
+
else do {
|
|
1666
|
+
let t = this.getNextConstrName("c");
|
|
1667
|
+
d = `ind_${e.name}_${t}`, f = l === "==" ? `${d}_le` : d, p = l === "==" ? `${d}_ge` : d;
|
|
1668
|
+
} while ((l === "<=" || l === "==") && (this.hasConstraintName(f) || this.hasBoolVarName(f)) || (l === ">=" || l === "==") && (this.hasConstraintName(p) || this.hasBoolVarName(p)));
|
|
1669
|
+
let m = [];
|
|
1670
|
+
try {
|
|
1671
|
+
if ((l === "<=" || l === "==") && (this.hasConstraintName(f) || this.hasBoolVarName(f))) throw Error(this.hasBoolVarName(f) ? `Constraint name '${f}' conflicts with an existing Boolean variable in model` : `Constraint with name '${f}' already exists in model`);
|
|
1672
|
+
if ((l === ">=" || l === "==") && (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`);
|
|
1673
|
+
n.M !== void 0 && Pe(n.M, d);
|
|
1674
|
+
let t = (e) => this.varMapByName.get(e.name) === e;
|
|
1675
|
+
for (let [e] of s.terms) if (!t(e)) throw Error(`Variable "${e.name}" in constraint "${d}" does not belong to model "${this.name}". All variables must belong to the model by object identity.`);
|
|
1103
1676
|
if (l === "<=" || l === "==") {
|
|
1104
|
-
let t =
|
|
1105
|
-
|
|
1677
|
+
let t = X(e, s, "<=", u, i, n.M === void 0 ? Ie(s, u, f) : n.M, f);
|
|
1678
|
+
m.push([new c(t.lhs, "<=", t.rhs, f), f]);
|
|
1106
1679
|
}
|
|
1107
1680
|
if (l === ">=" || l === "==") {
|
|
1108
|
-
let t =
|
|
1109
|
-
|
|
1681
|
+
let t = X(e, s, ">=", u, i, n.M === void 0 ? Le(s, u, p) : n.M, p);
|
|
1682
|
+
m.push([new c(t.lhs, ">=", t.rhs, p), p]);
|
|
1110
1683
|
}
|
|
1684
|
+
for (let [e, n] of m) h(e, this.name, t, n);
|
|
1685
|
+
} catch (e) {
|
|
1686
|
+
throw o === void 0 ? this.constrPrefixCounters.delete("c") : this.constrPrefixCounters.set("c", o), e;
|
|
1111
1687
|
}
|
|
1112
|
-
return
|
|
1113
|
-
}
|
|
1114
|
-
addIndicator(e, t, n = {}) {
|
|
1115
|
-
return this.indicator(e, t, n);
|
|
1688
|
+
return this.runTransactionalBatch(() => m.map(([e, t]) => this.addConstraint(e, t)));
|
|
1116
1689
|
}
|
|
1117
1690
|
toLpString() {
|
|
1118
|
-
|
|
1691
|
+
this.validateIntegrity();
|
|
1692
|
+
let { lpString: e } = C({
|
|
1119
1693
|
name: this.name,
|
|
1120
1694
|
sense: this.sense,
|
|
1121
|
-
objective: this.
|
|
1695
|
+
objective: this.objectiveExpr,
|
|
1122
1696
|
constraints: this.constraints,
|
|
1123
1697
|
variables: this.variables
|
|
1124
1698
|
});
|
|
1125
1699
|
return e;
|
|
1126
1700
|
}
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1701
|
+
validateIntegrity() {
|
|
1702
|
+
k(this);
|
|
1703
|
+
}
|
|
1704
|
+
ensureExecutionValid(e, t, n) {
|
|
1705
|
+
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.`);
|
|
1706
|
+
if (this.activeOperationId !== t) throw Error(`Stale ${n}() result discarded because a newer solve or check operation was started on model "${this.name}".`);
|
|
1707
|
+
}
|
|
1708
|
+
wrapSolveOptions(e, t, n) {
|
|
1709
|
+
let r = e.onProgress;
|
|
1710
|
+
return r ? {
|
|
1711
|
+
...e,
|
|
1712
|
+
onProgress: (e) => {
|
|
1713
|
+
this.activeOperationId === n && this.modelRevision === t && r(e);
|
|
1714
|
+
}
|
|
1715
|
+
} : e;
|
|
1716
|
+
}
|
|
1717
|
+
hasPrimalFromResult(e) {
|
|
1718
|
+
if (typeof e.hasPrimalSolution == "boolean") return e.hasPrimalSolution;
|
|
1719
|
+
let t = e.status, n = e.terminationStatus ?? t, r = e.values || {}, i = e.boolValues || {};
|
|
1720
|
+
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
|
+
}
|
|
1722
|
+
resolveSolverAndOptions(e, t) {
|
|
1723
|
+
if (e && typeof e == "object" && "solve" in e && typeof e.solve == "function") {
|
|
1724
|
+
let { solver: n, ...r } = t || {};
|
|
1725
|
+
return {
|
|
1726
|
+
activeSolver: e,
|
|
1727
|
+
activeOptions: r
|
|
1728
|
+
};
|
|
1729
|
+
}
|
|
1730
|
+
if (typeof e == "function") {
|
|
1731
|
+
let { solver: n, ...r } = t || {};
|
|
1732
|
+
return {
|
|
1733
|
+
activeSolver: new e(r),
|
|
1734
|
+
activeOptions: r
|
|
1735
|
+
};
|
|
1736
|
+
}
|
|
1737
|
+
if (typeof e == "string") {
|
|
1738
|
+
let { solver: n, ...r } = t || {};
|
|
1739
|
+
return {
|
|
1740
|
+
activeSolver: D(e, r),
|
|
1741
|
+
activeOptions: r
|
|
1742
|
+
};
|
|
1743
|
+
}
|
|
1744
|
+
let { solver: n, ...r } = e || {};
|
|
1745
|
+
return n ? {
|
|
1746
|
+
activeSolver: D(n, r),
|
|
1747
|
+
activeOptions: r
|
|
1748
|
+
} : {
|
|
1749
|
+
activeSolver: this.solver || D(),
|
|
1750
|
+
activeOptions: r
|
|
1751
|
+
};
|
|
1752
|
+
}
|
|
1753
|
+
async solve(e, t) {
|
|
1754
|
+
let n = ++this.activeOperationId, r = this.modelRevision;
|
|
1755
|
+
this.clearSolutionFields(), this.validateIntegrity();
|
|
1756
|
+
let { activeSolver: i, activeOptions: a } = this.resolveSolverAndOptions(e, t);
|
|
1757
|
+
if (this._objectiveExpr instanceof A && 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.`);
|
|
1758
|
+
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.`);
|
|
1759
|
+
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.`);
|
|
1760
|
+
let o = {
|
|
1131
1761
|
name: this.name,
|
|
1132
1762
|
sense: this.sense,
|
|
1133
|
-
objective: this.
|
|
1763
|
+
objective: this._objectiveExpr,
|
|
1134
1764
|
constraints: this.constraints,
|
|
1135
1765
|
variables: this.variables,
|
|
1136
1766
|
logicalConstraints: this.logicalConstraints,
|
|
1137
1767
|
boolVars: this.boolVars
|
|
1138
|
-
},
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1768
|
+
}, s = this.wrapSolveOptions(a, r, n), c;
|
|
1769
|
+
try {
|
|
1770
|
+
c = await i.solve(o, s);
|
|
1771
|
+
} catch (e) {
|
|
1772
|
+
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
1773
|
+
}
|
|
1774
|
+
this.ensureExecutionValid(r, n, "solve"), this.runTime = c.runTime ?? 0, this.status = c.status, this.terminationStatus = c.terminationStatus ?? c.status;
|
|
1775
|
+
let l = this.hasPrimalFromResult(c);
|
|
1776
|
+
this.hasPrimalSolution = l, this.objectiveValue = l && typeof c.objectiveValue == "number" && Number.isFinite(c.objectiveValue) ? c.objectiveValue : null, this.objectiveBound = typeof c.objectiveBound == "number" && Number.isFinite(c.objectiveBound) ? c.objectiveBound : void 0;
|
|
1777
|
+
let u = typeof c.relGap == "number" && Number.isFinite(c.relGap) ? c.relGap : typeof c.mipGap == "number" && Number.isFinite(c.mipGap) ? c.mipGap : void 0;
|
|
1778
|
+
this.relGap = u, this.mipGap = u, this.absGap = typeof c.absGap == "number" && Number.isFinite(c.absGap) ? c.absGap : this.objectiveValue !== null && this.objectiveBound !== void 0 ? Math.abs(this.objectiveValue - this.objectiveBound) : void 0;
|
|
1779
|
+
let d = (e, t, n) => {
|
|
1780
|
+
Object.defineProperty(e, t, {
|
|
1781
|
+
value: n,
|
|
1782
|
+
enumerable: !0,
|
|
1783
|
+
writable: !0,
|
|
1784
|
+
configurable: !0
|
|
1785
|
+
});
|
|
1786
|
+
}, f = {}, p = {}, m = {}, h = {};
|
|
1787
|
+
if (this.values.clear(), l && c.values) {
|
|
1788
|
+
for (let [e, t] of Object.entries(c.values)) if (typeof t == "number" && Number.isFinite(t)) {
|
|
1789
|
+
let n = this.getVarByName(e), r = this.getBoolVarByName(e);
|
|
1790
|
+
n && (n.value = t, d(f, n.name, t), this.values.set(n.name, t)), r && (r.value = !!t, this.values.set(r.name, t)), !n && !r && this.values.set(e, t);
|
|
1791
|
+
} else if (typeof t == "boolean") {
|
|
1792
|
+
let n = t, r = this.getBoolVarByName(e);
|
|
1793
|
+
r ? (r.value = n, d(f, r.name, +!!n), this.values.set(r.name, n)) : this.values.set(e, n);
|
|
1154
1794
|
}
|
|
1155
1795
|
}
|
|
1156
|
-
if (
|
|
1157
|
-
|
|
1158
|
-
|
|
1796
|
+
if (l && c.boolValues) for (let [e, t] of Object.entries(c.boolValues)) {
|
|
1797
|
+
if (typeof t != "boolean") continue;
|
|
1798
|
+
let n = this.getBoolVarByName(e);
|
|
1799
|
+
n ? (n.value = t, this.values.has(n.name) || this.values.set(n.name, t)) : this.values.has(e) || this.values.set(e, t);
|
|
1159
1800
|
}
|
|
1160
|
-
if (
|
|
1161
|
-
|
|
1162
|
-
|
|
1801
|
+
if (l && c.reducedCosts) for (let [e, t] of Object.entries(c.reducedCosts)) {
|
|
1802
|
+
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
1803
|
+
let n = this.getVarByName(e);
|
|
1804
|
+
n && (n.reducedCost = t, d(m, n.name, t));
|
|
1163
1805
|
}
|
|
1164
|
-
if (
|
|
1165
|
-
|
|
1166
|
-
|
|
1806
|
+
if (c.duals) for (let [e, t] of Object.entries(c.duals)) {
|
|
1807
|
+
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
1808
|
+
let n = this.getConstraintByName(e);
|
|
1809
|
+
n && (n.dual = t, d(p, n.name, t));
|
|
1810
|
+
}
|
|
1811
|
+
if (c.slacks) for (let [e, t] of Object.entries(c.slacks)) {
|
|
1812
|
+
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
1813
|
+
let n = this.getConstraintByName(e);
|
|
1814
|
+
n && (n.slack = t, d(h, n.name, t));
|
|
1167
1815
|
}
|
|
1168
1816
|
return this.solution = {
|
|
1169
1817
|
status: this.status,
|
|
1818
|
+
terminationStatus: this.terminationStatus,
|
|
1819
|
+
hasPrimalSolution: this.hasPrimalSolution,
|
|
1170
1820
|
objectiveValue: this.objectiveValue,
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1821
|
+
...this.objectiveBound === void 0 ? {} : { objectiveBound: this.objectiveBound },
|
|
1822
|
+
...this.relGap === void 0 ? {} : {
|
|
1823
|
+
relGap: this.relGap,
|
|
1824
|
+
mipGap: this.mipGap
|
|
1825
|
+
},
|
|
1826
|
+
...this.absGap === void 0 ? {} : { absGap: this.absGap },
|
|
1827
|
+
values: f,
|
|
1828
|
+
duals: p,
|
|
1829
|
+
reducedCosts: m,
|
|
1830
|
+
slacks: h,
|
|
1175
1831
|
runTime: this.runTime,
|
|
1176
|
-
raw:
|
|
1177
|
-
}, this.status;
|
|
1178
|
-
}
|
|
1179
|
-
async solve(e, t) {
|
|
1180
|
-
return this.optimize(e, t);
|
|
1832
|
+
raw: c.raw
|
|
1833
|
+
}, this.hasSolutionState = !0, this.status;
|
|
1181
1834
|
}
|
|
1182
1835
|
async check(e, t) {
|
|
1183
|
-
let n, r;
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1836
|
+
let n = ++this.activeOperationId, r = this.modelRevision;
|
|
1837
|
+
this.clearSolutionFields(), this.validateIntegrity();
|
|
1838
|
+
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
|
+
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
|
+
let o = this.wrapSolveOptions(a, r, n), s = (e, t, n) => {
|
|
1842
|
+
Object.defineProperty(e, t, {
|
|
1843
|
+
value: n,
|
|
1844
|
+
enumerable: !0,
|
|
1845
|
+
writable: !0,
|
|
1846
|
+
configurable: !0
|
|
1847
|
+
});
|
|
1848
|
+
}, c = {
|
|
1849
|
+
name: this.name,
|
|
1850
|
+
variables: this.variables,
|
|
1851
|
+
boolVars: this.boolVars,
|
|
1852
|
+
constraints: this.constraints,
|
|
1853
|
+
logicalConstraints: this.logicalConstraints
|
|
1854
|
+
};
|
|
1855
|
+
if (typeof i.check == "function") {
|
|
1856
|
+
let e;
|
|
1857
|
+
try {
|
|
1858
|
+
e = await i.check(c, o);
|
|
1859
|
+
} catch (e) {
|
|
1860
|
+
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
1202
1861
|
}
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
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]);
|
|
1863
|
+
let t = {};
|
|
1864
|
+
if (e.values && e.status === "Sat") {
|
|
1865
|
+
for (let [n, r] of Object.entries(e.values)) if (typeof r == "number") {
|
|
1866
|
+
if (!Number.isFinite(r)) continue;
|
|
1867
|
+
let e = this.getVarByName(n), i = this.getBoolVarByName(n);
|
|
1868
|
+
e && (e.value = r, this.values.set(e.name, r), s(t, e.name, r)), i && (i.value = !!r, this.values.set(i.name, i.value), s(t, i.name, i.value)), !e && !i && (this.values.set(n, r), s(t, n, r));
|
|
1869
|
+
} else if (typeof r == "boolean") {
|
|
1870
|
+
let e = this.getBoolVarByName(n);
|
|
1871
|
+
e ? (e.value = r, this.values.set(e.name, r), s(t, e.name, r)) : (this.values.set(n, r), s(t, n, r));
|
|
1872
|
+
}
|
|
1212
1873
|
}
|
|
1213
|
-
return {
|
|
1214
|
-
status:
|
|
1215
|
-
values:
|
|
1874
|
+
return this.hasSolutionState = !0, {
|
|
1875
|
+
status: e.status,
|
|
1876
|
+
values: t,
|
|
1877
|
+
unsatCore: this.unsatCore,
|
|
1878
|
+
conflicts: this.unsatCore,
|
|
1216
1879
|
runTime: this.runTime
|
|
1217
1880
|
};
|
|
1218
|
-
} finally {
|
|
1219
|
-
this.objective = i, this.sense = a;
|
|
1220
1881
|
}
|
|
1882
|
+
let l = {
|
|
1883
|
+
name: this.name,
|
|
1884
|
+
sense: "Minimize",
|
|
1885
|
+
objective: new j(),
|
|
1886
|
+
constraints: this.constraints,
|
|
1887
|
+
variables: this.variables,
|
|
1888
|
+
logicalConstraints: this.logicalConstraints,
|
|
1889
|
+
boolVars: this.boolVars
|
|
1890
|
+
}, u;
|
|
1891
|
+
try {
|
|
1892
|
+
u = await i.solve(l, o);
|
|
1893
|
+
} catch (e) {
|
|
1894
|
+
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
1895
|
+
}
|
|
1896
|
+
this.ensureExecutionValid(r, n, "check"), this.runTime = u.runTime ?? 0;
|
|
1897
|
+
let d = u.status, f = u.terminationStatus ?? d, p = this.hasPrimalFromResult(u) || d === "Optimal" || d === "Feasible", m = p ? "Sat" : d === "Infeasible" ? "Unsat" : "Unknown";
|
|
1898
|
+
this.status = m, this.terminationStatus = a.signal?.aborted || f === "Interrupted" ? "Interrupted" : f === "Optimal" || f === "Feasible" || f === "Infeasible" ? m : f, this.hasPrimalSolution = p, this.objectiveValue = null, this.objectiveBound = void 0, this.relGap = void 0, this.mipGap = void 0, this.absGap = void 0, this.solution = null, this.values.clear();
|
|
1899
|
+
let h = {};
|
|
1900
|
+
if (p && u.values) {
|
|
1901
|
+
for (let [e, t] of Object.entries(u.values)) if (typeof t == "number" && Number.isFinite(t)) {
|
|
1902
|
+
let n = this.getVarByName(e), r = this.getBoolVarByName(e);
|
|
1903
|
+
n && (n.value = t, this.values.set(n.name, t), s(h, n.name, t)), r && (r.value = !!t, this.values.set(r.name, r.value), s(h, r.name, r.value)), !n && !r && (this.values.set(e, t), s(h, e, t));
|
|
1904
|
+
} else if (typeof t == "boolean") {
|
|
1905
|
+
let n = t, r = this.getBoolVarByName(e);
|
|
1906
|
+
r ? (r.value = n, this.values.set(r.name, n), s(h, r.name, n)) : (this.values.set(e, n), s(h, e, n));
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
if (p && u.boolValues) for (let [e, t] of Object.entries(u.boolValues)) {
|
|
1910
|
+
if (typeof t != "boolean") continue;
|
|
1911
|
+
let n = this.getBoolVarByName(e);
|
|
1912
|
+
n ? (n.value = t, this.values.set(n.name, t), s(h, n.name, t)) : (this.values.set(e, t), s(h, e, t));
|
|
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);
|
|
1918
|
+
}
|
|
1919
|
+
return this.hasSolutionState = !0, {
|
|
1920
|
+
status: m,
|
|
1921
|
+
values: h,
|
|
1922
|
+
runTime: this.runTime
|
|
1923
|
+
};
|
|
1924
|
+
}
|
|
1925
|
+
validateSolution(e = {}) {
|
|
1926
|
+
return Ne(this, e);
|
|
1221
1927
|
}
|
|
1222
1928
|
};
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1929
|
+
//#endregion
|
|
1930
|
+
//#region src/modeler/objective.ts
|
|
1931
|
+
function ze(e, t) {
|
|
1932
|
+
let n = e;
|
|
1933
|
+
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 model.constraint(expr\`... <= ...\`) for constraints, or supply an unconstrained arithmetic expression to ${t}().`);
|
|
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;
|
|
1938
|
+
}
|
|
1939
|
+
if (typeof n == "string" || n instanceof j || n instanceof A || 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;
|
|
1940
|
+
throw Error(`Invalid expression passed to ${t}(): expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.`);
|
|
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({
|
|
1955
|
+
BoolExpr: () => r,
|
|
1956
|
+
BoolOp: () => n,
|
|
1957
|
+
BoolVar: () => o,
|
|
1227
1958
|
Constraint: () => c,
|
|
1228
|
-
HiGHS: () =>
|
|
1229
|
-
HighsSolver: () =>
|
|
1230
|
-
LinExpr: () =>
|
|
1231
|
-
MockSolver: () =>
|
|
1232
|
-
Model: () =>
|
|
1233
|
-
OFFICIAL_HIGHS_CDN_WASM_URL: () =>
|
|
1234
|
-
QuadExpr: () =>
|
|
1235
|
-
Var: () =>
|
|
1236
|
-
and: () =>
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1959
|
+
HiGHS: () => J,
|
|
1960
|
+
HighsSolver: () => q,
|
|
1961
|
+
LinExpr: () => j,
|
|
1962
|
+
MockSolver: () => ke,
|
|
1963
|
+
Model: () => Re,
|
|
1964
|
+
OFFICIAL_HIGHS_CDN_WASM_URL: () => te,
|
|
1965
|
+
QuadExpr: () => A,
|
|
1966
|
+
Var: () => b,
|
|
1967
|
+
and: () => y,
|
|
1968
|
+
buildIndicatorLinearization: () => X,
|
|
1969
|
+
buildLpSymbolMaps: () => u,
|
|
1970
|
+
deriveBigMForGe: () => Le,
|
|
1971
|
+
deriveBigMForLe: () => Ie,
|
|
1972
|
+
dot: () => s,
|
|
1973
|
+
expr: () => be,
|
|
1974
|
+
generateLpString: () => C,
|
|
1975
|
+
getHighs: () => F,
|
|
1976
|
+
getHighsWasmUrl: () => L,
|
|
1977
|
+
getSolver: () => D,
|
|
1978
|
+
implies: () => e,
|
|
1979
|
+
isLpExportResult: () => E,
|
|
1980
|
+
isValidWasmHeader: () => P,
|
|
1981
|
+
listAvailableSolvers: () => S,
|
|
1982
|
+
mapHighsStatus: () => K,
|
|
1983
|
+
mapHighsTerminationStatus: () => G,
|
|
1984
|
+
maximize: () => Be,
|
|
1985
|
+
minimize: () => Ve,
|
|
1986
|
+
not: () => v,
|
|
1987
|
+
or: () => i,
|
|
1988
|
+
parseConstraint: () => he,
|
|
1989
|
+
parseExpr: () => pe,
|
|
1990
|
+
probeWasmUrl: () => M,
|
|
1991
|
+
registerHighsSolver: () => Y,
|
|
1992
|
+
registerMockSolver: () => Ae,
|
|
1993
|
+
registerSolver: () => T,
|
|
1994
|
+
resolveBrowserWasmUrl: () => I,
|
|
1995
|
+
sanitizeIdentifier: () => f,
|
|
1996
|
+
setDefaultSolver: () => _,
|
|
1997
|
+
setHighsWasmUrl: () => R,
|
|
1998
|
+
solveLp: () => W,
|
|
1999
|
+
solveLpWithHighs: () => N,
|
|
2000
|
+
sum: () => t,
|
|
2001
|
+
validateModelIntegrity: () => k,
|
|
2002
|
+
validateModelSolution: () => Ne,
|
|
2003
|
+
validateUserBigM: () => Pe,
|
|
2004
|
+
xor: () => a
|
|
2005
|
+
}), je);
|
|
1264
2006
|
//#endregion
|
|
1265
|
-
export {
|
|
2007
|
+
export { r as BoolExpr, n as BoolOp, o as BoolVar, c as Constraint, J as HiGHS, q as HighsSolver, j as LinExpr, ke as MockSolver, Re as Model, A as QuadExpr, b as Var, y as and, X as buildIndicatorLinearization, u as buildLpSymbolMaps, Le as deriveBigMForGe, Ie as deriveBigMForLe, s as dot, be as expr, C as generateLpString, F as getHighs, L as getHighsWasmUrl, D as getSolver, e as implies, E as isLpExportResult, S as listAvailableSolvers, Be as maximize, Ve as minimize, le as normalizeSense, v as not, i as or, he as parseConstraint, pe as parseExpr, T as registerSolver, f as sanitizeIdentifier, _ as setDefaultSolver, R as setHighsWasmUrl, N as solveLpWithHighs, t as sum, k as validateModelIntegrity, Ne as validateModelSolution, Pe as validateUserBigM, a as xor };
|