@ohtaman/washi 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +100 -107
- package/README.md +98 -105
- package/README.zh-CN.md +101 -108
- package/dist/browser/highs-worker.js +21 -3
- package/dist/browser/loader-CtaDHef_.js +273 -0
- package/dist/browser/solvers/glpk.js +433 -286
- package/dist/browser/solvers/glpk.min.js +1 -1
- package/dist/browser/solvers/z3.js +1002 -981
- package/dist/browser/solvers/z3.min.js +2 -2
- package/dist/browser/washi.js +2129 -676
- package/dist/browser/washi.min.js +4 -4
- package/dist/lib/highs-worker.js +21 -3
- package/dist/lib/loader-DmNC_UNk.js +279 -0
- package/dist/lib/registry-BEfvpZW3.js +951 -0
- package/dist/lib/solvers/glpk.js +201 -90
- package/dist/lib/solvers/z3.js +399 -259
- package/dist/lib/washi.js +1627 -988
- package/dist/types/index.d.ts +4 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/modeler/big-m.d.ts +75 -0
- package/dist/types/modeler/big-m.d.ts.map +1 -0
- package/dist/types/modeler/boolean-expr.d.ts +103 -14
- package/dist/types/modeler/boolean-expr.d.ts.map +1 -1
- package/dist/types/modeler/constraint.d.ts +36 -9
- package/dist/types/modeler/constraint.d.ts.map +1 -1
- package/dist/types/modeler/expression.d.ts +113 -28
- package/dist/types/modeler/expression.d.ts.map +1 -1
- package/dist/types/modeler/index.d.ts +10 -6
- package/dist/types/modeler/index.d.ts.map +1 -1
- package/dist/types/modeler/lp-writer.d.ts +27 -2
- package/dist/types/modeler/lp-writer.d.ts.map +1 -1
- package/dist/types/modeler/model.d.ts +478 -131
- package/dist/types/modeler/model.d.ts.map +1 -1
- package/dist/types/modeler/objective.d.ts +59 -0
- package/dist/types/modeler/objective.d.ts.map +1 -0
- package/dist/types/modeler/parser.d.ts +34 -10
- package/dist/types/modeler/parser.d.ts.map +1 -1
- package/dist/types/modeler/quad-expr.d.ts +26 -7
- package/dist/types/modeler/quad-expr.d.ts.map +1 -1
- package/dist/types/modeler/solution-validator.d.ts +93 -0
- package/dist/types/modeler/solution-validator.d.ts.map +1 -0
- package/dist/types/modeler/solvers/glpk/solver.d.ts +26 -2
- package/dist/types/modeler/solvers/glpk/solver.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/loader.d.ts +36 -11
- package/dist/types/modeler/solvers/highs/loader.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/solver.d.ts +11 -4
- package/dist/types/modeler/solvers/highs/solver.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/worker-client.d.ts.map +1 -1
- package/dist/types/modeler/solvers/mock.d.ts +14 -5
- package/dist/types/modeler/solvers/mock.d.ts.map +1 -1
- package/dist/types/modeler/solvers/types.d.ts +71 -11
- package/dist/types/modeler/solvers/types.d.ts.map +1 -1
- package/dist/types/modeler/solvers/z3/loader.d.ts +2 -3
- package/dist/types/modeler/solvers/z3/loader.d.ts.map +1 -1
- package/dist/types/modeler/solvers/z3/solver.d.ts +15 -5
- package/dist/types/modeler/solvers/z3/solver.d.ts.map +1 -1
- package/dist/types/modeler/types.d.ts +59 -1
- package/dist/types/modeler/types.d.ts.map +1 -1
- package/dist/types/modeler/validation.d.ts +56 -0
- package/dist/types/modeler/validation.d.ts.map +1 -0
- package/dist/types/modeler/variable.d.ts +48 -14
- package/dist/types/modeler/variable.d.ts.map +1 -1
- package/docs/examples/diet-sensitivity.md +90 -0
- package/docs/examples/ecommerce-coupons.md +106 -0
- package/docs/examples/index.md +53 -0
- package/docs/examples/knapsack.md +60 -0
- package/docs/examples/portfolio-qp.md +83 -0
- package/docs/examples/production.md +51 -0
- package/docs/examples/shift-scheduling.md +175 -0
- package/docs/examples/smt-security.md +74 -0
- package/docs/examples/transportation.md +90 -0
- package/docs/examples/unsat-core.md +64 -0
- package/docs/getting-started/ai-agents.md +267 -0
- package/docs/getting-started/cross-origin.md +87 -0
- package/docs/getting-started/index.md +116 -0
- package/docs/getting-started/runtimes.md +227 -0
- package/docs/guide/constraints.md +177 -0
- package/docs/guide/expressions.md +204 -0
- package/docs/guide/objectives.md +170 -0
- package/docs/guide/unsat-core.md +147 -0
- package/docs/guide/variables.md +188 -0
- package/docs/ja/getting-started/ai-agents.md +266 -0
- package/docs/solvers/custom-solver.md +525 -0
- package/docs/solvers/glpk.md +66 -0
- package/docs/solvers/highs.md +93 -0
- package/docs/solvers/index.md +42 -0
- package/docs/solvers/z3.md +78 -0
- package/docs/zh/getting-started/ai-agents.md +266 -0
- package/llms-full.txt +3249 -0
- package/llms.txt +197 -0
- package/package.json +18 -5
- package/skills/washi/SKILL.md +197 -0
- package/dist/browser/loader-CVt4CloI.js +0 -58
- package/dist/lib/async-mutex-Duo4jwzn.js +0 -195
- package/dist/lib/constraint-BRuB3ooC.js +0 -90
- package/dist/lib/loader-Dti0v9yC.js +0 -50
- package/dist/lib/registry-DksqCSjI.js +0 -32
package/dist/lib/washi.js
CHANGED
|
@@ -1,531 +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
|
-
if (typeof t == "number") {
|
|
80
|
-
let n = new e(/* @__PURE__ */ new Map(), /* @__PURE__ */ new Map(), this.constant * t);
|
|
81
|
-
for (let [e, r] of this.linearTerms) {
|
|
82
|
-
let i = r * t;
|
|
83
|
-
Math.abs(i) >= 1e-12 && n.linearTerms.set(e, i);
|
|
84
|
-
}
|
|
85
|
-
for (let [e, r] of this.quadTerms) {
|
|
86
|
-
let i = r.coeff * t;
|
|
87
|
-
Math.abs(i) >= 1e-12 && n.quadTerms.set(e, {
|
|
88
|
-
var1: r.var1,
|
|
89
|
-
var2: r.var2,
|
|
90
|
-
coeff: i
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
return n;
|
|
94
|
-
}
|
|
95
|
-
if ("id" in t && "name" in t && !("terms" in t) && !("quadTerms" in t)) {
|
|
96
|
-
if (this.quadTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
97
|
-
let n = new e();
|
|
98
|
-
Math.abs(this.constant) >= 1e-12 && n.linearTerms.set(t, this.constant);
|
|
99
|
-
for (let [r, i] of this.linearTerms) n = n.add(e.fromProduct(r, t, i));
|
|
100
|
-
return n;
|
|
101
|
-
}
|
|
102
|
-
let n = t, r = "quadTerms" in n ? n.quadTerms.size : 0, i = "quadTerms" in n ? n.linearTerms : n.terms;
|
|
103
|
-
if (this.quadTerms.size > 0 && (r > 0 || i.size > 0) || r > 0 && this.linearTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
104
|
-
if (r === 0 && i.size === 0) return this.mul(n.constant);
|
|
105
|
-
if (this.quadTerms.size === 0 && this.linearTerms.size === 0) {
|
|
106
|
-
let t = n.mul(this.constant);
|
|
107
|
-
if (t instanceof e) return t;
|
|
108
|
-
let r = new e();
|
|
109
|
-
r.constant = t.constant;
|
|
110
|
-
for (let [e, n] of t.terms) r.linearTerms.set(e, n);
|
|
111
|
-
return r;
|
|
112
|
-
}
|
|
113
|
-
let a = new e();
|
|
114
|
-
if (a.constant = this.constant * n.constant, Math.abs(n.constant) >= 1e-12) for (let [e, t] of this.linearTerms) a.linearTerms.set(e, (a.linearTerms.get(e) || 0) + t * n.constant);
|
|
115
|
-
if (Math.abs(this.constant) >= 1e-12) for (let [e, t] of i) a.linearTerms.set(e, (a.linearTerms.get(e) || 0) + t * this.constant);
|
|
116
|
-
for (let [t, n] of this.linearTerms) for (let [r, o] of i) a = a.add(e.fromProduct(t, r, n * o));
|
|
117
|
-
return a;
|
|
118
|
-
}
|
|
119
|
-
div(e) {
|
|
120
|
-
if (Math.abs(e) < 1e-12) throw Error("Division by zero in QuadExpr.div()");
|
|
121
|
-
return this.mul(1 / e);
|
|
122
|
-
}
|
|
123
|
-
neg() {
|
|
124
|
-
return this.mul(-1);
|
|
125
|
-
}
|
|
126
|
-
get value() {
|
|
127
|
-
let e = this.constant;
|
|
128
|
-
for (let [t, n] of this.linearTerms) {
|
|
129
|
-
if (t.value === null) return null;
|
|
130
|
-
e += n * t.value;
|
|
131
|
-
}
|
|
132
|
-
for (let t of this.quadTerms.values()) {
|
|
133
|
-
if (t.var1.value === null || t.var2.value === null) return null;
|
|
134
|
-
e += t.coeff * t.var1.value * t.var2.value;
|
|
135
|
-
}
|
|
136
|
-
return e;
|
|
137
|
-
}
|
|
138
|
-
getValue() {
|
|
139
|
-
return this.value;
|
|
140
|
-
}
|
|
141
|
-
toString() {
|
|
142
|
-
let e = [], t = !0;
|
|
143
|
-
for (let n of this.quadTerms.values()) {
|
|
144
|
-
let r = n.coeff, i = r >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(r), o = a === 1 ? "" : `${a} `;
|
|
145
|
-
n.var1 === n.var2 ? e.push(`${i}${o}${n.var1.name}^2`) : e.push(`${i}${o}${n.var1.name} * ${n.var2.name}`), t = !1;
|
|
146
|
-
}
|
|
147
|
-
for (let [n, r] of this.linearTerms) {
|
|
148
|
-
let i = r >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(r), o = a === 1 ? "" : `${a} `;
|
|
149
|
-
e.push(`${i}${o}${n.name}`), t = !1;
|
|
150
|
-
}
|
|
151
|
-
if (this.constant !== 0 || e.length === 0) {
|
|
152
|
-
let n = this.constant >= 0 ? t ? "" : "+ " : "- ";
|
|
153
|
-
e.push(`${n}${Math.abs(this.constant)}`);
|
|
154
|
-
}
|
|
155
|
-
return e.join(" ") || "0";
|
|
156
|
-
}
|
|
157
|
-
static fromProduct(t, n, r = 1) {
|
|
158
|
-
let i = new e(), a = E(t, n);
|
|
159
|
-
return i.quadTerms.set(a, {
|
|
160
|
-
var1: t.id <= n.id ? t : n,
|
|
161
|
-
var2: t.id <= n.id ? n : t,
|
|
162
|
-
coeff: r
|
|
163
|
-
}), i;
|
|
164
|
-
}
|
|
165
|
-
}, O = class e {
|
|
166
|
-
terms;
|
|
167
|
-
constant;
|
|
168
|
-
constructor(e = /* @__PURE__ */ new Map(), t = 0) {
|
|
169
|
-
this.terms = new Map(e), this.constant = t;
|
|
170
|
-
}
|
|
171
|
-
clone() {
|
|
172
|
-
return new e(this.terms, this.constant);
|
|
173
|
-
}
|
|
174
|
-
add(e) {
|
|
175
|
-
if (e instanceof D) return e.add(this);
|
|
176
|
-
let t = this.clone();
|
|
177
|
-
if (typeof e == "number") t.constant += e;
|
|
178
|
-
else if ("terms" in e) {
|
|
179
|
-
for (let [n, r] of e.terms) {
|
|
180
|
-
let e = (t.terms.get(n) || 0) + r;
|
|
181
|
-
Math.abs(e) < 1e-12 ? t.terms.delete(n) : t.terms.set(n, e);
|
|
182
|
-
}
|
|
183
|
-
t.constant += e.constant;
|
|
184
|
-
} else {
|
|
185
|
-
let n = (t.terms.get(e) || 0) + 1;
|
|
186
|
-
Math.abs(n) < 1e-12 ? t.terms.delete(e) : t.terms.set(e, n);
|
|
187
|
-
}
|
|
188
|
-
return t;
|
|
189
|
-
}
|
|
190
|
-
sub(e) {
|
|
191
|
-
return e instanceof D ? e.neg().add(this) : typeof e == "number" ? this.add(-e) : ("terms" in e, this.add(e.mul(-1)));
|
|
192
|
-
}
|
|
193
|
-
mul(t) {
|
|
194
|
-
if (typeof t == "number") {
|
|
195
|
-
let n = new e(/* @__PURE__ */ new Map(), this.constant * t);
|
|
196
|
-
for (let [e, r] of this.terms) {
|
|
197
|
-
let i = r * t;
|
|
198
|
-
Math.abs(i) >= 1e-12 && n.terms.set(e, i);
|
|
199
|
-
}
|
|
200
|
-
return n;
|
|
201
|
-
}
|
|
202
|
-
if (t instanceof M || typeof t == "object" && t && "id" in t && !("terms" in t) && !("quadTerms" in t)) {
|
|
203
|
-
let e = t, n = new D();
|
|
204
|
-
Math.abs(this.constant) >= 1e-12 && n.linearTerms.set(e, this.constant);
|
|
205
|
-
for (let [t, r] of this.terms) n = n.add(D.fromProduct(t, e, r));
|
|
206
|
-
return n;
|
|
207
|
-
}
|
|
208
|
-
if (t instanceof D) {
|
|
209
|
-
if (t.quadTerms.size > 0 && this.terms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
210
|
-
if (this.terms.size === 0) return t.mul(this.constant);
|
|
211
|
-
let e = new D();
|
|
212
|
-
if (e.constant = this.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [n, r] of this.terms) e.linearTerms.set(n, (e.linearTerms.get(n) || 0) + r * t.constant);
|
|
213
|
-
if (Math.abs(this.constant) >= 1e-12) for (let [n, r] of t.linearTerms) e.linearTerms.set(n, (e.linearTerms.get(n) || 0) + r * this.constant);
|
|
214
|
-
for (let [n, r] of this.terms) for (let [i, a] of t.linearTerms) e = e.add(D.fromProduct(n, i, r * a));
|
|
215
|
-
return e;
|
|
216
|
-
}
|
|
217
|
-
if (this.terms.size === 0) return t.mul(this.constant);
|
|
218
|
-
if (t.terms.size === 0) return this.mul(t.constant);
|
|
219
|
-
let n = new D();
|
|
220
|
-
if (n.constant = this.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [e, r] of this.terms) n.linearTerms.set(e, (n.linearTerms.get(e) || 0) + r * t.constant);
|
|
221
|
-
if (Math.abs(this.constant) >= 1e-12) for (let [e, r] of t.terms) n.linearTerms.set(e, (n.linearTerms.get(e) || 0) + r * this.constant);
|
|
222
|
-
for (let [e, r] of this.terms) for (let [i, a] of t.terms) n = n.add(D.fromProduct(e, i, r * a));
|
|
223
|
-
return n;
|
|
224
|
-
}
|
|
225
|
-
div(e) {
|
|
226
|
-
if (Math.abs(e) < 1e-12) throw Error("Division by zero in LinExpr.div()");
|
|
227
|
-
return this.mul(1 / e);
|
|
228
|
-
}
|
|
229
|
-
neg() {
|
|
230
|
-
return this.mul(-1);
|
|
231
|
-
}
|
|
232
|
-
get value() {
|
|
233
|
-
let e = this.constant;
|
|
234
|
-
for (let [t, n] of this.terms) {
|
|
235
|
-
if (t.value === null) return null;
|
|
236
|
-
e += n * t.value;
|
|
237
|
-
}
|
|
238
|
-
return e;
|
|
239
|
-
}
|
|
240
|
-
getValue() {
|
|
241
|
-
return this.value;
|
|
242
|
-
}
|
|
243
|
-
le(e, t) {
|
|
244
|
-
return this.toConstraint("<=", e, t);
|
|
245
|
-
}
|
|
246
|
-
lessThanOrEqual(e, t) {
|
|
247
|
-
return this.le(e, t);
|
|
248
|
-
}
|
|
249
|
-
ge(e, t) {
|
|
250
|
-
return this.toConstraint(">=", e, t);
|
|
251
|
-
}
|
|
252
|
-
greaterThanOrEqual(e, t) {
|
|
253
|
-
return this.ge(e, t);
|
|
254
|
-
}
|
|
255
|
-
eq(e, t) {
|
|
256
|
-
return this.toConstraint("==", e, t);
|
|
257
|
-
}
|
|
258
|
-
equalTo(e, t) {
|
|
259
|
-
return this.eq(e, t);
|
|
260
|
-
}
|
|
261
|
-
toConstraint(t, n, r) {
|
|
262
|
-
let i = this.clone(), a = 0;
|
|
263
|
-
typeof n == "number" ? a = n : "terms" in n ? (i = i.sub(new e(n.terms, 0)), a = n.constant) : i = i.sub(n);
|
|
264
|
-
let o = a - i.constant;
|
|
265
|
-
return i.constant = 0, new c(i, t, o, r);
|
|
266
|
-
}
|
|
267
|
-
toString() {
|
|
268
|
-
let e = [], t = !0;
|
|
269
|
-
for (let [n, r] of this.terms) {
|
|
270
|
-
let i = r >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(r), o = a === 1 ? "" : `${a} `;
|
|
271
|
-
e.push(`${i}${o}${n.name}`), t = !1;
|
|
272
|
-
}
|
|
273
|
-
if (this.constant !== 0 || e.length === 0) {
|
|
274
|
-
let n = this.constant >= 0 ? t ? "" : "+ " : "- ";
|
|
275
|
-
e.push(`${n}${Math.abs(this.constant)}`);
|
|
276
|
-
}
|
|
277
|
-
return e.join(" ") || "0";
|
|
278
|
-
}
|
|
279
|
-
};
|
|
280
|
-
function k(e, t) {
|
|
281
|
-
let n = /* @__PURE__ */ new Map(), r = 0;
|
|
282
|
-
function i(e) {
|
|
283
|
-
if (e != null) {
|
|
284
|
-
if (typeof e == "number") r += e;
|
|
285
|
-
else if (typeof e == "object" && "terms" in e) {
|
|
286
|
-
let t = e;
|
|
287
|
-
for (let [e, r] of t.terms) {
|
|
288
|
-
let t = n.get(e) || 0;
|
|
289
|
-
n.set(e, t + r);
|
|
290
|
-
}
|
|
291
|
-
r += t.constant;
|
|
292
|
-
} else {
|
|
293
|
-
let t = e, r = n.get(t) || 0;
|
|
294
|
-
n.set(t, r + 1);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
if (typeof e == "number") {
|
|
299
|
-
let n = e, r = t;
|
|
300
|
-
for (let e = 0; e < n; e++) i(r(e, e));
|
|
301
|
-
} else {
|
|
302
|
-
let n = 0;
|
|
303
|
-
for (let r of e) i(t ? t(r, n++) : r);
|
|
304
|
-
}
|
|
305
|
-
for (let [e, t] of n) Math.abs(t) < 1e-12 && n.delete(e);
|
|
306
|
-
return new O(n, r);
|
|
307
|
-
}
|
|
308
|
-
function A(e, t) {
|
|
309
|
-
let n = /* @__PURE__ */ new Map(), r = 0;
|
|
310
|
-
function i(e) {
|
|
311
|
-
return typeof e == "object" && !!e && typeof e.id == "number" && typeof e.name == "string" && typeof e.mul == "function" && typeof e.le == "function";
|
|
312
|
-
}
|
|
313
|
-
function a(e) {
|
|
314
|
-
return i(e) || e instanceof O || e instanceof D;
|
|
315
|
-
}
|
|
316
|
-
function o(e, t) {
|
|
317
|
-
if (typeof t == "number") r += e * t;
|
|
318
|
-
else if (t instanceof O) {
|
|
319
|
-
for (let [r, i] of t.terms) {
|
|
320
|
-
let t = n.get(r) || 0;
|
|
321
|
-
n.set(r, t + e * i);
|
|
322
|
-
}
|
|
323
|
-
r += e * t.constant;
|
|
324
|
-
} else if (i(t)) {
|
|
325
|
-
let r = t, i = n.get(r) || 0;
|
|
326
|
-
n.set(r, i + e);
|
|
327
|
-
} else throw Error("Cannot multiply number by non-variable/expression operand in dot().");
|
|
328
|
-
}
|
|
329
|
-
function s(e) {
|
|
330
|
-
return typeof e == "object" && !!e && !Array.isArray(e) && !a(e);
|
|
331
|
-
}
|
|
332
|
-
function c(e, t, n = "") {
|
|
333
|
-
if (e === void 0 || t === void 0 || e === null || t === null) throw Error(`Nullish or undefined operand encountered in dot() at '${n || "root"}'.`);
|
|
334
|
-
if (typeof e == "number") {
|
|
335
|
-
o(e, t);
|
|
336
|
-
return;
|
|
337
|
-
}
|
|
338
|
-
if (typeof t == "number") {
|
|
339
|
-
o(t, e);
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
if (Array.isArray(e) || Array.isArray(t)) {
|
|
343
|
-
if (Array.isArray(e) && Array.isArray(t)) {
|
|
344
|
-
if (e.length !== t.length) throw Error(`Array length mismatch in dot() at '${n || "root"}': received lengths ${e.length} and ${t.length}.`);
|
|
345
|
-
for (let r = 0; r < e.length; r++) c(e[r], t[r], n ? `${n}[${r}]` : `[${r}]`);
|
|
346
|
-
return;
|
|
347
|
-
}
|
|
348
|
-
let r = Array.isArray(e) ? e : t, i = Array.isArray(e) ? t : e;
|
|
349
|
-
if (s(i)) {
|
|
350
|
-
let a = Object.keys(i);
|
|
351
|
-
if (a.length > 0 && a.every((e) => /^\d+$/.test(e))) {
|
|
352
|
-
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.`);
|
|
353
|
-
let o = [];
|
|
354
|
-
for (let e = 0; e < r.length; e++) !(e in i) && !(String(e) in i) && o.push(e);
|
|
355
|
-
if (o.length > 0) throw Error(`Key mismatch in dot() at '${n || "root"}': missing indices [${o.join(", ")}] in numeric record.`);
|
|
356
|
-
for (let i = 0; i < r.length; i++) c(e[i], t[i], n ? `${n}[${i}]` : `[${i}]`);
|
|
357
|
-
return;
|
|
358
|
-
}
|
|
359
|
-
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(", ")}].`);
|
|
360
|
-
}
|
|
361
|
-
throw Error(`Type mismatch in dot() at '${n || "root"}': one operand is an Array while the other is not.`);
|
|
362
|
-
}
|
|
363
|
-
if (s(e) && s(t)) {
|
|
364
|
-
let r = Object.keys(e), i = Object.keys(t), a = r.filter((e) => !(e in t)), o = i.filter((t) => !(t in e));
|
|
365
|
-
if (a.length > 0 || o.length > 0) {
|
|
366
|
-
let e = [];
|
|
367
|
-
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("; ")}.`);
|
|
368
|
-
}
|
|
369
|
-
for (let i of r) c(e[i], t[i], n ? `${n}.${i}` : i);
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
throw Error(`Unsupported operand types in dot() at '${n || "root"}'.`);
|
|
373
|
-
}
|
|
374
|
-
c(e, t);
|
|
375
|
-
for (let [e, t] of n) Math.abs(t) < 1e-12 && n.delete(e);
|
|
376
|
-
return new O(n, r);
|
|
377
|
-
}
|
|
378
|
-
//#endregion
|
|
379
|
-
//#region src/modeler/variable.ts
|
|
380
|
-
var j = 0;
|
|
381
|
-
function ie(e) {
|
|
382
|
-
if (!e) return "Continuous";
|
|
383
|
-
let t = e.toLowerCase();
|
|
384
|
-
return t === "binary" || t === "bin" ? "Binary" : t === "integer" || t === "int" ? "Integer" : "Continuous";
|
|
385
|
-
}
|
|
386
|
-
var M = class e {
|
|
387
|
-
id;
|
|
388
|
-
name;
|
|
389
|
-
type;
|
|
390
|
-
lb;
|
|
391
|
-
ub;
|
|
392
|
-
value = null;
|
|
393
|
-
reducedCost = null;
|
|
394
|
-
constructor(e = {}) {
|
|
395
|
-
this.id = ++j, this.name = e.name || `x_${this.id}`, this.type = ie(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);
|
|
396
|
-
}
|
|
397
|
-
mul(t) {
|
|
398
|
-
if (typeof t == "number") return new O(/* @__PURE__ */ new Map([[this, t]]), 0);
|
|
399
|
-
if (t instanceof e) return D.fromProduct(this, t, 1);
|
|
400
|
-
if (t instanceof D) {
|
|
401
|
-
if (t.quadTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
402
|
-
let e = new D();
|
|
403
|
-
Math.abs(t.constant) >= 1e-12 && e.linearTerms.set(this, t.constant);
|
|
404
|
-
for (let [n, r] of t.linearTerms) e = e.add(D.fromProduct(this, n, r));
|
|
405
|
-
return e;
|
|
406
|
-
}
|
|
407
|
-
let n = new D();
|
|
408
|
-
Math.abs(t.constant) >= 1e-12 && n.linearTerms.set(this, t.constant);
|
|
409
|
-
for (let [e, r] of t.terms) {
|
|
410
|
-
let t = D.fromProduct(this, e, r);
|
|
411
|
-
n = n.add(t);
|
|
412
|
-
}
|
|
413
|
-
return n;
|
|
414
|
-
}
|
|
415
|
-
add(e) {
|
|
416
|
-
return e instanceof D ? e.add(this) : new O(/* @__PURE__ */ new Map([[this, 1]]), 0).add(e);
|
|
417
|
-
}
|
|
418
|
-
sub(e) {
|
|
419
|
-
return e instanceof D ? e.neg().add(this) : new O(/* @__PURE__ */ new Map([[this, 1]]), 0).sub(e);
|
|
420
|
-
}
|
|
421
|
-
neg() {
|
|
422
|
-
return this.mul(-1);
|
|
423
|
-
}
|
|
424
|
-
le(e, t) {
|
|
425
|
-
return new O(/* @__PURE__ */ new Map([[this, 1]]), 0).le(e, t);
|
|
426
|
-
}
|
|
427
|
-
lessThanOrEqual(e, t) {
|
|
428
|
-
return this.le(e, t);
|
|
429
|
-
}
|
|
430
|
-
ge(e, t) {
|
|
431
|
-
return new O(/* @__PURE__ */ new Map([[this, 1]]), 0).ge(e, t);
|
|
432
|
-
}
|
|
433
|
-
greaterThanOrEqual(e, t) {
|
|
434
|
-
return this.ge(e, t);
|
|
435
|
-
}
|
|
436
|
-
eq(e, t) {
|
|
437
|
-
return new O(/* @__PURE__ */ new Map([[this, 1]]), 0).eq(e, t);
|
|
438
|
-
}
|
|
439
|
-
equalTo(e, t) {
|
|
440
|
-
return this.eq(e, t);
|
|
441
|
-
}
|
|
442
|
-
toString() {
|
|
443
|
-
return this.name;
|
|
444
|
-
}
|
|
445
|
-
};
|
|
446
|
-
//#endregion
|
|
447
31
|
//#region src/modeler/parser.ts
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
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++;
|
|
454
39
|
continue;
|
|
455
40
|
}
|
|
456
|
-
if (
|
|
41
|
+
if (a === "+") n.push({
|
|
457
42
|
type: "PLUS",
|
|
458
43
|
value: "+"
|
|
459
|
-
}),
|
|
460
|
-
else if (
|
|
44
|
+
}), r++;
|
|
45
|
+
else if (a === "-") n.push({
|
|
461
46
|
type: "MINUS",
|
|
462
47
|
value: "-"
|
|
463
|
-
}),
|
|
464
|
-
else if (
|
|
48
|
+
}), r++;
|
|
49
|
+
else if (a === "*") r + 1 < i && e[r + 1] === "*" ? (n.push({
|
|
465
50
|
type: "CARET",
|
|
466
51
|
value: "**"
|
|
467
|
-
}),
|
|
52
|
+
}), r += 2) : (n.push({
|
|
468
53
|
type: "STAR",
|
|
469
54
|
value: "*"
|
|
470
|
-
}),
|
|
471
|
-
else if (
|
|
55
|
+
}), r++);
|
|
56
|
+
else if (a === "^") n.push({
|
|
472
57
|
type: "CARET",
|
|
473
58
|
value: "^"
|
|
474
|
-
}),
|
|
475
|
-
else if (
|
|
59
|
+
}), r++;
|
|
60
|
+
else if (a === "/") n.push({
|
|
476
61
|
type: "SLASH",
|
|
477
62
|
value: "/"
|
|
478
|
-
}),
|
|
479
|
-
else if (
|
|
63
|
+
}), r++;
|
|
64
|
+
else if (a === "(") n.push({
|
|
480
65
|
type: "LPAREN",
|
|
481
66
|
value: "("
|
|
482
|
-
}),
|
|
483
|
-
else if (
|
|
67
|
+
}), r++;
|
|
68
|
+
else if (a === ")") n.push({
|
|
484
69
|
type: "RPAREN",
|
|
485
70
|
value: ")"
|
|
486
|
-
}),
|
|
487
|
-
else if (
|
|
488
|
-
let
|
|
489
|
-
|
|
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({
|
|
490
75
|
type: "COMP",
|
|
491
|
-
value:
|
|
76
|
+
value: t
|
|
492
77
|
});
|
|
493
|
-
} else if (/[0-9.]/.test(
|
|
494
|
-
let
|
|
495
|
-
for (;
|
|
496
|
-
|
|
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({
|
|
497
94
|
type: "NUMBER",
|
|
498
|
-
value:
|
|
95
|
+
value: a,
|
|
96
|
+
numericValue: o
|
|
499
97
|
});
|
|
500
|
-
} else if (/[a-zA-Z_]/.test(
|
|
501
|
-
let
|
|
502
|
-
for (;
|
|
503
|
-
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({
|
|
504
109
|
type: "IDENT",
|
|
505
|
-
value:
|
|
110
|
+
value: a
|
|
506
111
|
});
|
|
507
|
-
} else throw Error(`Unexpected character '${
|
|
112
|
+
} else throw Error(`Unexpected character '${a}' at position ${r} in: "${e}"`);
|
|
508
113
|
}
|
|
509
|
-
return
|
|
114
|
+
return n;
|
|
510
115
|
}
|
|
511
|
-
|
|
512
|
-
return e instanceof D ? e.add(t) : t instanceof D ? t.add(e) : e.add(t);
|
|
513
|
-
}
|
|
514
|
-
function se(e, t) {
|
|
515
|
-
return e instanceof D ? e.sub(t) : t instanceof D ? t.neg().add(e) : e.sub(t);
|
|
516
|
-
}
|
|
517
|
-
function N(e, t) {
|
|
518
|
-
let n = e instanceof D ? e.quadTerms : /* @__PURE__ */ new Map(), r = t instanceof D ? t.quadTerms : /* @__PURE__ */ new Map(), i = e instanceof D ? e.linearTerms : e.terms, a = t instanceof D ? t.linearTerms : t.terms;
|
|
519
|
-
if (n.size > 0 && (r.size > 0 || a.size > 0) || r.size > 0 && (n.size > 0 || i.size > 0)) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
520
|
-
if (n.size === 0 && i.size === 0) return t.mul(e.constant);
|
|
521
|
-
if (r.size === 0 && a.size === 0) return e.mul(t.constant);
|
|
522
|
-
let o = new D();
|
|
523
|
-
if (o.constant = e.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [e, n] of i) o.linearTerms.set(e, (o.linearTerms.get(e) || 0) + n * t.constant);
|
|
524
|
-
if (Math.abs(e.constant) >= 1e-12) for (let [t, n] of a) o.linearTerms.set(t, (o.linearTerms.get(t) || 0) + n * e.constant);
|
|
525
|
-
for (let [e, t] of i) for (let [n, r] of a) o = o.add(D.fromProduct(e, n, t * r));
|
|
526
|
-
return o;
|
|
527
|
-
}
|
|
528
|
-
var ce = class {
|
|
116
|
+
var fe = class {
|
|
529
117
|
tokens;
|
|
530
118
|
pos = 0;
|
|
531
119
|
resolver;
|
|
@@ -546,28 +134,20 @@ var ce = class {
|
|
|
546
134
|
for (; this.pos < this.tokens.length;) {
|
|
547
135
|
let t = this.peek();
|
|
548
136
|
if (!t) break;
|
|
549
|
-
if (t.type === "PLUS") this.consume(), e =
|
|
550
|
-
else if (t.type === "MINUS") this.consume(), e =
|
|
137
|
+
if (t.type === "PLUS") this.consume(), e = e.add(this.parseTerm());
|
|
138
|
+
else if (t.type === "MINUS") this.consume(), e = e.sub(this.parseTerm());
|
|
551
139
|
else break;
|
|
552
140
|
}
|
|
553
|
-
return e instanceof
|
|
141
|
+
return e instanceof A && e.quadTerms.size === 0 ? new j(e.linearTerms, e.constant) : e;
|
|
554
142
|
}
|
|
555
143
|
parseTerm() {
|
|
556
144
|
let e = this.parseFactor();
|
|
557
145
|
for (; this.pos < this.tokens.length;) {
|
|
558
146
|
let t = this.peek();
|
|
559
147
|
if (!t) break;
|
|
560
|
-
if (t.type === "STAR")
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
e = N(e, t);
|
|
564
|
-
} else if (t.type === "SLASH") {
|
|
565
|
-
this.consume();
|
|
566
|
-
let t = this.parseFactor(), n = t instanceof D ? t.linearTerms : t.terms, r = t instanceof D ? t.quadTerms.size : 0;
|
|
567
|
-
if (n.size > 0 || r > 0) throw Error("Cannot divide by variable in expression");
|
|
568
|
-
if (Math.abs(t.constant) < 1e-12) throw Error("Division by zero in expression");
|
|
569
|
-
e = e.div(t.constant);
|
|
570
|
-
} 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;
|
|
571
151
|
}
|
|
572
152
|
return e;
|
|
573
153
|
}
|
|
@@ -579,20 +159,20 @@ var ce = class {
|
|
|
579
159
|
let t;
|
|
580
160
|
if (e.type === "NUMBER") {
|
|
581
161
|
this.consume();
|
|
582
|
-
let n =
|
|
162
|
+
let n = e.numericValue ?? Number(e.value);
|
|
583
163
|
if (this.peek()?.type === "IDENT" || this.peek()?.type === "LPAREN") {
|
|
584
164
|
let e;
|
|
585
165
|
if (this.peek()?.type === "IDENT") {
|
|
586
166
|
let t = this.consume(), n = this.resolve(t.value);
|
|
587
|
-
e = n instanceof
|
|
167
|
+
e = n instanceof b || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new j(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
|
|
588
168
|
} else this.consume("LPAREN"), e = this.parseExpression(), this.consume("RPAREN");
|
|
589
169
|
return this.applyPower(e).mul(n);
|
|
590
170
|
}
|
|
591
|
-
t = new
|
|
171
|
+
t = new j(/* @__PURE__ */ new Map(), n);
|
|
592
172
|
} else if (e.type === "IDENT") {
|
|
593
173
|
this.consume();
|
|
594
174
|
let n = this.resolve(e.value);
|
|
595
|
-
t = n instanceof
|
|
175
|
+
t = n instanceof b || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new j(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
|
|
596
176
|
} else if (e.type === "LPAREN") this.consume("LPAREN"), t = this.parseExpression(), this.consume("RPAREN");
|
|
597
177
|
else throw Error(`Unexpected token '${e.value}' in expression`);
|
|
598
178
|
return this.applyPower(t);
|
|
@@ -602,24 +182,27 @@ var ce = class {
|
|
|
602
182
|
let t = [];
|
|
603
183
|
for (; this.peek()?.type === "CARET";) {
|
|
604
184
|
this.consume();
|
|
605
|
-
let e = this.
|
|
606
|
-
|
|
607
|
-
this.
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
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);
|
|
611
193
|
}
|
|
612
194
|
let n = t[t.length - 1];
|
|
613
195
|
for (let e = t.length - 2; e >= 0; e--) n = t[e] ** +n;
|
|
614
196
|
if (!Number.isFinite(n) || n < 0) throw Error("Exponent creates an invalid or out-of-range power");
|
|
615
|
-
let r = e instanceof
|
|
197
|
+
let r = e instanceof A, i = r ? e.quadTerms.size : 0, a = r ? e.linearTerms.size : e.terms.size;
|
|
616
198
|
if (i === 0 && a === 0) {
|
|
617
199
|
let t = e.constant ** +n;
|
|
618
|
-
|
|
200
|
+
if (e.constant !== 0 && n > 0 && t === 0) throw Error("Constant exponentiation underflows to zero.");
|
|
201
|
+
return new j(/* @__PURE__ */ new Map(), t);
|
|
619
202
|
}
|
|
620
|
-
if (n === 0) return new
|
|
203
|
+
if (n === 0) return new j(/* @__PURE__ */ new Map(), 1);
|
|
621
204
|
if (n === 1) return e;
|
|
622
|
-
if (n === 2) return
|
|
205
|
+
if (n === 2) return e.mul(e);
|
|
623
206
|
throw Error(`Exponent ${n} creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)`);
|
|
624
207
|
}
|
|
625
208
|
getRemainingToken() {
|
|
@@ -631,143 +214,170 @@ var ce = class {
|
|
|
631
214
|
return t;
|
|
632
215
|
}
|
|
633
216
|
};
|
|
634
|
-
function
|
|
635
|
-
let
|
|
636
|
-
if (
|
|
637
|
-
return
|
|
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;
|
|
238
|
+
}
|
|
239
|
+
function he(e, t, n) {
|
|
240
|
+
return me(e, t, n);
|
|
241
|
+
}
|
|
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
|
+
}
|
|
638
256
|
}
|
|
639
|
-
function
|
|
640
|
-
|
|
641
|
-
if (!r) throw Error(`Constraint must contain a comparison operator (<=, >=, ==, =): "${e}"`);
|
|
642
|
-
let i = r[0], a = r.index, o = e.substring(0, a).trim(), s = e.substring(a + i.length).trim(), c;
|
|
643
|
-
if (i === "<=" || i === "=<") c = "<=";
|
|
644
|
-
else if (i === ">=" || i === "=>") c = ">=";
|
|
645
|
-
else if (i === "==" || i === "=") c = "==";
|
|
646
|
-
else throw Error(`Unsupported operator "${i}"`);
|
|
647
|
-
let l = P(o, t), u = P(s, t);
|
|
648
|
-
if (l instanceof D && l.quadTerms.size > 0 || u instanceof D && u.quadTerms.size > 0) throw Error("Quadratic constraints are not supported (only linear constraints are allowed in MILP/LP/QP)");
|
|
649
|
-
let d = l instanceof D ? new O(l.linearTerms, l.constant) : l, f = u instanceof D ? new O(u.linearTerms, u.constant) : u;
|
|
650
|
-
return c === "<=" ? d.le(f, n) : c === ">=" ? d.ge(f, n) : d.eq(f, n);
|
|
257
|
+
function ve(e) {
|
|
258
|
+
return e instanceof c || typeof e == "object" && !!e && "sense" in e && "lhs" in e && "rhs" in e;
|
|
651
259
|
}
|
|
652
|
-
function
|
|
653
|
-
let n = /* @__PURE__ */ new Map(), r = "";
|
|
654
|
-
for (
|
|
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) {
|
|
655
265
|
let e = t[i];
|
|
656
|
-
if (typeof e == "number")
|
|
657
|
-
|
|
658
|
-
let t =
|
|
659
|
-
|
|
660
|
-
}
|
|
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.");
|
|
661
276
|
}
|
|
662
277
|
return {
|
|
663
|
-
fullText:
|
|
664
|
-
resolver: (e) => n.get(e)
|
|
278
|
+
fullText: o,
|
|
279
|
+
resolver: (e) => n.get(e),
|
|
280
|
+
numberMap: r
|
|
665
281
|
};
|
|
666
282
|
}
|
|
667
|
-
function
|
|
668
|
-
let { fullText: n, resolver: r } =
|
|
669
|
-
return
|
|
670
|
-
}
|
|
671
|
-
function R(e, ...t) {
|
|
672
|
-
let { fullText: n, resolver: r } = I(e, t);
|
|
673
|
-
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);
|
|
674
286
|
}
|
|
675
287
|
//#endregion
|
|
676
|
-
//#region src/modeler/
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
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
|
+
};
|
|
680
313
|
}
|
|
681
|
-
function
|
|
682
|
-
let
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
d.push(t && t.toLowerCase() === "maximize" ? "Maximize" : "Minimize");
|
|
696
|
-
let f = [], p = !0, m = n instanceof D ? n.linearTerms : n.terms;
|
|
697
|
-
if (m) for (let [e, t] of m) {
|
|
698
|
-
if (Math.abs(t) < 1e-12) continue;
|
|
699
|
-
let n = o.get(e), r = t >= 0 ? p ? "" : "+ " : "- ", i = Math.abs(t), a = i === 1 ? "" : `${i} `;
|
|
700
|
-
f.push(`${r}${a}${n}`), p = !1;
|
|
701
|
-
}
|
|
702
|
-
if (n instanceof D && n.quadTerms.size > 0) {
|
|
703
|
-
let e = [], t = !0;
|
|
704
|
-
for (let r of n.quadTerms.values()) {
|
|
705
|
-
if (Math.abs(r.coeff) < 1e-12) continue;
|
|
706
|
-
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);
|
|
707
|
-
r.var1 === r.var2 ? e.push(`${i}${s}${c} ^ 2`) : e.push(`${i}${s}${c} * ${l}`), t = !1;
|
|
708
|
-
}
|
|
709
|
-
if (e.length > 0) {
|
|
710
|
-
let t = `[ ${e.join(" ")} ] / 2`;
|
|
711
|
-
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);
|
|
712
328
|
}
|
|
713
329
|
}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
}
|
|
726
|
-
d.push("Bounds");
|
|
727
|
-
let g = [], _ = [];
|
|
728
|
-
for (let e of i) {
|
|
729
|
-
let t = o.get(e);
|
|
730
|
-
if (e.type === "Binary") {
|
|
731
|
-
_.push(t);
|
|
732
|
-
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);
|
|
733
341
|
}
|
|
734
|
-
|
|
735
|
-
let n = e.lb === -Infinity, r = e.ub === Infinity;
|
|
736
|
-
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}`);
|
|
737
|
-
}
|
|
738
|
-
if (g.length > 0) {
|
|
739
|
-
d.push("Generals");
|
|
740
|
-
for (let e = 0; e < g.length; e += 10) d.push(" " + g.slice(e, e + 10).join(" "));
|
|
741
|
-
}
|
|
742
|
-
if (_.length > 0) {
|
|
743
|
-
d.push("Binary");
|
|
744
|
-
for (let e = 0; e < _.length; e += 10) d.push(" " + _.slice(e, e + 10).join(" "));
|
|
745
|
-
}
|
|
746
|
-
return d.push("End"), {
|
|
747
|
-
lpString: d.join("\n") + "\n",
|
|
748
|
-
nameToVar: a,
|
|
749
|
-
nameToConstraint: s
|
|
750
|
-
};
|
|
342
|
+
}
|
|
751
343
|
}
|
|
752
|
-
|
|
753
|
-
//#region src/modeler/solvers/highs/worker-client.ts
|
|
754
|
-
var V = null, le = 0, H = /* @__PURE__ */ new Map();
|
|
755
|
-
function ue() {
|
|
344
|
+
function we() {
|
|
756
345
|
if (typeof window > "u" || typeof Worker > "u") return null;
|
|
757
346
|
if (!V) try {
|
|
758
|
-
V =
|
|
347
|
+
V = ne();
|
|
759
348
|
let e = V;
|
|
760
|
-
V.onmessage = (
|
|
761
|
-
let { type:
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
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
|
+
}
|
|
766
376
|
};
|
|
767
377
|
let t = (t) => {
|
|
768
378
|
if (V === e) {
|
|
769
379
|
V = null, e.terminate();
|
|
770
|
-
for (let e of H.values()) e.reject(t);
|
|
380
|
+
for (let e of H.values()) e.cleanupAbort?.(), e.reject(t);
|
|
771
381
|
H.clear();
|
|
772
382
|
}
|
|
773
383
|
};
|
|
@@ -777,47 +387,97 @@ function ue() {
|
|
|
777
387
|
}
|
|
778
388
|
return V;
|
|
779
389
|
}
|
|
780
|
-
async function
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
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();
|
|
787
406
|
return new Promise((t, n) => {
|
|
788
|
-
|
|
407
|
+
let o = {
|
|
408
|
+
id: l,
|
|
409
|
+
lpString: e,
|
|
410
|
+
workerOptions: s,
|
|
411
|
+
reportProgress: c,
|
|
412
|
+
startTime: u,
|
|
413
|
+
onProgress: a,
|
|
789
414
|
resolve: t,
|
|
790
415
|
reject: n
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
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);
|
|
801
430
|
}
|
|
431
|
+
H.set(l, o), U(r);
|
|
802
432
|
});
|
|
803
433
|
}
|
|
804
434
|
//#endregion
|
|
805
435
|
//#region src/modeler/solvers/highs/solver.ts
|
|
806
|
-
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
|
+
}
|
|
807
458
|
if (typeof e != "string") return "Unknown";
|
|
808
|
-
let
|
|
809
|
-
if (!
|
|
810
|
-
switch (
|
|
459
|
+
let n = e.trim();
|
|
460
|
+
if (!n) return "Unknown";
|
|
461
|
+
switch (n) {
|
|
811
462
|
case "Optimal": return "Optimal";
|
|
812
463
|
case "Infeasible": return "Infeasible";
|
|
813
464
|
case "Unbounded": return "Unbounded";
|
|
814
|
-
case "Primal infeasible or unbounded":
|
|
465
|
+
case "Primal infeasible or unbounded":
|
|
466
|
+
case "InfeasibleOrUnbounded": return "InfeasibleOrUnbounded";
|
|
815
467
|
case "Time limit reached":
|
|
816
468
|
case "TimeLimit": return "TimeLimit";
|
|
817
469
|
case "Iteration limit reached":
|
|
818
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";
|
|
819
475
|
case "Bound on objective reached":
|
|
476
|
+
case "ObjectiveBound": return "ObjectiveBound";
|
|
820
477
|
case "Target for objective reached":
|
|
478
|
+
case "ObjectiveTarget": return "ObjectiveTarget";
|
|
479
|
+
case "Interrupted":
|
|
480
|
+
case "User interrupt": return "Interrupted";
|
|
821
481
|
case "Feasible": return "Feasible";
|
|
822
482
|
case "Not Set": return "NotSolved";
|
|
823
483
|
case "Load error":
|
|
@@ -829,13 +489,32 @@ function W(e) {
|
|
|
829
489
|
case "Empty":
|
|
830
490
|
case "Unknown": return "Unknown";
|
|
831
491
|
}
|
|
832
|
-
let
|
|
833
|
-
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";
|
|
834
494
|
}
|
|
835
|
-
|
|
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
|
+
}
|
|
512
|
+
}
|
|
513
|
+
var q = class e {
|
|
836
514
|
static capabilities = {
|
|
837
515
|
supportsMIP: !0,
|
|
838
|
-
supportsQP: !0
|
|
516
|
+
supportsQP: !0,
|
|
517
|
+
supportsWarmStart: !0
|
|
839
518
|
};
|
|
840
519
|
name = "HiGHS";
|
|
841
520
|
version = "1.15.3";
|
|
@@ -844,184 +523,816 @@ var G = class e {
|
|
|
844
523
|
constructor(e = {}) {
|
|
845
524
|
this.options = e;
|
|
846
525
|
}
|
|
847
|
-
async solve(e, t, n = {}) {
|
|
848
|
-
let r = {
|
|
526
|
+
async solve(e, t = {}, n = {}) {
|
|
527
|
+
let r = E(t), i = r ? n : t, a = {
|
|
849
528
|
...this.options,
|
|
850
|
-
...
|
|
851
|
-
},
|
|
852
|
-
|
|
853
|
-
|
|
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,
|
|
854
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 },
|
|
855
581
|
values: {},
|
|
856
582
|
reducedCosts: {},
|
|
857
583
|
duals: {},
|
|
858
584
|
slacks: {},
|
|
859
|
-
runTime:
|
|
860
|
-
raw:
|
|
585
|
+
runTime: _,
|
|
586
|
+
raw: g
|
|
861
587
|
};
|
|
862
|
-
let
|
|
863
|
-
|
|
864
|
-
|
|
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);
|
|
865
598
|
if (n) {
|
|
866
|
-
|
|
867
|
-
|
|
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);
|
|
868
604
|
}
|
|
869
605
|
}
|
|
870
|
-
if (
|
|
871
|
-
let e = Array.isArray(
|
|
606
|
+
if (g.Rows) {
|
|
607
|
+
let e = Array.isArray(g.Rows) ? g.Rows : Object.values(g.Rows);
|
|
872
608
|
for (let t of e) {
|
|
873
|
-
let e = t.Name, n =
|
|
874
|
-
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))) {
|
|
875
611
|
let e = n.rhs - t.Primal;
|
|
876
|
-
|
|
612
|
+
A(N, n.name, Math.abs(e) < 1e-9 ? 0 : e);
|
|
877
613
|
}
|
|
878
614
|
}
|
|
879
615
|
}
|
|
880
616
|
return {
|
|
881
|
-
status:
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
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
|
|
889
633
|
};
|
|
890
634
|
}
|
|
891
|
-
},
|
|
892
|
-
function
|
|
893
|
-
|
|
635
|
+
}, J = q;
|
|
636
|
+
function Y() {
|
|
637
|
+
T("highs", (e) => new q(e)), _((e) => new q(e));
|
|
894
638
|
}
|
|
895
|
-
|
|
639
|
+
Y();
|
|
896
640
|
//#endregion
|
|
897
641
|
//#region src/modeler/solvers/highs/index.ts
|
|
898
|
-
var
|
|
899
|
-
HiGHS: () =>
|
|
900
|
-
HighsSolver: () =>
|
|
901
|
-
OFFICIAL_HIGHS_CDN_WASM_URL: () =>
|
|
902
|
-
getHighs: () =>
|
|
903
|
-
getHighsWasmUrl: () =>
|
|
904
|
-
isValidWasmHeader: () =>
|
|
905
|
-
mapHighsStatus: () =>
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
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
|
|
912
657
|
});
|
|
913
|
-
import * as
|
|
914
|
-
|
|
915
|
-
import * as
|
|
916
|
-
|
|
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);
|
|
917
662
|
//#endregion
|
|
918
663
|
//#region src/modeler/solvers/highs.ts
|
|
919
|
-
var
|
|
920
|
-
HiGHS: () =>
|
|
921
|
-
HighsSolver: () =>
|
|
922
|
-
OFFICIAL_HIGHS_CDN_WASM_URL: () =>
|
|
923
|
-
getHighs: () =>
|
|
924
|
-
getHighsWasmUrl: () =>
|
|
925
|
-
isValidWasmHeader: () =>
|
|
926
|
-
mapHighsStatus: () =>
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
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
|
|
933
679
|
});
|
|
934
|
-
|
|
680
|
+
z(Oe, Te);
|
|
935
681
|
//#endregion
|
|
936
682
|
//#region src/modeler/solvers/mock.ts
|
|
937
|
-
var
|
|
683
|
+
var ke = class {
|
|
938
684
|
name;
|
|
939
685
|
capabilities;
|
|
940
686
|
options;
|
|
941
687
|
constructor(e = {}) {
|
|
942
688
|
this.name = e.name || "MockSolver", this.capabilities = e.capabilities || {
|
|
943
689
|
supportsMIP: !0,
|
|
944
|
-
supportsQP: !0
|
|
690
|
+
supportsQP: !0,
|
|
691
|
+
supportsWarmStart: !0
|
|
945
692
|
}, this.options = e;
|
|
946
693
|
}
|
|
947
|
-
async solve(e, t, n = {}) {
|
|
948
|
-
let r = {
|
|
694
|
+
async solve(e, t = {}, n = {}) {
|
|
695
|
+
let r = E(t) ? n : t, i = {
|
|
949
696
|
...this.options,
|
|
950
|
-
...
|
|
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 }
|
|
951
707
|
};
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
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,
|
|
959
778
|
runTime: .001,
|
|
960
779
|
raw: { mock: !0 }
|
|
961
780
|
};
|
|
962
781
|
}
|
|
963
782
|
};
|
|
964
|
-
function
|
|
965
|
-
|
|
783
|
+
function Ae() {
|
|
784
|
+
T("mock", (e) => new ke(e));
|
|
966
785
|
}
|
|
967
|
-
|
|
786
|
+
Ae();
|
|
968
787
|
//#endregion
|
|
969
788
|
//#region src/modeler/solvers/index.ts
|
|
970
|
-
var
|
|
971
|
-
HiGHS: () =>
|
|
972
|
-
HighsSolver: () =>
|
|
973
|
-
MockSolver: () =>
|
|
974
|
-
OFFICIAL_HIGHS_CDN_WASM_URL: () =>
|
|
975
|
-
getHighs: () =>
|
|
976
|
-
getHighsWasmUrl: () =>
|
|
977
|
-
getSolver: () =>
|
|
978
|
-
isValidWasmHeader: () =>
|
|
979
|
-
listAvailableSolvers: () =>
|
|
980
|
-
mapHighsStatus: () =>
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
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
|
|
990
810
|
});
|
|
991
|
-
|
|
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
|
+
}
|
|
992
1268
|
//#endregion
|
|
993
1269
|
//#region src/modeler/model.ts
|
|
994
|
-
|
|
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 {
|
|
995
1280
|
name;
|
|
996
|
-
|
|
997
|
-
|
|
1281
|
+
_sense;
|
|
1282
|
+
_objectiveExpr;
|
|
998
1283
|
variables = [];
|
|
999
1284
|
constraints = [];
|
|
1000
1285
|
boolVars = [];
|
|
1001
1286
|
logicalConstraints = [];
|
|
1002
|
-
unsatCore =
|
|
1287
|
+
unsatCore = void 0;
|
|
1003
1288
|
values = /* @__PURE__ */ new Map();
|
|
1004
1289
|
varMapByName = /* @__PURE__ */ new Map();
|
|
1290
|
+
varPrefixCounters = /* @__PURE__ */ new Map();
|
|
1005
1291
|
boolVarMapByName = /* @__PURE__ */ new Map();
|
|
1006
1292
|
boolVarPrefixCounters = /* @__PURE__ */ new Map();
|
|
1007
1293
|
constrMapByName = /* @__PURE__ */ new Map();
|
|
1294
|
+
constrPrefixCounters = /* @__PURE__ */ new Map();
|
|
1295
|
+
logicalConstrMapByName = /* @__PURE__ */ new Map();
|
|
1296
|
+
logicalConstrCounter = 0;
|
|
1008
1297
|
status = "NotSolved";
|
|
1298
|
+
terminationStatus = "NotSolved";
|
|
1299
|
+
hasPrimalSolution = !1;
|
|
1009
1300
|
objectiveValue = null;
|
|
1301
|
+
objectiveBound = void 0;
|
|
1302
|
+
relGap = void 0;
|
|
1303
|
+
mipGap = void 0;
|
|
1304
|
+
absGap = void 0;
|
|
1010
1305
|
runTime = 0;
|
|
1011
1306
|
solution = null;
|
|
1012
1307
|
solver = null;
|
|
1308
|
+
hasSolutionState = !1;
|
|
1309
|
+
modelRevision = 0;
|
|
1310
|
+
activeOperationId = 0;
|
|
1311
|
+
batchDepth = 0;
|
|
1312
|
+
batchMutated = !1;
|
|
1313
|
+
batchUndoActions = [];
|
|
1013
1314
|
constructor(e = {}, t) {
|
|
1014
1315
|
let n;
|
|
1015
1316
|
n = typeof e == "string" ? {
|
|
1016
1317
|
...t,
|
|
1017
1318
|
name: e
|
|
1018
|
-
} : 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;
|
|
1019
1323
|
}
|
|
1020
|
-
|
|
1021
|
-
|
|
1324
|
+
set sense(e) {
|
|
1325
|
+
let t = le(e);
|
|
1326
|
+
this._sense !== t && (this._sense = t, this.recordModelMutation());
|
|
1022
1327
|
}
|
|
1023
|
-
get
|
|
1024
|
-
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;
|
|
1025
1336
|
}
|
|
1026
1337
|
get numVars() {
|
|
1027
1338
|
return this.variables.length;
|
|
@@ -1029,50 +1340,123 @@ var $ = class {
|
|
|
1029
1340
|
get numConstrs() {
|
|
1030
1341
|
return this.constraints.length;
|
|
1031
1342
|
}
|
|
1032
|
-
|
|
1033
|
-
if (
|
|
1034
|
-
|
|
1035
|
-
for (let
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
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);
|
|
1378
|
+
}
|
|
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);
|
|
1042
1383
|
}
|
|
1043
|
-
|
|
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;
|
|
1044
1397
|
}
|
|
1045
|
-
|
|
1046
|
-
|
|
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
|
+
});
|
|
1417
|
+
}
|
|
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;
|
|
1047
1421
|
return this.addVar({
|
|
1048
1422
|
...r,
|
|
1049
1423
|
type: e,
|
|
1050
|
-
name:
|
|
1424
|
+
name: a
|
|
1051
1425
|
});
|
|
1052
1426
|
}
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
let
|
|
1056
|
-
|
|
1057
|
-
...
|
|
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
|
|
1433
|
+
});
|
|
1434
|
+
}
|
|
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,
|
|
1058
1441
|
type: e,
|
|
1059
|
-
name:
|
|
1442
|
+
name: void 0,
|
|
1443
|
+
prefix: r
|
|
1060
1444
|
}));
|
|
1061
1445
|
return n;
|
|
1062
|
-
}
|
|
1063
|
-
if (
|
|
1446
|
+
});
|
|
1447
|
+
if (Z(t)) return this.runTransactionalBatch(() => {
|
|
1064
1448
|
let n = {};
|
|
1065
1449
|
for (let r of t) {
|
|
1066
|
-
let t =
|
|
1450
|
+
let t = u ? `${u}_${r}` : `${r}`;
|
|
1067
1451
|
n[r] = this.addVar({
|
|
1068
|
-
...
|
|
1452
|
+
...l,
|
|
1069
1453
|
type: e,
|
|
1070
1454
|
name: t
|
|
1071
1455
|
});
|
|
1072
1456
|
}
|
|
1073
1457
|
return n;
|
|
1074
|
-
}
|
|
1075
|
-
throw Error(`Invalid arguments provided for ${
|
|
1458
|
+
});
|
|
1459
|
+
throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
1076
1460
|
}
|
|
1077
1461
|
binary(e, t, n) {
|
|
1078
1462
|
return this.createDomainVars("Binary", e, t, n);
|
|
@@ -1084,52 +1468,96 @@ var $ = class {
|
|
|
1084
1468
|
return this.createDomainVars("Continuous", e, t, n);
|
|
1085
1469
|
}
|
|
1086
1470
|
bool(e, t, n) {
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
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
|
+
});
|
|
1094
1484
|
}
|
|
1095
|
-
if (typeof e == "string" || e === void 0)
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
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);
|
|
1489
|
+
}
|
|
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);
|
|
1101
1494
|
}
|
|
1102
|
-
if (
|
|
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(() => {
|
|
1103
1503
|
let t = {};
|
|
1104
1504
|
for (let n of e) {
|
|
1105
|
-
let e =
|
|
1505
|
+
let e = c ? `${c}_${n}` : `${n}`;
|
|
1106
1506
|
t[n] = this.createBoolVar(e);
|
|
1107
1507
|
}
|
|
1108
1508
|
return t;
|
|
1109
|
-
}
|
|
1509
|
+
});
|
|
1110
1510
|
throw Error("Invalid arguments provided for boolean variable creation");
|
|
1111
1511
|
}
|
|
1112
1512
|
hasVarName(e) {
|
|
1113
1513
|
return this.varMapByName.has(e) || this.boolVarMapByName.has(e);
|
|
1114
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
|
+
}
|
|
1115
1520
|
getNextBoolVarName(e) {
|
|
1116
1521
|
let t = this.boolVarPrefixCounters.get(e) ?? 0, n = `${e}_${t}`;
|
|
1117
|
-
for (; this.hasVarName(n);) t++, n = `${e}_${t}`;
|
|
1522
|
+
for (; this.hasVarName(n) || this.hasConstraintName(n);) t++, n = `${e}_${t}`;
|
|
1118
1523
|
return this.boolVarPrefixCounters.set(e, t + 1), n;
|
|
1119
1524
|
}
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
return this.
|
|
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;
|
|
1125
1547
|
}
|
|
1126
1548
|
addVar(e) {
|
|
1127
|
-
let t = e || {}, n = typeof t.name == "string" ? t.name.trim() : void 0, r = n && n.length > 0 ? n : void 0, i =
|
|
1128
|
-
|
|
1129
|
-
name
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
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
|
|
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;
|
|
1560
|
+
}
|
|
1133
1561
|
}
|
|
1134
1562
|
getVarByName(e) {
|
|
1135
1563
|
return this.varMapByName.get(e);
|
|
@@ -1140,28 +1568,41 @@ var $ = class {
|
|
|
1140
1568
|
getConstraintByName(e) {
|
|
1141
1569
|
return this.constrMapByName.get(e);
|
|
1142
1570
|
}
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
this.
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
if (
|
|
1155
|
-
|
|
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);
|
|
1156
1597
|
return this;
|
|
1157
|
-
}
|
|
1158
|
-
if (e instanceof
|
|
1159
|
-
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().");
|
|
1160
1601
|
return this.addConstraint(e, t), this;
|
|
1161
1602
|
}
|
|
1162
1603
|
getValues(e) {
|
|
1163
1604
|
if (e == null) return null;
|
|
1164
|
-
if (e instanceof
|
|
1605
|
+
if (e instanceof b || e instanceof o) return e.value;
|
|
1165
1606
|
if (Array.isArray(e)) return e.map((e) => this.getValues(e));
|
|
1166
1607
|
if (typeof e == "object") {
|
|
1167
1608
|
let t = {};
|
|
@@ -1171,198 +1612,396 @@ var $ = class {
|
|
|
1171
1612
|
return null;
|
|
1172
1613
|
}
|
|
1173
1614
|
addConstraint(e, t) {
|
|
1174
|
-
if (e instanceof
|
|
1175
|
-
if (e instanceof
|
|
1176
|
-
if (e instanceof
|
|
1177
|
-
let n = t
|
|
1178
|
-
|
|
1179
|
-
name
|
|
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,
|
|
1180
1632
|
expr: e
|
|
1181
|
-
}
|
|
1633
|
+
};
|
|
1634
|
+
return this.logicalConstraints.push(a), this.logicalConstrMapByName.set(i, a), this.recordModelMutation(), e;
|
|
1182
1635
|
}
|
|
1183
|
-
let n;
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
for (let t of e) this.add(t);
|
|
1190
|
-
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`);
|
|
1191
1642
|
}
|
|
1192
|
-
|
|
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;
|
|
1193
1653
|
}
|
|
1194
1654
|
indicator(e, t, n = {}) {
|
|
1195
|
-
if (
|
|
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).");
|
|
1196
1658
|
if (!("sense" in t) || !("lhs" in t)) throw Error("Invalid constraint expression passed to indicator(). Expression must include a comparison operator (<=, >=, ==).");
|
|
1197
|
-
let r = t, i = n.activeValue === void 0 ? 1 : n.activeValue
|
|
1198
|
-
if (i
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
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.`);
|
|
1208
1676
|
if (l === "<=" || l === "==") {
|
|
1209
|
-
let t =
|
|
1210
|
-
|
|
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]);
|
|
1211
1679
|
}
|
|
1212
1680
|
if (l === ">=" || l === "==") {
|
|
1213
|
-
let t =
|
|
1214
|
-
|
|
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]);
|
|
1215
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;
|
|
1216
1687
|
}
|
|
1217
|
-
return
|
|
1688
|
+
return this.runTransactionalBatch(() => m.map(([e, t]) => this.addConstraint(e, t)));
|
|
1218
1689
|
}
|
|
1219
1690
|
toLpString() {
|
|
1220
|
-
|
|
1691
|
+
this.validateIntegrity();
|
|
1692
|
+
let { lpString: e } = C({
|
|
1221
1693
|
name: this.name,
|
|
1222
1694
|
sense: this.sense,
|
|
1223
|
-
objective: this.
|
|
1695
|
+
objective: this.objectiveExpr,
|
|
1224
1696
|
constraints: this.constraints,
|
|
1225
1697
|
variables: this.variables
|
|
1226
1698
|
});
|
|
1227
1699
|
return e;
|
|
1228
1700
|
}
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
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 = {
|
|
1234
1761
|
name: this.name,
|
|
1235
1762
|
sense: this.sense,
|
|
1236
|
-
objective: this.
|
|
1763
|
+
objective: this._objectiveExpr,
|
|
1237
1764
|
constraints: this.constraints,
|
|
1238
1765
|
variables: this.variables,
|
|
1239
1766
|
logicalConstraints: this.logicalConstraints,
|
|
1240
1767
|
boolVars: this.boolVars
|
|
1241
|
-
},
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
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);
|
|
1257
1794
|
}
|
|
1258
1795
|
}
|
|
1259
|
-
if (
|
|
1260
|
-
|
|
1261
|
-
|
|
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);
|
|
1800
|
+
}
|
|
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));
|
|
1262
1805
|
}
|
|
1263
|
-
if (
|
|
1264
|
-
|
|
1265
|
-
|
|
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));
|
|
1266
1810
|
}
|
|
1267
|
-
if (
|
|
1268
|
-
|
|
1269
|
-
|
|
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));
|
|
1270
1815
|
}
|
|
1271
1816
|
return this.solution = {
|
|
1272
1817
|
status: this.status,
|
|
1818
|
+
terminationStatus: this.terminationStatus,
|
|
1819
|
+
hasPrimalSolution: this.hasPrimalSolution,
|
|
1273
1820
|
objectiveValue: this.objectiveValue,
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
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,
|
|
1278
1831
|
runTime: this.runTime,
|
|
1279
|
-
raw:
|
|
1280
|
-
}, this.status;
|
|
1281
|
-
}
|
|
1282
|
-
async solve(e, t) {
|
|
1283
|
-
return this.optimize(e, t);
|
|
1832
|
+
raw: c.raw
|
|
1833
|
+
}, this.hasSolutionState = !0, this.status;
|
|
1284
1834
|
}
|
|
1285
1835
|
async check(e, t) {
|
|
1286
|
-
let n, r;
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
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;
|
|
1305
1861
|
}
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
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
|
+
}
|
|
1315
1873
|
}
|
|
1316
|
-
return {
|
|
1317
|
-
status:
|
|
1318
|
-
values:
|
|
1874
|
+
return this.hasSolutionState = !0, {
|
|
1875
|
+
status: e.status,
|
|
1876
|
+
values: t,
|
|
1877
|
+
unsatCore: this.unsatCore,
|
|
1878
|
+
conflicts: this.unsatCore,
|
|
1319
1879
|
runTime: this.runTime
|
|
1320
1880
|
};
|
|
1321
|
-
} finally {
|
|
1322
|
-
this.objective = i, this.sense = a;
|
|
1323
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);
|
|
1324
1927
|
}
|
|
1325
1928
|
};
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
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,
|
|
1330
1958
|
Constraint: () => c,
|
|
1331
|
-
HiGHS: () =>
|
|
1332
|
-
HighsSolver: () =>
|
|
1333
|
-
LinExpr: () =>
|
|
1334
|
-
MockSolver: () =>
|
|
1335
|
-
Model: () =>
|
|
1336
|
-
OFFICIAL_HIGHS_CDN_WASM_URL: () =>
|
|
1337
|
-
QuadExpr: () =>
|
|
1338
|
-
Var: () =>
|
|
1339
|
-
and: () =>
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
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);
|
|
1367
2006
|
//#endregion
|
|
1368
|
-
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 };
|