@ohtaman/washi 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +103 -386
- package/README.md +104 -387
- package/README.zh-CN.md +103 -386
- package/THIRD_PARTY_LICENSES.md +5 -4
- package/dist/browser/_washi-node-only-BvRk9kiK.js +0 -0
- package/dist/browser/browser-runtime-TLCY0hkc.js +1793 -0
- package/dist/browser/highs-worker.js +1 -1
- package/dist/browser/highs.wasm +0 -0
- package/dist/browser/highs.wasm.LICENSE +1 -2
- package/dist/browser/loader-DewlSho8.js +643 -0
- package/dist/browser/solvers/glpk.js +3 -3
- package/dist/browser/solvers/glpk.min.js +1 -1
- package/dist/browser/solvers/z3.js +7 -1
- package/dist/browser/solvers/z3.min.js +1 -1
- package/dist/browser/washi.js +1708 -540
- package/dist/browser/washi.min.js +3 -4
- package/dist/lib/_washi-node-only-BvRk9kiK.js +0 -0
- package/dist/lib/highs-browser-runtime.js +2120 -4124
- package/dist/lib/highs-node-runtime.js +24 -1
- package/dist/lib/highs-runtime.js +2 -0
- package/dist/lib/highs-worker.js +1 -1
- package/dist/lib/highs.wasm +0 -0
- package/dist/lib/highs.wasm.LICENSE +1 -2
- package/dist/lib/loader-BZUQNvh4.js +649 -0
- package/dist/lib/{registry-BEfvpZW3.js → registry-D7TZ3Wh_.js} +142 -59
- package/dist/lib/solvers/glpk.js +4 -4
- package/dist/lib/solvers/z3.js +1 -1
- package/dist/lib/washi.js +1576 -465
- package/dist/types/decomposition/benders.d.ts +32 -0
- package/dist/types/decomposition/benders.d.ts.map +1 -0
- package/dist/types/decomposition/column-generation.d.ts +34 -0
- package/dist/types/decomposition/column-generation.d.ts.map +1 -0
- package/dist/types/decomposition/index.d.ts +4 -0
- package/dist/types/decomposition/index.d.ts.map +1 -0
- package/dist/types/decomposition/types.d.ts +230 -0
- package/dist/types/decomposition/types.d.ts.map +1 -0
- package/dist/types/index.d.ts +4 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/modeler/boolean-expr.d.ts.map +1 -1
- package/dist/types/modeler/constraint.d.ts +11 -0
- package/dist/types/modeler/constraint.d.ts.map +1 -1
- package/dist/types/modeler/expression.d.ts +57 -26
- package/dist/types/modeler/expression.d.ts.map +1 -1
- package/dist/types/modeler/index.d.ts +4 -3
- package/dist/types/modeler/index.d.ts.map +1 -1
- package/dist/types/modeler/linearizer.d.ts +15 -0
- package/dist/types/modeler/linearizer.d.ts.map +1 -0
- package/dist/types/modeler/lp-writer.d.ts +3 -1
- package/dist/types/modeler/lp-writer.d.ts.map +1 -1
- package/dist/types/modeler/model.d.ts +159 -8
- package/dist/types/modeler/model.d.ts.map +1 -1
- package/dist/types/modeler/parser.d.ts +25 -5
- package/dist/types/modeler/parser.d.ts.map +1 -1
- package/dist/types/modeler/solvers/glpk/solver.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/browser-runtime.d.ts +2 -1
- package/dist/types/modeler/solvers/highs/browser-runtime.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/driver.d.ts +232 -0
- package/dist/types/modeler/solvers/highs/driver.d.ts.map +1 -0
- package/dist/types/modeler/solvers/highs/index.d.ts +1 -0
- package/dist/types/modeler/solvers/highs/index.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/loader.d.ts +4 -4
- package/dist/types/modeler/solvers/highs/loader.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/node-runtime.d.ts +2 -1
- package/dist/types/modeler/solvers/highs/node-runtime.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/solver.d.ts +1 -1
- package/dist/types/modeler/solvers/highs/solver.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/worker-client.d.ts.map +1 -1
- package/dist/types/modeler/solvers/types.d.ts +4 -0
- package/dist/types/modeler/solvers/types.d.ts.map +1 -1
- package/dist/types/modeler/types.d.ts +27 -0
- package/dist/types/modeler/types.d.ts.map +1 -1
- package/docs/examples/diet-sensitivity.md +15 -14
- package/docs/examples/ecommerce-coupons.md +15 -22
- package/docs/examples/index.md +18 -12
- package/docs/examples/knapsack.md +8 -7
- package/docs/examples/portfolio-qp.md +11 -4
- package/docs/examples/production.md +4 -4
- package/docs/examples/shift-scheduling.md +20 -7
- package/docs/examples/smt-security.md +16 -4
- package/docs/examples/transportation.md +46 -19
- package/docs/examples/traveling-salesperson.md +157 -0
- package/docs/examples/unsat-core.md +15 -5
- package/docs/examples/vehicle-routing.md +208 -0
- package/docs/getting-started/ai-agents.md +33 -18
- package/docs/getting-started/cross-origin.md +56 -28
- package/docs/getting-started/index.md +40 -69
- package/docs/getting-started/runtimes.md +66 -61
- package/docs/guide/constraints.md +47 -41
- package/docs/guide/decomposition.md +267 -0
- package/docs/guide/expressions.md +90 -39
- package/docs/guide/formulation-tips.md +212 -0
- package/docs/guide/objectives.md +7 -4
- package/docs/guide/unsat-core.md +28 -9
- package/docs/guide/variables.md +33 -38
- package/docs/ja/getting-started/ai-agents.md +32 -18
- package/docs/solvers/custom-solver.md +1 -1
- package/docs/solvers/highs.md +48 -5
- package/docs/solvers/index.md +4 -4
- package/docs/solvers/z3.md +3 -0
- package/docs/zh/getting-started/ai-agents.md +32 -18
- package/llms-full.txt +1536 -478
- package/llms.txt +28 -22
- package/package.json +19 -16
- package/skills/washi/SKILL.md +21 -17
- package/dist/browser/browser-runtime-D13gHOT5.js +0 -4189
- package/dist/browser/loader-CtaDHef_.js +0 -273
- package/dist/lib/loader-DmNC_UNk.js +0 -279
package/dist/browser/washi.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as e, i as t, n, o as r, r as i,
|
|
1
|
+
import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "./loader-DewlSho8.js";
|
|
2
2
|
//#region src/modeler/types.ts
|
|
3
|
-
function
|
|
3
|
+
function s(e) {
|
|
4
4
|
if (e === void 0) return "Minimize";
|
|
5
5
|
if (typeof e == "string") {
|
|
6
6
|
let t = e.toLowerCase();
|
|
@@ -11,68 +11,68 @@ function o(e) {
|
|
|
11
11
|
}
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region src/modeler/boolean-expr.ts
|
|
14
|
-
var
|
|
15
|
-
function
|
|
16
|
-
if (e instanceof
|
|
17
|
-
throw typeof e == "object" && e && ("terms" in e || "quadTerms" in e) ? Error(`Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical operator "${t}". Use a comparison constraint such as expr\`\${x} <= 10\` or a BoolVar/BoolExpr.`) : Error(`Invalid operand passed to logical operator "${t}": expected a BoolVar, BoolExpr, or Constraint.`);
|
|
14
|
+
var c = 0;
|
|
15
|
+
function l(e, t) {
|
|
16
|
+
if (e instanceof u || e instanceof y) return e;
|
|
17
|
+
throw typeof e == "object" && e && ("terms" in e || "quadTerms" in e) ? Error(`Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical operator "${t}". Use a comparison constraint such as expr\`\${x} <= 10\` or a BoolVar/BoolExpr.`) : typeof e == "object" && e && "id" in e && "name" in e && "lb" in e && "ub" in e && !("sense" in e) ? Error(`Invalid operand passed to logical operator "${t}": expected a BoolVar, BoolExpr, or Constraint, but received numeric variable "${e.name}". Use m.bool() for propositional variables, add a comparison such as expr\`\${x} == 1\`, or use m.indicator(binVar, constraint) for 0-1 Big-M indicator constraints.`) : Error(`Invalid operand passed to logical operator "${t}": expected a BoolVar, BoolExpr, or Constraint.`);
|
|
18
18
|
}
|
|
19
|
-
var
|
|
19
|
+
var u = class {
|
|
20
20
|
and(e) {
|
|
21
|
-
return new
|
|
21
|
+
return new f("and", [this, l(e, "and")]);
|
|
22
22
|
}
|
|
23
23
|
or(e) {
|
|
24
|
-
return new
|
|
24
|
+
return new f("or", [this, l(e, "or")]);
|
|
25
25
|
}
|
|
26
26
|
implies(e) {
|
|
27
|
-
return new
|
|
27
|
+
return new f("implies", [this, l(e, "implies")]);
|
|
28
28
|
}
|
|
29
29
|
xor(e) {
|
|
30
|
-
return new
|
|
30
|
+
return new f("xor", [this, l(e, "xor")]);
|
|
31
31
|
}
|
|
32
32
|
not() {
|
|
33
|
-
return new
|
|
33
|
+
return new f("not", [this]);
|
|
34
34
|
}
|
|
35
|
-
},
|
|
35
|
+
}, d = class extends u {
|
|
36
36
|
id;
|
|
37
37
|
name;
|
|
38
38
|
value = null;
|
|
39
39
|
constructor(e) {
|
|
40
|
-
super(), this.id = ++
|
|
40
|
+
super(), this.id = ++c, this.name = e || `p_${this.id}`;
|
|
41
41
|
}
|
|
42
42
|
toString() {
|
|
43
43
|
return this.name;
|
|
44
44
|
}
|
|
45
|
-
},
|
|
45
|
+
}, f = class extends u {
|
|
46
46
|
op;
|
|
47
47
|
children;
|
|
48
48
|
constructor(e, t) {
|
|
49
|
-
super(), this.op = e, this.children = t.map((t) =>
|
|
49
|
+
super(), this.op = e, this.children = t.map((t) => l(t, e));
|
|
50
50
|
}
|
|
51
51
|
toString() {
|
|
52
52
|
return this.op === "not" ? `not(${this.children[0].toString()})` : `(${this.children.map((e) => e.toString()).join(` ${this.op} `)})`;
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
|
-
function
|
|
55
|
+
function p(...e) {
|
|
56
56
|
if (e.length === 0) throw Error("and() requires at least one expression");
|
|
57
|
-
return new
|
|
57
|
+
return new f("and", e);
|
|
58
58
|
}
|
|
59
|
-
function
|
|
59
|
+
function m(...e) {
|
|
60
60
|
if (e.length === 0) throw Error("or() requires at least one expression");
|
|
61
|
-
return new
|
|
61
|
+
return new f("or", e);
|
|
62
62
|
}
|
|
63
|
-
function
|
|
64
|
-
return new
|
|
63
|
+
function h(e) {
|
|
64
|
+
return new f("not", [e]);
|
|
65
65
|
}
|
|
66
|
-
function
|
|
67
|
-
return new
|
|
66
|
+
function g(e, t) {
|
|
67
|
+
return new f("implies", [e, t]);
|
|
68
68
|
}
|
|
69
|
-
function
|
|
69
|
+
function _(...e) {
|
|
70
70
|
if (e.length === 0) throw Error("xor() requires at least one expression");
|
|
71
|
-
return new
|
|
71
|
+
return new f("xor", e);
|
|
72
72
|
}
|
|
73
73
|
//#endregion
|
|
74
74
|
//#region src/modeler/constraint.ts
|
|
75
|
-
var
|
|
75
|
+
var v = 0, y = class e {
|
|
76
76
|
kind = "constraint";
|
|
77
77
|
id;
|
|
78
78
|
_lhs;
|
|
@@ -83,8 +83,14 @@ var _ = 0, v = class e {
|
|
|
83
83
|
ownerModel = null;
|
|
84
84
|
slack = null;
|
|
85
85
|
dual = null;
|
|
86
|
+
addTerm(e, t) {
|
|
87
|
+
return t === 0 ? this : (this._lhs.addTerm(e, t), this.ownerModel?.notifyMutation?.(), this);
|
|
88
|
+
}
|
|
89
|
+
setTerm(e, t) {
|
|
90
|
+
return this._lhs.setTerm(e, t), this.ownerModel?.notifyMutation?.(), this;
|
|
91
|
+
}
|
|
86
92
|
constructor(e, t, n, r) {
|
|
87
|
-
this.id = ++
|
|
93
|
+
this.id = ++v, this._lhs = e, this._sense = t, this._rhs = n;
|
|
88
94
|
let i = typeof r == "string" ? r.trim() : void 0;
|
|
89
95
|
i && i.length > 0 ? (this._name = i, this.hasExplicitName = !0) : (this._name = `c_${this.id}`, this.hasExplicitName = !1);
|
|
90
96
|
}
|
|
@@ -116,19 +122,19 @@ var _ = 0, v = class e {
|
|
|
116
122
|
this._name = e, this.hasExplicitName = t;
|
|
117
123
|
}
|
|
118
124
|
and(e) {
|
|
119
|
-
return new
|
|
125
|
+
return new f("and", [this, e]);
|
|
120
126
|
}
|
|
121
127
|
or(e) {
|
|
122
|
-
return new
|
|
128
|
+
return new f("or", [this, e]);
|
|
123
129
|
}
|
|
124
130
|
implies(e) {
|
|
125
|
-
return new
|
|
131
|
+
return new f("implies", [this, e]);
|
|
126
132
|
}
|
|
127
133
|
xor(e) {
|
|
128
|
-
return new
|
|
134
|
+
return new f("xor", [this, e]);
|
|
129
135
|
}
|
|
130
136
|
not() {
|
|
131
|
-
return new
|
|
137
|
+
return new f("not", [this]);
|
|
132
138
|
}
|
|
133
139
|
add(e) {
|
|
134
140
|
throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
@@ -168,16 +174,16 @@ var _ = 0, v = class e {
|
|
|
168
174
|
return `${this.name}: ${this.lhs.toString()} ${e} ${this.rhs}`;
|
|
169
175
|
}
|
|
170
176
|
};
|
|
171
|
-
function
|
|
172
|
-
return e instanceof
|
|
177
|
+
function b(e) {
|
|
178
|
+
return e instanceof y || typeof e == "object" && !!e && "sense" in e && "lhs" in e && "rhs" in e;
|
|
173
179
|
}
|
|
174
180
|
//#endregion
|
|
175
181
|
//#region src/modeler/quad-expr.ts
|
|
176
|
-
function
|
|
182
|
+
function x(e, t) {
|
|
177
183
|
let n = e.id, r = t.id;
|
|
178
184
|
return n <= r ? `${n}:${r}` : `${r}:${n}`;
|
|
179
185
|
}
|
|
180
|
-
var
|
|
186
|
+
var S = class e {
|
|
181
187
|
kind = "quadratic";
|
|
182
188
|
linearTerms;
|
|
183
189
|
quadTerms;
|
|
@@ -191,11 +197,11 @@ var x = class e {
|
|
|
191
197
|
return new e(this.linearTerms, this.quadTerms, this.constant);
|
|
192
198
|
}
|
|
193
199
|
getQuadCoeff(e, t) {
|
|
194
|
-
let n =
|
|
200
|
+
let n = x(e, t), r = this.quadTerms.get(n);
|
|
195
201
|
return r ? r.coeff : 0;
|
|
196
202
|
}
|
|
197
203
|
add(t) {
|
|
198
|
-
if (
|
|
204
|
+
if (b(t)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
199
205
|
let n = this.clone();
|
|
200
206
|
if (typeof t == "number") return n.constant += t, n;
|
|
201
207
|
if (t instanceof e) {
|
|
@@ -224,11 +230,11 @@ var x = class e {
|
|
|
224
230
|
return i === 0 ? n.linearTerms.delete(r) : n.linearTerms.set(r, i), n;
|
|
225
231
|
}
|
|
226
232
|
sub(e) {
|
|
227
|
-
if (
|
|
233
|
+
if (b(e)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
228
234
|
return typeof e == "number" ? this.add(-e) : this.add(e.mul(-1));
|
|
229
235
|
}
|
|
230
236
|
mul(t) {
|
|
231
|
-
if (
|
|
237
|
+
if (b(t)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
232
238
|
if (typeof t == "number") {
|
|
233
239
|
let n = this.linearTerms.size > 0 || this.quadTerms.size > 0, r = this.constant === 0 && n ? 0 : this.constant * t;
|
|
234
240
|
if (this.constant !== 0 && t !== 0 && r === 0) throw Error("Constant multiplication underflows to zero.");
|
|
@@ -288,7 +294,7 @@ var x = class e {
|
|
|
288
294
|
}
|
|
289
295
|
toConstraint(e, t, n) {
|
|
290
296
|
if (this.quadTerms.size > 0) throw Error(`Quadratic expressions are not supported in linear constraints (${e}): quadratic terms are only allowed in objectives.`);
|
|
291
|
-
let r = new
|
|
297
|
+
let r = new C(this.linearTerms, this.constant);
|
|
292
298
|
return e === "<=" ? r.le(t, n) : e === ">=" ? r.ge(t, n) : r.eq(t, n);
|
|
293
299
|
}
|
|
294
300
|
and(e) {
|
|
@@ -325,7 +331,7 @@ var x = class e {
|
|
|
325
331
|
static fromProduct(t, n, r = 1) {
|
|
326
332
|
let i = new e();
|
|
327
333
|
if (r === 0) return i;
|
|
328
|
-
let a =
|
|
334
|
+
let a = x(t, n);
|
|
329
335
|
return i.quadTerms.set(a, {
|
|
330
336
|
var1: t.id <= n.id ? t : n,
|
|
331
337
|
var2: t.id <= n.id ? n : t,
|
|
@@ -355,7 +361,7 @@ var x = class e {
|
|
|
355
361
|
return s;
|
|
356
362
|
}
|
|
357
363
|
static extractScalarDivisor(e, t) {
|
|
358
|
-
if (
|
|
364
|
+
if (b(e)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
359
365
|
if (typeof e == "number") {
|
|
360
366
|
if (e === 0) throw Error(`Division by zero in ${t}`);
|
|
361
367
|
return e;
|
|
@@ -365,19 +371,26 @@ var x = class e {
|
|
|
365
371
|
if (e.constant === 0) throw Error(`Division by zero in ${t}`);
|
|
366
372
|
return e.constant;
|
|
367
373
|
}
|
|
368
|
-
},
|
|
374
|
+
}, C = class e {
|
|
369
375
|
kind = "linear";
|
|
370
376
|
terms;
|
|
371
377
|
constant;
|
|
372
378
|
constructor(e = /* @__PURE__ */ new Map(), t = 0) {
|
|
373
379
|
this.terms = new Map(e), this.constant = t;
|
|
374
380
|
}
|
|
381
|
+
setTerm(e, t) {
|
|
382
|
+
return t === 0 ? this.terms.delete(e) : this.terms.set(e, t), this;
|
|
383
|
+
}
|
|
384
|
+
addTerm(e, t) {
|
|
385
|
+
let n = (this.terms.get(e) ?? 0) + t;
|
|
386
|
+
return n === 0 ? this.terms.delete(e) : this.terms.set(e, n), this;
|
|
387
|
+
}
|
|
375
388
|
clone() {
|
|
376
389
|
return new e(this.terms, this.constant);
|
|
377
390
|
}
|
|
378
391
|
add(e) {
|
|
379
|
-
if (
|
|
380
|
-
if (e instanceof
|
|
392
|
+
if (b(e)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
393
|
+
if (e instanceof S) return e.add(this);
|
|
381
394
|
let t = this.clone();
|
|
382
395
|
if (typeof e == "number") t.constant += e;
|
|
383
396
|
else if ("terms" in e) {
|
|
@@ -393,11 +406,11 @@ var x = class e {
|
|
|
393
406
|
return t;
|
|
394
407
|
}
|
|
395
408
|
sub(e) {
|
|
396
|
-
if (
|
|
397
|
-
return e instanceof
|
|
409
|
+
if (b(e)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
410
|
+
return e instanceof S ? e.neg().add(this) : typeof e == "number" ? this.add(-e) : this.add(e.mul(-1));
|
|
398
411
|
}
|
|
399
412
|
mul(t) {
|
|
400
|
-
if (
|
|
413
|
+
if (b(t)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
401
414
|
if (typeof t == "number") {
|
|
402
415
|
let n = this.constant === 0 && this.terms.size > 0 ? 0 : this.constant * t;
|
|
403
416
|
if (this.constant !== 0 && t !== 0 && n === 0) throw Error("Constant multiplication underflows to zero.");
|
|
@@ -409,10 +422,10 @@ var x = class e {
|
|
|
409
422
|
}
|
|
410
423
|
return r;
|
|
411
424
|
}
|
|
412
|
-
return t instanceof
|
|
425
|
+
return t instanceof M || typeof t == "object" && t && "id" in t && !("terms" in t) && !("quadTerms" in t) ? S.multiplyLinearTerms(this.constant, this.terms, 0, /* @__PURE__ */ new Map([[t, 1]])) : t instanceof S ? this.terms.size === 0 ? t.mul(this.constant) : new S(this.terms, /* @__PURE__ */ new Map(), this.constant).mul(t) : this.terms.size === 0 ? t.mul(this.constant) : t.terms.size === 0 ? this.mul(t.constant) : S.multiplyLinearTerms(this.constant, this.terms, t.constant, t.terms);
|
|
413
426
|
}
|
|
414
427
|
div(e) {
|
|
415
|
-
let t =
|
|
428
|
+
let t = S.extractScalarDivisor(e, "LinExpr.div()");
|
|
416
429
|
return this.mul(1 / t);
|
|
417
430
|
}
|
|
418
431
|
neg() {
|
|
@@ -438,14 +451,14 @@ var x = class e {
|
|
|
438
451
|
toConstraint(t, n, r) {
|
|
439
452
|
let i = this.clone(), a = 0;
|
|
440
453
|
if (typeof n == "number") a = n;
|
|
441
|
-
else if (n instanceof
|
|
442
|
-
else if (n instanceof
|
|
454
|
+
else if (n instanceof y || typeof n == "object" && n && "sense" in n && "lhs" in n) throw Error(`Cannot compare against a Constraint in (${t}): expected a number, Var, or LinExpr.`);
|
|
455
|
+
else if (n instanceof S || typeof n == "object" && n && "quadTerms" in n) {
|
|
443
456
|
let r = n;
|
|
444
457
|
if (r.quadTerms.size > 0) throw Error(`Quadratic expressions are not supported in linear constraints (${t}): quadratic terms are only allowed in objectives.`);
|
|
445
458
|
i = i.sub(new e(r.linearTerms, 0)), a = r.constant;
|
|
446
459
|
} else "terms" in n ? (i = i.sub(new e(n.terms, 0)), a = n.constant) : i = i.sub(n);
|
|
447
460
|
let o = a - i.constant;
|
|
448
|
-
return i.constant = 0, new
|
|
461
|
+
return i.constant = 0, new y(i, t, o, r);
|
|
449
462
|
}
|
|
450
463
|
and(e) {
|
|
451
464
|
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'and': expected a BoolVar, Constraint, or BoolOp.");
|
|
@@ -475,55 +488,125 @@ var x = class e {
|
|
|
475
488
|
return e.join(" ") || "0";
|
|
476
489
|
}
|
|
477
490
|
};
|
|
478
|
-
function
|
|
491
|
+
function w(e, t) {
|
|
479
492
|
let n = /* @__PURE__ */ new Map(), r = 0;
|
|
480
493
|
function i(e) {
|
|
494
|
+
return e instanceof y || e.kind === "constraint" || "sense" in e && (e.sense === "<=" || e.sense === ">=" || e.sense === "==") && "lhs" in e && "rhs" in e && typeof e.rhs == "number" && typeof e.lhs == "object" && e.lhs !== null && "terms" in e.lhs && e.lhs.terms instanceof Map;
|
|
495
|
+
}
|
|
496
|
+
function a(e) {
|
|
497
|
+
return e instanceof S || "quadTerms" in e && e.quadTerms instanceof Map && "linearTerms" in e && e.linearTerms instanceof Map && typeof e.constant == "number";
|
|
498
|
+
}
|
|
499
|
+
function o(e) {
|
|
500
|
+
return e instanceof C || "terms" in e && e.terms instanceof Map && typeof e.constant == "number";
|
|
501
|
+
}
|
|
502
|
+
function s(e) {
|
|
503
|
+
return e instanceof M || !i(e) && typeof e.id == "number" && typeof e.name == "string" && typeof e.lb == "number" && typeof e.ub == "number" && typeof e.type == "string" && typeof e.mul == "function";
|
|
504
|
+
}
|
|
505
|
+
function c(e) {
|
|
506
|
+
return i(e) || a(e) || o(e) || s(e);
|
|
507
|
+
}
|
|
508
|
+
function l(e) {
|
|
509
|
+
if (typeof e != "object" || !e || Array.isArray(e) || c(e)) return !1;
|
|
510
|
+
let t = Object.getPrototypeOf(e);
|
|
511
|
+
return t === Object.prototype || t === null;
|
|
512
|
+
}
|
|
513
|
+
function u(e) {
|
|
481
514
|
if (e != null) {
|
|
482
|
-
if (typeof e == "number")
|
|
483
|
-
|
|
484
|
-
|
|
515
|
+
if (typeof e == "number") {
|
|
516
|
+
if (!Number.isFinite(e)) throw Error(`Invalid non-finite number "${e}" in sum().`);
|
|
517
|
+
let t = r + e;
|
|
518
|
+
if (!Number.isFinite(t)) throw Error("Constant accumulation overflows finite floating-point range in sum().");
|
|
519
|
+
r = t;
|
|
520
|
+
} else if (typeof e == "object" && i(e)) throw Error("Cannot sum a constraint comparison (<=, >=, ==) in sum(): expected a number, Var, or LinExpr.");
|
|
521
|
+
else if (typeof e == "object" && a(e)) {
|
|
485
522
|
let t = e;
|
|
486
523
|
if (t.quadTerms.size > 0) throw Error("Quadratic expressions are not supported in sum(): sum() produces a linear expression (LinExpr).");
|
|
524
|
+
if (!Number.isFinite(t.constant)) throw Error(`Invalid non-finite constant "${t.constant}" in sum().`);
|
|
487
525
|
for (let [e, r] of t.linearTerms) {
|
|
488
|
-
|
|
489
|
-
n.
|
|
526
|
+
if (!Number.isFinite(r)) throw Error(`Invalid non-finite coefficient "${r}" in sum().`);
|
|
527
|
+
let t = (n.get(e) ?? 0) + r;
|
|
528
|
+
if (!Number.isFinite(t)) throw Error("Coefficient accumulation overflows finite floating-point range in sum().");
|
|
529
|
+
n.set(e, t);
|
|
490
530
|
}
|
|
491
|
-
r
|
|
492
|
-
|
|
531
|
+
let i = r + t.constant;
|
|
532
|
+
if (!Number.isFinite(i)) throw Error("Constant accumulation overflows finite floating-point range in sum().");
|
|
533
|
+
r = i;
|
|
534
|
+
} else if (typeof e == "object" && o(e)) {
|
|
493
535
|
let t = e;
|
|
536
|
+
if (!Number.isFinite(t.constant)) throw Error(`Invalid non-finite constant "${t.constant}" in sum().`);
|
|
494
537
|
for (let [e, r] of t.terms) {
|
|
495
|
-
|
|
496
|
-
n.
|
|
538
|
+
if (!Number.isFinite(r)) throw Error(`Invalid non-finite coefficient "${r}" in sum().`);
|
|
539
|
+
let t = (n.get(e) ?? 0) + r;
|
|
540
|
+
if (!Number.isFinite(t)) throw Error("Coefficient accumulation overflows finite floating-point range in sum().");
|
|
541
|
+
n.set(e, t);
|
|
497
542
|
}
|
|
498
|
-
r
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
543
|
+
let i = r + t.constant;
|
|
544
|
+
if (!Number.isFinite(i)) throw Error("Constant accumulation overflows finite floating-point range in sum().");
|
|
545
|
+
r = i;
|
|
546
|
+
} else if (typeof e == "object" && s(e)) {
|
|
547
|
+
let t = e, r = (n.get(t) ?? 0) + 1;
|
|
548
|
+
if (!Number.isFinite(r)) throw Error("Coefficient accumulation overflows finite floating-point range in sum().");
|
|
549
|
+
n.set(t, r);
|
|
502
550
|
} else throw Error("Unsupported item in sum(): expected a number, Var, or LinExpr.");
|
|
503
551
|
}
|
|
504
552
|
}
|
|
553
|
+
function d(e, t = 0) {
|
|
554
|
+
if (e != null) {
|
|
555
|
+
if (typeof e == "number") {
|
|
556
|
+
u(e);
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
if (typeof e == "object") {
|
|
560
|
+
if (c(e)) {
|
|
561
|
+
u(e);
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
if (!(e instanceof String) && !(e instanceof Map) && Symbol.iterator in e && typeof e[Symbol.iterator] == "function") {
|
|
565
|
+
if (t >= 2) throw Error("Nested containers deeper than 2D are not supported in sum().");
|
|
566
|
+
for (let n of e) d(n, t + 1);
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
if (l(e)) {
|
|
570
|
+
if (t >= 2) throw Error("Nested containers deeper than 2D are not supported in sum().");
|
|
571
|
+
if (Object.getOwnPropertySymbols(e).length > 0) throw Error("Symbol keys are not supported in sum().");
|
|
572
|
+
for (let n of Object.keys(e)) d(e[n], t + 1);
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
u(e);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
505
579
|
if (typeof e == "number") {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
580
|
+
if (typeof t != "function") throw Error("sum(count, mapFn) requires a mapping function as the second argument.");
|
|
581
|
+
if (!Number.isInteger(e) || e < 0) throw Error("sum(count, mapFn) requires a non-negative integer count.");
|
|
582
|
+
let n = e;
|
|
583
|
+
for (let e = 0; e < n; e++) d(t(e, e), 0);
|
|
584
|
+
} else if (typeof e == "object" && e && !(e instanceof String) && (!(e instanceof Map) || typeof t == "function") && Symbol.iterator in e && typeof e[Symbol.iterator] == "function") {
|
|
509
585
|
let n = 0;
|
|
510
|
-
for (let r of e)
|
|
511
|
-
}
|
|
586
|
+
for (let r of e) t ? d(t(r, n++), 0) : d(r, 1);
|
|
587
|
+
} else if (l(e)) {
|
|
588
|
+
if (Object.getOwnPropertySymbols(e).length > 0) throw Error("Symbol keys are not supported in sum().");
|
|
589
|
+
let n = 0;
|
|
590
|
+
for (let r of Object.keys(e)) {
|
|
591
|
+
let i = e[r];
|
|
592
|
+
t ? d(t(i, n++), 0) : d(i, 1);
|
|
593
|
+
}
|
|
594
|
+
} else throw Error("Unsupported item in sum(): expected an Iterable, Record, or (count, mapFn).");
|
|
512
595
|
for (let [e, t] of n) t === 0 && n.delete(e);
|
|
513
|
-
return new
|
|
596
|
+
return new C(n, r);
|
|
514
597
|
}
|
|
515
|
-
function
|
|
598
|
+
function T(e, t) {
|
|
516
599
|
let n = /* @__PURE__ */ new Map(), r = 0;
|
|
517
600
|
function i(e) {
|
|
518
|
-
return typeof e == "object" && !!e && !(e instanceof
|
|
601
|
+
return typeof e == "object" && !!e && !(e instanceof y) && typeof e.id == "number" && typeof e.name == "string" && typeof e.lb == "number" && typeof e.ub == "number" && typeof e.type == "string" && typeof e.mul == "function" && typeof e.le == "function";
|
|
519
602
|
}
|
|
520
603
|
function a(e) {
|
|
521
|
-
return i(e) || e instanceof
|
|
604
|
+
return i(e) || e instanceof C || e instanceof S;
|
|
522
605
|
}
|
|
523
606
|
function o(e, t, a) {
|
|
524
607
|
if (!Number.isFinite(e)) throw Error(`Invalid non-finite coefficient "${e}" in dot() at '${a || "root"}'.`);
|
|
525
|
-
if (t instanceof
|
|
526
|
-
if (t instanceof
|
|
608
|
+
if (t instanceof S) throw Error(`Quadratic expressions are not supported in dot() at '${a || "root"}': dot() produces a linear expression (LinExpr).`);
|
|
609
|
+
if (t instanceof C) {
|
|
527
610
|
if (!Number.isFinite(t.constant)) throw Error(`Invalid non-finite constant "${t.constant}" in dot() at '${a || "root"}'.`);
|
|
528
611
|
let i = e === 0 || t.constant === 0 ? 0 : e * t.constant;
|
|
529
612
|
if (e !== 0 && t.constant !== 0 && i === 0) throw Error("Constant multiplication underflows to zero.");
|
|
@@ -547,7 +630,7 @@ function w(e, t) {
|
|
|
547
630
|
} else throw Error(`Cannot multiply number by non-variable/expression operand in dot() at '${a || "root"}'.`);
|
|
548
631
|
}
|
|
549
632
|
function s(e) {
|
|
550
|
-
return typeof e == "object" && !!e && !Array.isArray(e) && !a(e) && !(e instanceof
|
|
633
|
+
return typeof e == "object" && !!e && !Array.isArray(e) && !a(e) && !(e instanceof y) && e.kind !== "constraint";
|
|
551
634
|
}
|
|
552
635
|
function c(e, t, n = "") {
|
|
553
636
|
if (e === void 0 || t === void 0 || e === null || t === null) throw Error(`Nullish or undefined operand encountered in dot() at '${n || "root"}'.`);
|
|
@@ -595,39 +678,39 @@ function w(e, t) {
|
|
|
595
678
|
}
|
|
596
679
|
c(e, t);
|
|
597
680
|
for (let [e, t] of n) t === 0 && n.delete(e);
|
|
598
|
-
return new
|
|
681
|
+
return new C(n, r);
|
|
599
682
|
}
|
|
600
683
|
//#endregion
|
|
601
684
|
//#region src/modeler/validation.ts
|
|
602
|
-
var
|
|
603
|
-
function
|
|
604
|
-
if (e instanceof
|
|
605
|
-
else if (e instanceof
|
|
606
|
-
let r = e.ownerModel, i =
|
|
685
|
+
var E = /* @__PURE__ */ new WeakMap(), D = /* @__PURE__ */ new WeakMap(), O = /* @__PURE__ */ new WeakMap();
|
|
686
|
+
function k(e, t, n) {
|
|
687
|
+
if (e instanceof f) for (let r of e.children) k(r, t, n);
|
|
688
|
+
else if (e instanceof y) {
|
|
689
|
+
let r = e.ownerModel, i = D.get(e);
|
|
607
690
|
(r !== t || i !== t) && (n && n.push(() => {
|
|
608
|
-
e.ownerModel = r, i ?
|
|
609
|
-
}), e.ownerModel = t,
|
|
691
|
+
e.ownerModel = r, i ? D.set(e, i) : D.delete(e);
|
|
692
|
+
}), e.ownerModel = t, D.set(e, t));
|
|
610
693
|
}
|
|
611
694
|
}
|
|
612
|
-
function
|
|
613
|
-
let n =
|
|
695
|
+
function ee(e, t) {
|
|
696
|
+
let n = E.get(e);
|
|
614
697
|
if (n && n !== t) throw Error(`Variable "${e.name}" already belongs to model "${n.name}" and cannot be added to model "${t.name}".`);
|
|
615
|
-
|
|
698
|
+
E.set(e, t);
|
|
616
699
|
}
|
|
617
|
-
function
|
|
618
|
-
let n =
|
|
700
|
+
function te(e, t) {
|
|
701
|
+
let n = O.get(e);
|
|
619
702
|
if (n) throw Error(n === t ? `Constraint "${e.name}" is already registered in model "${t.name}".` : `Constraint "${e.name}" already belongs to model "${n.name}" and cannot be added to model "${t.name}".`);
|
|
620
|
-
let r =
|
|
703
|
+
let r = D.get(e);
|
|
621
704
|
if (r && r !== t) throw Error(`Constraint "${e.name}" already belongs to model "${r.name}" and cannot be added to model "${t.name}".`);
|
|
622
|
-
return
|
|
705
|
+
return O.set(e, t), D.set(e, t), r;
|
|
623
706
|
}
|
|
624
|
-
function
|
|
625
|
-
|
|
707
|
+
function ne(e, t) {
|
|
708
|
+
E.get(e) === t && E.delete(e);
|
|
626
709
|
}
|
|
627
|
-
function
|
|
628
|
-
|
|
710
|
+
function re(e, t, n) {
|
|
711
|
+
O.get(e) === t && O.delete(e), D.get(e) === t && (n ? D.set(e, n) : D.delete(e));
|
|
629
712
|
}
|
|
630
|
-
var
|
|
713
|
+
var ie = 1e-6;
|
|
631
714
|
function A(e) {
|
|
632
715
|
if (typeof e.lb != "number" || Number.isNaN(e.lb)) throw Error(`Variable "${e.name}" has invalid lower bound: ${e.lb} (NaN or non-numeric bound is not allowed).`);
|
|
633
716
|
if (e.lb === Infinity) throw Error(`Variable "${e.name}" has invalid lower bound: +Infinity is not allowed as a lower bound.`);
|
|
@@ -637,14 +720,14 @@ function A(e) {
|
|
|
637
720
|
if (e.initialValue !== void 0) {
|
|
638
721
|
if (typeof e.initialValue != "number" || !Number.isFinite(e.initialValue)) throw Error(`Variable "${e.name}" has invalid initialValue: ${String(e.initialValue)} (initialValue must be a finite number).`);
|
|
639
722
|
let t = e.type === "Binary" ? Math.max(0, e.lb) : e.lb, n = e.type === "Binary" ? Math.min(1, e.ub) : e.ub;
|
|
640
|
-
if (e.initialValue < t - 1e-6 || e.initialValue > n + 1e-6) throw Error(`Variable "${e.name}" has initialValue (${e.initialValue}) outside its bounds [${t}, ${n}] (tolerance ${
|
|
723
|
+
if (e.initialValue < t - 1e-6 || e.initialValue > n + 1e-6) throw Error(`Variable "${e.name}" has initialValue (${e.initialValue}) outside its bounds [${t}, ${n}] (tolerance ${ie}).`);
|
|
641
724
|
if (e.type === "Integer" || e.type === "Binary") {
|
|
642
725
|
let r = Math.round(e.initialValue);
|
|
643
|
-
if (Math.abs(e.initialValue - r) > 1e-6 || r < t || r > n) throw Error(`Variable "${e.name}" of type "${e.type}" has non-integral or out-of-domain initialValue: ${e.initialValue} (must be within ${
|
|
726
|
+
if (Math.abs(e.initialValue - r) > 1e-6 || r < t || r > n) throw Error(`Variable "${e.name}" of type "${e.type}" has non-integral or out-of-domain initialValue: ${e.initialValue} (must be within ${ie} of an integer in [${t}, ${n}]).`);
|
|
644
727
|
}
|
|
645
728
|
}
|
|
646
729
|
}
|
|
647
|
-
function
|
|
730
|
+
function ae(e) {
|
|
648
731
|
if (e.initialValue === void 0) return;
|
|
649
732
|
if (A(e), e.type === "Integer" || e.type === "Binary") {
|
|
650
733
|
let t = Math.round(e.initialValue);
|
|
@@ -653,8 +736,8 @@ function ie(e) {
|
|
|
653
736
|
let t = Math.min(e.ub, Math.max(e.lb, e.initialValue));
|
|
654
737
|
return Object.is(t, -0) ? 0 : t;
|
|
655
738
|
}
|
|
656
|
-
function
|
|
657
|
-
if (e instanceof
|
|
739
|
+
function oe(e, t, n) {
|
|
740
|
+
if (e instanceof S) {
|
|
658
741
|
if (!Number.isFinite(e.constant)) throw Error(`Objective function has invalid constant: ${e.constant}. Constant must be a finite number.`);
|
|
659
742
|
for (let [r, i] of e.linearTerms) {
|
|
660
743
|
if (!n(r)) throw Error(`Variable "${r.name}" in objective function does not belong to model "${t}". All variables must belong to the model by object identity.`);
|
|
@@ -681,13 +764,13 @@ function j(e, t, n, r = e.name) {
|
|
|
681
764
|
if (!Number.isFinite(a)) throw Error(`Variable "${i.name}" in constraint "${r}" has invalid coefficient: ${a}. Coefficients must be finite numbers.`);
|
|
682
765
|
}
|
|
683
766
|
}
|
|
684
|
-
function
|
|
685
|
-
if (e instanceof
|
|
767
|
+
function se(e, t, n, r, i, a) {
|
|
768
|
+
if (e instanceof d) {
|
|
686
769
|
if (!i(e)) throw Error(`Boolean variable "${e.name}" in logical constraint "${t}" does not belong to model "${n}".`);
|
|
687
|
-
} else if (e instanceof
|
|
688
|
-
else if (e instanceof
|
|
770
|
+
} else if (e instanceof f) for (let o of e.children) se(o, t, n, r, i, a);
|
|
771
|
+
else if (e instanceof y) {
|
|
689
772
|
if (a) {
|
|
690
|
-
let r =
|
|
773
|
+
let r = D.get(e) ?? e.ownerModel ?? void 0;
|
|
691
774
|
if (r && r !== a) throw Error(`Constraint "${e.name}" embedded in logical constraint "${t}" already belongs to model "${r.name ?? "another model"}" and cannot be added to model "${n}".`);
|
|
692
775
|
}
|
|
693
776
|
if (!Number.isFinite(e.rhs)) throw Error(`Constraint "${e.name}" embedded in logical constraint "${t}" has invalid RHS: ${e.rhs}.`);
|
|
@@ -698,11 +781,11 @@ function M(e, t, n, r, i, a) {
|
|
|
698
781
|
}
|
|
699
782
|
}
|
|
700
783
|
}
|
|
701
|
-
function
|
|
784
|
+
function ce(e) {
|
|
702
785
|
let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set();
|
|
703
786
|
for (let r of e.variables) {
|
|
704
787
|
A(r);
|
|
705
|
-
let i =
|
|
788
|
+
let i = E.get(r);
|
|
706
789
|
if (i && i !== e || t.has(r.name) || e.getVarByName(r.name) !== r) throw Error(`Variable "${r.name}" is duplicated or not canonically registered in model "${e.name}".`);
|
|
707
790
|
t.add(r.name), n.add(r);
|
|
708
791
|
}
|
|
@@ -723,18 +806,18 @@ function oe(e) {
|
|
|
723
806
|
a.add(t.name);
|
|
724
807
|
}
|
|
725
808
|
for (let t of e.constraints) {
|
|
726
|
-
let n =
|
|
809
|
+
let n = D.get(t);
|
|
727
810
|
if (n && n !== e || e.getConstraintByName(t.name) !== t) throw Error(`Constraint "${t.name}" is duplicated or not canonically registered in model "${e.name}".`);
|
|
728
811
|
}
|
|
729
812
|
for (let t of e.logicalConstraints) if (e.getLogicalConstraintByName(t.name) !== t) throw Error(`Logical constraint "${t.name}" is duplicated or not canonically registered in model "${e.name}".`);
|
|
730
|
-
e.objectiveExpr &&
|
|
813
|
+
e.objectiveExpr && oe(e.objectiveExpr, e.name, (e) => n.has(e));
|
|
731
814
|
for (let t of e.constraints) j(t, e.name, (e) => n.has(e));
|
|
732
|
-
for (let t of e.logicalConstraints)
|
|
815
|
+
for (let t of e.logicalConstraints) se(t.expr, t.name, e.name, (e) => n.has(e), (e) => i.has(e), e);
|
|
733
816
|
}
|
|
734
817
|
//#endregion
|
|
735
818
|
//#region src/modeler/variable.ts
|
|
736
|
-
var
|
|
737
|
-
function
|
|
819
|
+
var le = 0;
|
|
820
|
+
function ue(e) {
|
|
738
821
|
if (e === void 0) return "Continuous";
|
|
739
822
|
if (typeof e == "string") {
|
|
740
823
|
let t = e.toLowerCase();
|
|
@@ -744,7 +827,7 @@ function ce(e) {
|
|
|
744
827
|
}
|
|
745
828
|
throw Error(`Invalid variable type "${String(e)}": expected "Continuous", "Integer", or "Binary".`);
|
|
746
829
|
}
|
|
747
|
-
var
|
|
830
|
+
var M = class {
|
|
748
831
|
id;
|
|
749
832
|
_name;
|
|
750
833
|
prefix;
|
|
@@ -757,9 +840,9 @@ var N = class {
|
|
|
757
840
|
value = null;
|
|
758
841
|
reducedCost = null;
|
|
759
842
|
constructor(e = {}) {
|
|
760
|
-
this.id = ++
|
|
843
|
+
this.id = ++le;
|
|
761
844
|
let t = typeof e.name == "string" ? e.name.trim() : "", n = typeof e.prefix == "string" ? e.prefix.trim() : "";
|
|
762
|
-
this.prefix = n.length > 0 ? n : "x", this.hasExplicitName = t.length > 0, this._name = this.hasExplicitName ? t : `${this.prefix}_${this.id}`, this._type =
|
|
845
|
+
this.prefix = n.length > 0 ? n : "x", this.hasExplicitName = t.length > 0, this._name = this.hasExplicitName ? t : `${this.prefix}_${this.id}`, this._type = ue(e.type), this._type === "Binary" ? (this._lb = 0, this._ub = 1) : (this._lb = e.lb === void 0 ? 0 : e.lb, this._ub = e.ub === void 0 ? Infinity : e.ub), this._initialValue = e.initialValue === void 0 ? void 0 : Object.is(e.initialValue, -0) ? 0 : e.initialValue, this._initialValue !== void 0 && A(this);
|
|
763
846
|
}
|
|
764
847
|
get name() {
|
|
765
848
|
return this._name;
|
|
@@ -768,7 +851,7 @@ var N = class {
|
|
|
768
851
|
return this._type;
|
|
769
852
|
}
|
|
770
853
|
set type(e) {
|
|
771
|
-
let t =
|
|
854
|
+
let t = ue(e);
|
|
772
855
|
this._type !== t && (this._type = t, this.ownerModel?.notifyMutation?.());
|
|
773
856
|
}
|
|
774
857
|
get lb() {
|
|
@@ -794,31 +877,37 @@ var N = class {
|
|
|
794
877
|
this._name = e;
|
|
795
878
|
}
|
|
796
879
|
mul(e) {
|
|
797
|
-
return typeof e == "number" ? new
|
|
880
|
+
return typeof e == "number" ? new C(/* @__PURE__ */ new Map([[this, 1]]), 0).mul(e) : new S(/* @__PURE__ */ new Map([[this, 1]]), /* @__PURE__ */ new Map(), 0).mul(e);
|
|
798
881
|
}
|
|
799
882
|
add(e) {
|
|
800
|
-
return e instanceof
|
|
883
|
+
return e instanceof S ? e.add(this) : new C(/* @__PURE__ */ new Map([[this, 1]]), 0).add(e);
|
|
801
884
|
}
|
|
802
885
|
sub(e) {
|
|
803
|
-
return e instanceof
|
|
886
|
+
return e instanceof S ? e.neg().add(this) : new C(/* @__PURE__ */ new Map([[this, 1]]), 0).sub(e);
|
|
804
887
|
}
|
|
805
888
|
neg() {
|
|
806
889
|
return this.mul(-1);
|
|
807
890
|
}
|
|
808
891
|
le(e, t) {
|
|
809
|
-
return new
|
|
892
|
+
return new C(/* @__PURE__ */ new Map([[this, 1]]), 0).le(e, t);
|
|
810
893
|
}
|
|
811
894
|
ge(e, t) {
|
|
812
|
-
return new
|
|
895
|
+
return new C(/* @__PURE__ */ new Map([[this, 1]]), 0).ge(e, t);
|
|
813
896
|
}
|
|
814
897
|
eq(e, t) {
|
|
815
|
-
return new
|
|
898
|
+
return new C(/* @__PURE__ */ new Map([[this, 1]]), 0).eq(e, t);
|
|
816
899
|
}
|
|
817
900
|
toString() {
|
|
818
901
|
return this.name;
|
|
819
902
|
}
|
|
820
|
-
}
|
|
821
|
-
|
|
903
|
+
};
|
|
904
|
+
//#endregion
|
|
905
|
+
//#region src/modeler/parser.ts
|
|
906
|
+
function N(e) {
|
|
907
|
+
return typeof e == "object" && !!e && e.kind === "container";
|
|
908
|
+
}
|
|
909
|
+
var de = /^(?:[0-9]+(?:\.[0-9]+)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;
|
|
910
|
+
function fe(e, t) {
|
|
822
911
|
let n = [], r = 0, i = e.length;
|
|
823
912
|
for (; r < i;) {
|
|
824
913
|
let a = e[r];
|
|
@@ -857,6 +946,10 @@ function ue(e, t) {
|
|
|
857
946
|
type: "RPAREN",
|
|
858
947
|
value: ")"
|
|
859
948
|
}), r++;
|
|
949
|
+
else if (a === ",") n.push({
|
|
950
|
+
type: "COMMA",
|
|
951
|
+
value: ","
|
|
952
|
+
}), r++;
|
|
860
953
|
else if (a === "<" || a === ">" || a === "=") {
|
|
861
954
|
let t = a;
|
|
862
955
|
r + 1 < i && (e[r + 1] === "=" || e[r + 1] === "<" || e[r + 1] === ">") ? (t += e[r + 1], r += 2) : r++, n.push({
|
|
@@ -874,7 +967,7 @@ function ue(e, t) {
|
|
|
874
967
|
for (; r < i && (e[r] === "." || e[r] === "e" || e[r] === "E" || /[0-9]/.test(e[r]));) a += e[r++];
|
|
875
968
|
}
|
|
876
969
|
} else for (; r < i && (e[r] === "." || /[0-9]/.test(e[r]));) a += e[r++];
|
|
877
|
-
if (!
|
|
970
|
+
if (!de.test(a)) throw Error(`Invalid numeric literal '${a}' at position ${t} in: "${e}"`);
|
|
878
971
|
let o = Number(a);
|
|
879
972
|
if (!Number.isFinite(o)) throw Error(`Numeric literal '${a}' overflows finite floating-point range in: "${e}"`);
|
|
880
973
|
if (o === 0 && !/^[0.]+(?:[eE][+-]?\d+)?$/.test(a)) throw Error(`Numeric literal '${a}' underflows to zero at position ${t} in: "${e}"`);
|
|
@@ -901,12 +994,205 @@ function ue(e, t) {
|
|
|
901
994
|
}
|
|
902
995
|
return n;
|
|
903
996
|
}
|
|
904
|
-
|
|
997
|
+
function pe(e) {
|
|
998
|
+
return e instanceof S && e.quadTerms.size === 0 ? new C(e.linearTerms, e.constant) : e;
|
|
999
|
+
}
|
|
1000
|
+
function me(e) {
|
|
1001
|
+
return typeof e == "number" || e instanceof M || e instanceof C || e instanceof S || z(e);
|
|
1002
|
+
}
|
|
1003
|
+
function he(e) {
|
|
1004
|
+
return typeof e == "number" ? new C(/* @__PURE__ */ new Map(), e) : e instanceof M || "id" in e && !("terms" in e) && !("quadTerms" in e) ? new C(/* @__PURE__ */ new Map([[e, 1]]), 0) : e.clone();
|
|
1005
|
+
}
|
|
1006
|
+
function ge(e, t, n) {
|
|
1007
|
+
if (typeof e == "number" && typeof t == "number") {
|
|
1008
|
+
if (n === "+") {
|
|
1009
|
+
let n = e + t;
|
|
1010
|
+
if (!Number.isFinite(n)) throw Error(`Invalid non-finite constant "${n}" in expression.`);
|
|
1011
|
+
return n;
|
|
1012
|
+
}
|
|
1013
|
+
if (n === "-") {
|
|
1014
|
+
let n = e - t;
|
|
1015
|
+
if (!Number.isFinite(n)) throw Error(`Invalid non-finite constant "${n}" in expression.`);
|
|
1016
|
+
return n;
|
|
1017
|
+
}
|
|
1018
|
+
if (n === "*") {
|
|
1019
|
+
let n = e * t;
|
|
1020
|
+
if (e !== 0 && t !== 0 && n === 0) throw Error("Constant multiplication underflows to zero.");
|
|
1021
|
+
if (!Number.isFinite(n)) throw Error(`Invalid non-finite constant "${n}" in expression.`);
|
|
1022
|
+
return n;
|
|
1023
|
+
}
|
|
1024
|
+
if (t === 0) throw Error("Division by zero");
|
|
1025
|
+
let r = 1 / t * e;
|
|
1026
|
+
if (e !== 0 && r === 0) throw Error("Constant multiplication underflows to zero.");
|
|
1027
|
+
if (!Number.isFinite(r)) throw Error(`Invalid non-finite constant "${r}" in expression.`);
|
|
1028
|
+
return r;
|
|
1029
|
+
}
|
|
1030
|
+
let r = he(e), i = he(t), a;
|
|
1031
|
+
a = n === "+" ? r.add(i) : n === "-" ? r.sub(i) : n === "*" ? r.mul(i) : r.div(i);
|
|
1032
|
+
let o = pe(a);
|
|
1033
|
+
return B(o), o;
|
|
1034
|
+
}
|
|
1035
|
+
function P(e, t) {
|
|
1036
|
+
if (Array.isArray(e)) {
|
|
1037
|
+
let n = Array(e.length);
|
|
1038
|
+
for (let r = 0; r < e.length; r++) {
|
|
1039
|
+
let i = e[r];
|
|
1040
|
+
n[r] = me(i) ? t(i) : P(i, t);
|
|
1041
|
+
}
|
|
1042
|
+
return n;
|
|
1043
|
+
}
|
|
1044
|
+
let n = Object.create(null);
|
|
1045
|
+
for (let r of Object.keys(e)) {
|
|
1046
|
+
let i = e[r];
|
|
1047
|
+
n[r] = me(i) ? t(i) : P(i, t);
|
|
1048
|
+
}
|
|
1049
|
+
return n;
|
|
1050
|
+
}
|
|
1051
|
+
function F(e, t, n, r = "") {
|
|
1052
|
+
let i = me(e), a = me(t);
|
|
1053
|
+
if (i && a) return ge(e, t, n);
|
|
1054
|
+
if (i || a) throw Error(`Dimension mismatch in template expression at '${r || "root"}': cannot combine scalar element with sub-container.`);
|
|
1055
|
+
if (Array.isArray(e) || Array.isArray(t)) {
|
|
1056
|
+
if (Array.isArray(e) && Array.isArray(t)) {
|
|
1057
|
+
if (e.length !== t.length) throw Error(`Array length mismatch in template expression at '${r || "root"}': received lengths ${e.length} and ${t.length}.`);
|
|
1058
|
+
let i = Array(e.length);
|
|
1059
|
+
for (let a = 0; a < e.length; a++) i[a] = F(e[a], t[a], n, r ? `${r}[${a}]` : `[${a}]`);
|
|
1060
|
+
return i;
|
|
1061
|
+
}
|
|
1062
|
+
let i = Array.isArray(e) ? e : t, a = Array.isArray(e) ? t : e, o = Object.keys(a);
|
|
1063
|
+
if (o.length === i.length && o.every((e) => /^(?:0|[1-9]\d*)$/.test(e))) {
|
|
1064
|
+
let o = [];
|
|
1065
|
+
for (let e = 0; e < i.length; e++) Object.prototype.hasOwnProperty.call(a, e) || o.push(e);
|
|
1066
|
+
if (o.length > 0) throw Error(`Key mismatch in template expression at '${r || "root"}': missing indices [${o.join(", ")}] in numeric record.`);
|
|
1067
|
+
let s = Array(i.length);
|
|
1068
|
+
for (let a = 0; a < i.length; a++) {
|
|
1069
|
+
let i = e[a], o = t[a];
|
|
1070
|
+
s[a] = F(i, o, n, r ? `${r}[${a}]` : `[${a}]`);
|
|
1071
|
+
}
|
|
1072
|
+
return s;
|
|
1073
|
+
}
|
|
1074
|
+
throw o.length > 0 && o.every((e) => /^(?:0|[1-9]\d*)$/.test(e)) ? Error(`Array length mismatch in template expression at '${r || "root"}': array has length ${i.length}, but object has ${o.length} indices.`) : Error(`Type mismatch in template expression at '${r || "root"}': one operand is an Array while the other is an Object with keys [${o.slice(0, 5).join(", ")}].`);
|
|
1075
|
+
}
|
|
1076
|
+
let o = e, s = t, c = Object.keys(o), l = Object.keys(s), u = c.filter((e) => !Object.prototype.hasOwnProperty.call(s, e)), d = l.filter((e) => !Object.prototype.hasOwnProperty.call(o, e));
|
|
1077
|
+
if (u.length > 0 || d.length > 0) {
|
|
1078
|
+
let e = [];
|
|
1079
|
+
throw u.length > 0 && e.push(`missing in second operand: [${u.join(", ")}]`), d.length > 0 && e.push(`missing in first operand: [${d.join(", ")}]`), Error(`Key mismatch in template expression at '${r || "root"}': ${e.join("; ")}.`);
|
|
1080
|
+
}
|
|
1081
|
+
let f = Object.create(null);
|
|
1082
|
+
for (let e of c) f[e] = F(o[e], s[e], n, r ? `${r}.${e}` : e);
|
|
1083
|
+
return f;
|
|
1084
|
+
}
|
|
1085
|
+
function I(e, t, n) {
|
|
1086
|
+
let r = N(e), i = N(t);
|
|
1087
|
+
if (!r && !i) return ge(e, t, n);
|
|
1088
|
+
if (r && !i) return {
|
|
1089
|
+
kind: "container",
|
|
1090
|
+
data: P(e.data, (e) => ge(e, t, n)),
|
|
1091
|
+
fromNonArrayIterable: e.fromNonArrayIterable
|
|
1092
|
+
};
|
|
1093
|
+
if (!r && i) return {
|
|
1094
|
+
kind: "container",
|
|
1095
|
+
data: P(t.data, (t) => ge(e, t, n)),
|
|
1096
|
+
fromNonArrayIterable: t.fromNonArrayIterable
|
|
1097
|
+
};
|
|
1098
|
+
let a = e, o = t;
|
|
1099
|
+
return {
|
|
1100
|
+
kind: "container",
|
|
1101
|
+
data: F(a.data, o.data, n),
|
|
1102
|
+
fromNonArrayIterable: a.fromNonArrayIterable || o.fromNonArrayIterable
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
1105
|
+
function _e(e) {
|
|
1106
|
+
return typeof e == "number" ? -e : N(e) ? {
|
|
1107
|
+
kind: "container",
|
|
1108
|
+
data: P(e.data, (e) => typeof e == "number" ? -e : he(e).neg()),
|
|
1109
|
+
fromNonArrayIterable: e.fromNonArrayIterable
|
|
1110
|
+
} : e.neg();
|
|
1111
|
+
}
|
|
1112
|
+
function ve(e, t) {
|
|
1113
|
+
let n = e instanceof S, r = n ? e.quadTerms.size : 0, i = n ? e.linearTerms.size : e.terms.size;
|
|
1114
|
+
if (r === 0 && i === 0) {
|
|
1115
|
+
let n = e.constant ** +t;
|
|
1116
|
+
if (e.constant !== 0 && t > 0 && n === 0) throw Error("Constant exponentiation underflows to zero.");
|
|
1117
|
+
return new C(/* @__PURE__ */ new Map(), n);
|
|
1118
|
+
}
|
|
1119
|
+
if (t === 0) return new C(/* @__PURE__ */ new Map(), 1);
|
|
1120
|
+
if (t === 1) return e;
|
|
1121
|
+
if (t === 2) return e.mul(e);
|
|
1122
|
+
throw Error(`Exponent ${t} creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)`);
|
|
1123
|
+
}
|
|
1124
|
+
function L(e) {
|
|
1125
|
+
if (typeof e != "object" || !e || Array.isArray(e) || z(e) || V(e)) return !1;
|
|
1126
|
+
let t = Object.getPrototypeOf(e);
|
|
1127
|
+
return t === Object.prototype || t === null;
|
|
1128
|
+
}
|
|
1129
|
+
function ye(e) {
|
|
1130
|
+
if (typeof e == "number") {
|
|
1131
|
+
if (!Number.isFinite(e)) throw Error(`Invalid numeric value "${e}" in template expression: interpolated numbers must be finite.`);
|
|
1132
|
+
return e;
|
|
1133
|
+
}
|
|
1134
|
+
if (V(e)) throw Error("Cannot interpolate a constraint comparison (<=, >=, ==) inside a template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
1135
|
+
if (z(e)) return B(e), e instanceof M || "id" in e && !("terms" in e) && !("quadTerms" in e) ? e : e.clone();
|
|
1136
|
+
throw Error("Unsupported interpolation value in template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
1137
|
+
}
|
|
1138
|
+
function R(e) {
|
|
1139
|
+
return typeof e == "object" && !!e && !(e instanceof String) && !(e instanceof Map) && !z(e) && !V(e) && Symbol.iterator in e && typeof e[Symbol.iterator] == "function";
|
|
1140
|
+
}
|
|
1141
|
+
function be(e, t = 0) {
|
|
1142
|
+
if (Array.isArray(e)) {
|
|
1143
|
+
let n = !1, r = Array(e.length);
|
|
1144
|
+
for (let i = 0; i < e.length; i++) {
|
|
1145
|
+
if (!(i in e)) throw Error(`Unsupported interpolation value in template expression: sparse array hole at index ${i}.`);
|
|
1146
|
+
let a = e[i];
|
|
1147
|
+
if (Array.isArray(a) || L(a) || R(a)) {
|
|
1148
|
+
if (t >= 1) throw Error("Nested containers deeper than 2D are not supported in template expressions.");
|
|
1149
|
+
let e = be(a, t + 1);
|
|
1150
|
+
e.fromNonArrayIterable && (n = !0), r[i] = e.data;
|
|
1151
|
+
} else r[i] = ye(a);
|
|
1152
|
+
}
|
|
1153
|
+
return {
|
|
1154
|
+
kind: "container",
|
|
1155
|
+
data: r,
|
|
1156
|
+
fromNonArrayIterable: n
|
|
1157
|
+
};
|
|
1158
|
+
}
|
|
1159
|
+
if (R(e)) return {
|
|
1160
|
+
kind: "container",
|
|
1161
|
+
data: Array.from(e).map((e) => {
|
|
1162
|
+
if (Array.isArray(e) || L(e) || R(e)) {
|
|
1163
|
+
if (t >= 1) throw Error("Nested containers deeper than 2D are not supported in template expressions.");
|
|
1164
|
+
return be(e, t + 1).data;
|
|
1165
|
+
}
|
|
1166
|
+
return ye(e);
|
|
1167
|
+
}),
|
|
1168
|
+
fromNonArrayIterable: !0
|
|
1169
|
+
};
|
|
1170
|
+
if (L(e)) {
|
|
1171
|
+
if (Object.getOwnPropertySymbols(e).length > 0) throw Error("Symbol keys are not supported in template expression at 'root'.");
|
|
1172
|
+
let n = !1, r = Object.create(null);
|
|
1173
|
+
for (let i of Object.keys(e)) {
|
|
1174
|
+
let a = e[i];
|
|
1175
|
+
if (Array.isArray(a) || L(a) || R(a)) {
|
|
1176
|
+
if (t >= 1) throw Error("Nested containers deeper than 2D are not supported in template expressions.");
|
|
1177
|
+
let e = be(a, t + 1);
|
|
1178
|
+
e.fromNonArrayIterable && (n = !0), r[i] = e.data;
|
|
1179
|
+
} else r[i] = ye(a);
|
|
1180
|
+
}
|
|
1181
|
+
return {
|
|
1182
|
+
kind: "container",
|
|
1183
|
+
data: r,
|
|
1184
|
+
fromNonArrayIterable: n
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
throw Error("Unsupported interpolation value in template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
1188
|
+
}
|
|
1189
|
+
var xe = class {
|
|
905
1190
|
tokens;
|
|
906
1191
|
pos = 0;
|
|
907
1192
|
resolver;
|
|
908
|
-
|
|
909
|
-
|
|
1193
|
+
templateCtx;
|
|
1194
|
+
constructor(e, t, n) {
|
|
1195
|
+
this.tokens = e, this.resolver = t, this.templateCtx = n;
|
|
910
1196
|
}
|
|
911
1197
|
peek() {
|
|
912
1198
|
return this.tokens[this.pos];
|
|
@@ -918,54 +1204,240 @@ var de = class {
|
|
|
918
1204
|
return t;
|
|
919
1205
|
}
|
|
920
1206
|
parseExpression() {
|
|
921
|
-
let e = this.
|
|
1207
|
+
let e = this.parseExpressionNode();
|
|
1208
|
+
if (N(e)) throw Error("Container expression (Array or Record) cannot be used directly as a scalar expression or constraint; wrap it in sum(...) or use dot(a, b).");
|
|
1209
|
+
return typeof e == "number" ? new C(/* @__PURE__ */ new Map(), e) : pe(e);
|
|
1210
|
+
}
|
|
1211
|
+
parseExpressionNode() {
|
|
1212
|
+
let e = this.parseTermNode();
|
|
922
1213
|
for (; this.pos < this.tokens.length;) {
|
|
923
1214
|
let t = this.peek();
|
|
924
1215
|
if (!t) break;
|
|
925
|
-
if (t.type === "PLUS") this.consume(), e = e
|
|
926
|
-
else if (t.type === "MINUS") this.consume(), e = e
|
|
1216
|
+
if (t.type === "PLUS") this.consume(), e = I(e, this.parseTermNode(), "+");
|
|
1217
|
+
else if (t.type === "MINUS") this.consume(), e = I(e, this.parseTermNode(), "-");
|
|
927
1218
|
else break;
|
|
928
1219
|
}
|
|
929
|
-
return e
|
|
1220
|
+
return N(e) || typeof e == "number" ? e : pe(e);
|
|
930
1221
|
}
|
|
931
|
-
|
|
932
|
-
let e = this.
|
|
1222
|
+
parseTermNode() {
|
|
1223
|
+
let e = this.parseFactorNode();
|
|
933
1224
|
for (; this.pos < this.tokens.length;) {
|
|
934
1225
|
let t = this.peek();
|
|
935
1226
|
if (!t) break;
|
|
936
|
-
if (t.type === "STAR") this.consume(), e = e
|
|
937
|
-
else if (t.type === "SLASH") this.consume(), e = e
|
|
1227
|
+
if (t.type === "STAR") this.consume(), e = I(e, this.parseFactorNode(), "*");
|
|
1228
|
+
else if (t.type === "SLASH") this.consume(), e = I(e, this.parseFactorNode(), "/");
|
|
938
1229
|
else break;
|
|
939
1230
|
}
|
|
940
1231
|
return e;
|
|
941
1232
|
}
|
|
942
|
-
|
|
1233
|
+
parseFactorNode() {
|
|
943
1234
|
let e = this.peek();
|
|
944
1235
|
if (!e) throw Error("Unexpected end of expression");
|
|
945
|
-
if (e.type === "PLUS") return this.consume(), this.
|
|
946
|
-
if (e.type === "MINUS") return this.consume(), this.
|
|
1236
|
+
if (e.type === "PLUS") return this.consume(), this.parseFactorNode();
|
|
1237
|
+
if (e.type === "MINUS") return this.consume(), _e(this.parseFactorNode());
|
|
947
1238
|
let t;
|
|
948
1239
|
if (e.type === "NUMBER") {
|
|
949
1240
|
this.consume();
|
|
950
1241
|
let n = e.numericValue ?? Number(e.value);
|
|
951
1242
|
if (this.peek()?.type === "IDENT" || this.peek()?.type === "LPAREN") {
|
|
952
|
-
let e;
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
return this.applyPower(e).mul(n);
|
|
958
|
-
}
|
|
959
|
-
t = new S(/* @__PURE__ */ new Map(), n);
|
|
960
|
-
} else if (e.type === "IDENT") {
|
|
961
|
-
this.consume();
|
|
962
|
-
let n = this.resolve(e.value);
|
|
963
|
-
t = n instanceof N || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new S(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
|
|
964
|
-
} else if (e.type === "LPAREN") this.consume("LPAREN"), t = this.parseExpression(), this.consume("RPAREN");
|
|
1243
|
+
let e = this.parsePrimaryNode();
|
|
1244
|
+
return I(this.applyPowerNode(e), n, "*");
|
|
1245
|
+
}
|
|
1246
|
+
t = n;
|
|
1247
|
+
} else if (e.type === "IDENT" || e.type === "LPAREN") t = this.parsePrimaryNode();
|
|
965
1248
|
else throw Error(`Unexpected token '${e.value}' in expression`);
|
|
966
|
-
return this.
|
|
1249
|
+
return this.applyPowerNode(t);
|
|
1250
|
+
}
|
|
1251
|
+
parsePrimaryNode() {
|
|
1252
|
+
if (this.peek()?.type === "IDENT") {
|
|
1253
|
+
let e = this.consume();
|
|
1254
|
+
return (e.value === "sum" || e.value === "dot") && this.peek()?.type === "LPAREN" ? this.parseFunctionCall(e.value) : this.resolveNode(e.value);
|
|
1255
|
+
}
|
|
1256
|
+
this.consume("LPAREN");
|
|
1257
|
+
let e = this.parseExpressionNode();
|
|
1258
|
+
return this.consume("RPAREN"), e;
|
|
1259
|
+
}
|
|
1260
|
+
parseFunctionCall(e) {
|
|
1261
|
+
this.consume("LPAREN");
|
|
1262
|
+
let t = 1;
|
|
1263
|
+
for (let n = this.pos; n < this.tokens.length && t > 0; n++) {
|
|
1264
|
+
let r = this.tokens[n];
|
|
1265
|
+
if (r.type === "LPAREN") t++;
|
|
1266
|
+
else if (r.type === "RPAREN") t--;
|
|
1267
|
+
else if (r.type === "COMP") throw Error(e === "sum" ? "Cannot sum a constraint comparison (<=, >=, ==) in sum(): expected a number, Var, LinExpr, or QuadExpr." : "Cannot use a constraint comparison (<=, >=, ==) in dot(): expected 1D or 2D Array or Record containers.");
|
|
1268
|
+
}
|
|
1269
|
+
if (this.peek()?.type === "RPAREN") throw this.consume("RPAREN"), Error(e === "sum" ? "sum() in template expression requires at least 1 argument." : "dot() in template expression requires exactly 2 arguments: dot(a, b).");
|
|
1270
|
+
if (e === "sum") {
|
|
1271
|
+
if (this.tokens[this.pos]?.type === "IDENT" && this.templateCtx?.rawContainerMap.has(this.tokens[this.pos].value) && this.tokens[this.pos + 1]?.type === "RPAREN") {
|
|
1272
|
+
let e = this.consume();
|
|
1273
|
+
this.consume("RPAREN");
|
|
1274
|
+
let t = this.templateCtx.rawContainerMap.get(e.value);
|
|
1275
|
+
return this.accumulateSumItems((e) => {
|
|
1276
|
+
e(t, 0);
|
|
1277
|
+
});
|
|
1278
|
+
}
|
|
1279
|
+
let e = this.pos, t = 0;
|
|
1280
|
+
for (; this.tokens[e]?.type === "LPAREN";) t++, e++;
|
|
1281
|
+
if (this.tokens[e]?.type === "IDENT" && this.templateCtx?.rawContainerMap.has(this.tokens[e].value)) {
|
|
1282
|
+
let n = this.tokens[e].value, r = e + 1, i = 0;
|
|
1283
|
+
for (; i < t && this.tokens[r]?.type === "RPAREN";) i++, r++;
|
|
1284
|
+
if (i === t && this.tokens[r]?.type === "COMMA") {
|
|
1285
|
+
this.pos = r + 1;
|
|
1286
|
+
let e = this.peek();
|
|
1287
|
+
if (!e || e.type !== "IDENT" || !this.templateCtx.functionMap.has(e.value)) throw Error("Second argument to sum() must be a mapping function: sum(itemsOrCount, mapFn).");
|
|
1288
|
+
if (this.consume(), this.peek()?.type === "COMMA") throw Error("sum() in template expression accepts at most 2 arguments: sum(container) or sum(itemsOrCount, mapFn).");
|
|
1289
|
+
return this.consume("RPAREN"), this.evalSumWithMapper(this.templateCtx.rawContainerMap.get(n), this.templateCtx.functionMap.get(e.value));
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
let n = this.parseExpressionNode();
|
|
1293
|
+
if (this.peek()?.type === "COMMA") {
|
|
1294
|
+
this.consume("COMMA");
|
|
1295
|
+
let e = this.peek();
|
|
1296
|
+
if (!e || e.type !== "IDENT" || !this.templateCtx?.functionMap.has(e.value)) throw Error("Second argument to sum() must be a mapping function: sum(itemsOrCount, mapFn).");
|
|
1297
|
+
if (this.consume(), this.peek()?.type === "COMMA") throw Error("sum() in template expression accepts at most 2 arguments: sum(container) or sum(itemsOrCount, mapFn).");
|
|
1298
|
+
this.consume("RPAREN");
|
|
1299
|
+
let t = this.templateCtx.functionMap.get(e.value);
|
|
1300
|
+
if (typeof n == "number") return this.evalSumWithMapper(n, t);
|
|
1301
|
+
if (!N(n) && n instanceof C && n.terms.size === 0) return this.evalSumWithMapper(n.constant, t);
|
|
1302
|
+
if (N(n)) return this.evalSumWithMapper(n.data, t);
|
|
1303
|
+
throw Error("Invalid first argument in sum(itemsOrCount, mapFn): expected an Iterable, Record, or non-negative integer count.");
|
|
1304
|
+
}
|
|
1305
|
+
return this.consume("RPAREN"), this.evalSumSingle(n);
|
|
1306
|
+
}
|
|
1307
|
+
let n = this.parseExpressionNode();
|
|
1308
|
+
if (this.peek()?.type !== "COMMA") throw Error("dot() in template expression requires exactly 2 arguments: dot(a, b).");
|
|
1309
|
+
this.consume("COMMA");
|
|
1310
|
+
let r = this.parseExpressionNode();
|
|
1311
|
+
if (this.peek()?.type === "COMMA") throw Error("dot() in template expression requires exactly 2 arguments: dot(a, b).");
|
|
1312
|
+
return this.consume("RPAREN"), this.evalDot(n, r);
|
|
1313
|
+
}
|
|
1314
|
+
accumulateSumItems(e) {
|
|
1315
|
+
let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), r = 0, i = (e, a = 0) => {
|
|
1316
|
+
if (e != null) {
|
|
1317
|
+
if (typeof e == "number") {
|
|
1318
|
+
if (!Number.isFinite(e)) throw Error(`Invalid non-finite number "${e}" in sum().`);
|
|
1319
|
+
let t = r + e;
|
|
1320
|
+
if (!Number.isFinite(t)) throw Error("Constant accumulation overflows finite floating-point range in sum().");
|
|
1321
|
+
r = t;
|
|
1322
|
+
return;
|
|
1323
|
+
}
|
|
1324
|
+
if (V(e)) throw Error("Cannot sum a constraint comparison (<=, >=, ==) in sum(): expected a number, Var, LinExpr, or QuadExpr.");
|
|
1325
|
+
if (e instanceof S || typeof e == "object" && e && "quadTerms" in e && e.quadTerms instanceof Map && "linearTerms" in e && e.linearTerms instanceof Map) {
|
|
1326
|
+
let i = e;
|
|
1327
|
+
B(i);
|
|
1328
|
+
let a = r + i.constant;
|
|
1329
|
+
if (!Number.isFinite(a)) throw Error("Constant accumulation overflows finite floating-point range in sum().");
|
|
1330
|
+
r = a;
|
|
1331
|
+
for (let [e, n] of i.linearTerms) {
|
|
1332
|
+
let r = (t.get(e) ?? 0) + n;
|
|
1333
|
+
if (!Number.isFinite(r)) throw Error("Coefficient accumulation overflows finite floating-point range in sum().");
|
|
1334
|
+
t.set(e, r);
|
|
1335
|
+
}
|
|
1336
|
+
for (let [e, t] of i.quadTerms) {
|
|
1337
|
+
let r = n.get(e);
|
|
1338
|
+
if (r) {
|
|
1339
|
+
let i = r.coeff + t.coeff;
|
|
1340
|
+
if (!Number.isFinite(i)) throw Error("Quadratic coefficient accumulation overflows finite floating-point range in sum().");
|
|
1341
|
+
n.set(e, {
|
|
1342
|
+
var1: t.var1,
|
|
1343
|
+
var2: t.var2,
|
|
1344
|
+
coeff: i
|
|
1345
|
+
});
|
|
1346
|
+
} else n.set(e, {
|
|
1347
|
+
var1: t.var1,
|
|
1348
|
+
var2: t.var2,
|
|
1349
|
+
coeff: t.coeff
|
|
1350
|
+
});
|
|
1351
|
+
}
|
|
1352
|
+
return;
|
|
1353
|
+
}
|
|
1354
|
+
if (e instanceof C || typeof e == "object" && e && "terms" in e && e.terms instanceof Map && typeof e.constant == "number") {
|
|
1355
|
+
let n = e;
|
|
1356
|
+
B(n);
|
|
1357
|
+
let i = r + n.constant;
|
|
1358
|
+
if (!Number.isFinite(i)) throw Error("Constant accumulation overflows finite floating-point range in sum().");
|
|
1359
|
+
r = i;
|
|
1360
|
+
for (let [e, r] of n.terms) {
|
|
1361
|
+
let n = (t.get(e) ?? 0) + r;
|
|
1362
|
+
if (!Number.isFinite(n)) throw Error("Coefficient accumulation overflows finite floating-point range in sum().");
|
|
1363
|
+
t.set(e, n);
|
|
1364
|
+
}
|
|
1365
|
+
return;
|
|
1366
|
+
}
|
|
1367
|
+
if (z(e)) {
|
|
1368
|
+
let n = e, r = (t.get(n) ?? 0) + 1;
|
|
1369
|
+
if (!Number.isFinite(r)) throw Error("Coefficient accumulation overflows finite floating-point range in sum().");
|
|
1370
|
+
t.set(n, r);
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1373
|
+
if (Array.isArray(e)) {
|
|
1374
|
+
if (a >= 2) throw Error("Nested containers deeper than 2D are not supported in sum().");
|
|
1375
|
+
for (let t = 0; t < e.length; t++) {
|
|
1376
|
+
if (!(t in e)) throw Error(`Unsupported item in sum(): sparse array hole at index ${t}.`);
|
|
1377
|
+
i(e[t], a + 1);
|
|
1378
|
+
}
|
|
1379
|
+
return;
|
|
1380
|
+
}
|
|
1381
|
+
if (R(e)) {
|
|
1382
|
+
if (a >= 2) throw Error("Nested containers deeper than 2D are not supported in sum().");
|
|
1383
|
+
for (let t of e) i(t, a + 1);
|
|
1384
|
+
return;
|
|
1385
|
+
}
|
|
1386
|
+
if (L(e)) {
|
|
1387
|
+
if (a >= 2) throw Error("Nested containers deeper than 2D are not supported in sum().");
|
|
1388
|
+
if (Object.getOwnPropertySymbols(e).length > 0) throw Error("Symbol keys are not supported in sum().");
|
|
1389
|
+
for (let t of Object.keys(e)) i(e[t], a + 1);
|
|
1390
|
+
return;
|
|
1391
|
+
}
|
|
1392
|
+
throw Error("Unsupported item in sum(): expected a number, Var, LinExpr, or QuadExpr.");
|
|
1393
|
+
}
|
|
1394
|
+
};
|
|
1395
|
+
e(i);
|
|
1396
|
+
for (let [e, n] of t) n === 0 && t.delete(e);
|
|
1397
|
+
for (let [e, t] of n) t.coeff === 0 && n.delete(e);
|
|
1398
|
+
return n.size > 0 ? new S(t, n, r) : new C(t, r);
|
|
1399
|
+
}
|
|
1400
|
+
evalSumSingle(e) {
|
|
1401
|
+
if (!N(e)) throw Error("sum() requires a container (Array, Iterable, or Record) or (itemsOrCount, mapFn).");
|
|
1402
|
+
return this.accumulateSumItems((t) => {
|
|
1403
|
+
t(e.data, 0);
|
|
1404
|
+
});
|
|
1405
|
+
}
|
|
1406
|
+
evalSumWithMapper(e, t) {
|
|
1407
|
+
return this.accumulateSumItems((n) => {
|
|
1408
|
+
if (typeof e == "number") {
|
|
1409
|
+
if (!Number.isInteger(e) || e < 0) throw Error("sum(count, mapFn) requires a non-negative integer count.");
|
|
1410
|
+
for (let r = 0; r < e; r++) n(t(r, r));
|
|
1411
|
+
return;
|
|
1412
|
+
}
|
|
1413
|
+
if (Array.isArray(e)) {
|
|
1414
|
+
for (let r = 0; r < e.length; r++) {
|
|
1415
|
+
if (!(r in e)) throw Error(`Unsupported item in sum(): sparse array hole at index ${r}.`);
|
|
1416
|
+
n(t(e[r], r));
|
|
1417
|
+
}
|
|
1418
|
+
return;
|
|
1419
|
+
}
|
|
1420
|
+
if (typeof e == "object" && e && !(e instanceof String) && Symbol.iterator in e && typeof e[Symbol.iterator] == "function") {
|
|
1421
|
+
let r = 0;
|
|
1422
|
+
for (let i of e) n(t(i, r++));
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1425
|
+
if (L(e)) {
|
|
1426
|
+
if (Object.getOwnPropertySymbols(e).length > 0) throw Error("Symbol keys are not supported in sum().");
|
|
1427
|
+
let r = 0;
|
|
1428
|
+
for (let i of Object.keys(e)) n(t(e[i], r++));
|
|
1429
|
+
return;
|
|
1430
|
+
}
|
|
1431
|
+
throw Error("Invalid first argument in sum(itemsOrCount, mapFn): expected an Iterable, Record, or non-negative integer count.");
|
|
1432
|
+
});
|
|
1433
|
+
}
|
|
1434
|
+
evalDot(e, t) {
|
|
1435
|
+
if (!N(e) || !N(t)) throw Error("dot() in template expression requires 1D or 2D Array or Record containers as arguments.");
|
|
1436
|
+
if (e.fromNonArrayIterable || t.fromNonArrayIterable) throw Error("Unsupported operand types in dot() at 'root': dot() requires Array or Record containers (use sum() for general Iterables).");
|
|
1437
|
+
let n = T(e.data, t.data);
|
|
1438
|
+
return B(n), n;
|
|
967
1439
|
}
|
|
968
|
-
|
|
1440
|
+
applyPowerNode(e) {
|
|
969
1441
|
if (this.peek()?.type !== "CARET") return e;
|
|
970
1442
|
let t = [];
|
|
971
1443
|
for (; this.peek()?.type === "CARET";) {
|
|
@@ -982,55 +1454,87 @@ var de = class {
|
|
|
982
1454
|
let n = t[t.length - 1];
|
|
983
1455
|
for (let e = t.length - 2; e >= 0; e--) n = t[e] ** +n;
|
|
984
1456
|
if (!Number.isFinite(n) || n < 0) throw Error("Exponent creates an invalid or out-of-range power");
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
if (
|
|
989
|
-
return
|
|
1457
|
+
if (typeof e == "number") {
|
|
1458
|
+
let t = e ** +n;
|
|
1459
|
+
if (e !== 0 && n > 0 && t === 0) throw Error("Constant exponentiation underflows to zero.");
|
|
1460
|
+
if (!Number.isFinite(t)) throw Error(`Invalid non-finite constant "${t}" in expression.`);
|
|
1461
|
+
return t;
|
|
990
1462
|
}
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1463
|
+
return N(e) ? {
|
|
1464
|
+
kind: "container",
|
|
1465
|
+
data: P(e.data, (e) => {
|
|
1466
|
+
if (typeof e == "number") {
|
|
1467
|
+
let t = e ** +n;
|
|
1468
|
+
if (e !== 0 && n > 0 && t === 0) throw Error("Constant exponentiation underflows to zero.");
|
|
1469
|
+
if (!Number.isFinite(t)) throw Error("Constant exponentiation overflows finite floating-point range.");
|
|
1470
|
+
return t;
|
|
1471
|
+
}
|
|
1472
|
+
let t = pe(ve(he(e), n));
|
|
1473
|
+
return B(t), t;
|
|
1474
|
+
}),
|
|
1475
|
+
fromNonArrayIterable: e.fromNonArrayIterable
|
|
1476
|
+
} : ve(e, n);
|
|
995
1477
|
}
|
|
996
1478
|
getRemainingToken() {
|
|
997
1479
|
return this.peek();
|
|
998
1480
|
}
|
|
999
|
-
|
|
1481
|
+
resolveNode(e) {
|
|
1482
|
+
if (this.templateCtx?.functionMap.has(e)) throw Error("Function interpolation is only supported as the second argument of sum(itemsOrCount, mapFn) in template expressions.");
|
|
1483
|
+
if (this.templateCtx?.rawContainerMap.has(e)) return be(this.templateCtx.rawContainerMap.get(e));
|
|
1000
1484
|
let t = this.resolver(e);
|
|
1001
1485
|
if (!t) throw Error(`Unknown variable '${e}' in expression`);
|
|
1002
|
-
return t;
|
|
1486
|
+
return t instanceof M || "id" in t && !("terms" in t) && !("quadTerms" in t) ? new C(/* @__PURE__ */ new Map([[t, 1]]), 0) : t.clone();
|
|
1003
1487
|
}
|
|
1004
1488
|
};
|
|
1005
|
-
function
|
|
1006
|
-
let
|
|
1007
|
-
if (
|
|
1008
|
-
return
|
|
1489
|
+
function Se(e, t, n, r) {
|
|
1490
|
+
let i = new xe(fe(e, n), t, r), a = i.parseExpression(), o = i.getRemainingToken();
|
|
1491
|
+
if (o) throw Error(`Unexpected token '${o.value}' after expression in "${e}"`);
|
|
1492
|
+
return B(a), a;
|
|
1493
|
+
}
|
|
1494
|
+
function Ce(e, t) {
|
|
1495
|
+
return Se(e, t);
|
|
1496
|
+
}
|
|
1497
|
+
function we(e) {
|
|
1498
|
+
let t = 0;
|
|
1499
|
+
for (let n = 0; n < e.length; n++) {
|
|
1500
|
+
let r = e[n];
|
|
1501
|
+
if (r === "(") t++;
|
|
1502
|
+
else if (r === ")") t > 0 && t--;
|
|
1503
|
+
else if (t === 0) {
|
|
1504
|
+
let t = e.slice(n, n + 2);
|
|
1505
|
+
if (t === "<=" || t === ">=" || t === "==" || t === "=<" || t === "=>") return {
|
|
1506
|
+
rawOp: t,
|
|
1507
|
+
index: n
|
|
1508
|
+
};
|
|
1509
|
+
if (r === "=") return {
|
|
1510
|
+
rawOp: "=",
|
|
1511
|
+
index: n
|
|
1512
|
+
};
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
return null;
|
|
1009
1516
|
}
|
|
1010
|
-
function
|
|
1011
|
-
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
if (
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
let f = u instanceof x ? new S(u.linearTerms, u.constant) : u, p = d instanceof x ? new S(d.linearTerms, d.constant) : d, m;
|
|
1024
|
-
if (m = l === "<=" ? f.le(p, n) : l === ">=" ? f.ge(p, n) : f.eq(p, n), F(m.lhs), !Number.isFinite(m.rhs)) throw Error(`Invalid non-finite right-hand side "${m.rhs}" in constraint.`);
|
|
1025
|
-
return m;
|
|
1026
|
-
}
|
|
1027
|
-
function me(e, t, n) {
|
|
1028
|
-
return pe(e, t, n);
|
|
1517
|
+
function Te(e, t, n, r, i) {
|
|
1518
|
+
let a = we(e);
|
|
1519
|
+
if (!a) throw Error(`Constraint must contain a comparison operator (<=, >=, ==, =): "${e}"`);
|
|
1520
|
+
let o = a.rawOp, s = a.index, c = e.substring(0, s).trim(), l = e.substring(s + o.length).trim(), u;
|
|
1521
|
+
if (o === "<=" || o === "=<") u = "<=";
|
|
1522
|
+
else if (o === ">=" || o === "=>") u = ">=";
|
|
1523
|
+
else if (o === "==" || o === "=") u = "==";
|
|
1524
|
+
else throw Error(`Unsupported operator "${o}"`);
|
|
1525
|
+
let d = Se(c, t, r, i), f = Se(l, t, r, i);
|
|
1526
|
+
if (d instanceof S && d.quadTerms.size > 0 || f instanceof S && f.quadTerms.size > 0) throw Error("Quadratic constraints are not supported (only linear constraints are allowed in MILP/LP/QP)");
|
|
1527
|
+
let p = d instanceof S ? new C(d.linearTerms, d.constant) : d, m = f instanceof S ? new C(f.linearTerms, f.constant) : f, h;
|
|
1528
|
+
if (h = u === "<=" ? p.le(m, n) : u === ">=" ? p.ge(m, n) : p.eq(m, n), B(h.lhs), !Number.isFinite(h.rhs)) throw Error(`Invalid non-finite right-hand side "${h.rhs}" in constraint.`);
|
|
1529
|
+
return h;
|
|
1029
1530
|
}
|
|
1030
|
-
function
|
|
1031
|
-
return e
|
|
1531
|
+
function Ee(e, t, n) {
|
|
1532
|
+
return Te(e, t, n);
|
|
1533
|
+
}
|
|
1534
|
+
function z(e) {
|
|
1535
|
+
return e instanceof M || e instanceof C || e instanceof S ? !0 : typeof e != "object" || !e || V(e) ? !1 : "terms" in e && e.terms instanceof Map && typeof e.constant == "number" || "quadTerms" in e && e.quadTerms instanceof Map && "linearTerms" in e && e.linearTerms instanceof Map && typeof e.constant == "number" || typeof e.id == "number" && typeof e.name == "string" && typeof e.lb == "number" && typeof e.ub == "number" && typeof e.type == "string" && typeof e.mul == "function";
|
|
1032
1536
|
}
|
|
1033
|
-
function
|
|
1537
|
+
function B(e) {
|
|
1034
1538
|
if ("constant" in e && !Number.isFinite(e.constant)) throw Error(`Invalid non-finite constant "${e.constant}" in expression.`);
|
|
1035
1539
|
if ("terms" in e && e.terms instanceof Map) {
|
|
1036
1540
|
for (let [, t] of e.terms) if (!Number.isFinite(t)) throw Error(`Invalid non-finite coefficient "${t}" in expression.`);
|
|
@@ -1042,57 +1546,67 @@ function F(e) {
|
|
|
1042
1546
|
for (let [, t] of e.quadTerms) if (!Number.isFinite(t.coeff)) throw Error(`Invalid non-finite quadratic coefficient "${t.coeff}" in expression.`);
|
|
1043
1547
|
}
|
|
1044
1548
|
}
|
|
1045
|
-
function
|
|
1046
|
-
return e instanceof
|
|
1549
|
+
function V(e) {
|
|
1550
|
+
return e instanceof y ? !0 : typeof e != "object" || !e ? !1 : e.kind === "constraint" || "sense" in e && (e.sense === "<=" || e.sense === ">=" || e.sense === "==") && "lhs" in e && "rhs" in e && typeof e.rhs == "number" && typeof e.lhs == "object" && e.lhs !== null && "terms" in e.lhs && e.lhs.terms instanceof Map;
|
|
1047
1551
|
}
|
|
1048
|
-
function
|
|
1049
|
-
let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), i = e.join(""),
|
|
1050
|
-
for (;
|
|
1051
|
-
let
|
|
1052
|
-
for (let
|
|
1053
|
-
let e = t[
|
|
1552
|
+
function De(e, t) {
|
|
1553
|
+
let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map(), o = e.join(""), s = "__washi_";
|
|
1554
|
+
for (; o.includes(s);) s += "_";
|
|
1555
|
+
let c = "";
|
|
1556
|
+
for (let o = 0; o < e.length; o++) if (c += e[o], o < t.length) {
|
|
1557
|
+
let e = t[o];
|
|
1054
1558
|
if (typeof e == "number") {
|
|
1055
1559
|
if (!Number.isFinite(e)) throw Error(`Invalid numeric value "${e}" in template expression: interpolated numbers must be finite.`);
|
|
1056
|
-
let t = `${
|
|
1057
|
-
r.set(t, e),
|
|
1058
|
-
} else if (
|
|
1059
|
-
else if (
|
|
1060
|
-
|
|
1061
|
-
let t = `${
|
|
1062
|
-
n.set(t, e),
|
|
1560
|
+
let t = `${s}num_${o}__`;
|
|
1561
|
+
r.set(t, e), c += `(${t})`;
|
|
1562
|
+
} else if (V(e)) throw Error("Cannot interpolate a constraint comparison (<=, >=, ==) inside a template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
1563
|
+
else if (z(e)) {
|
|
1564
|
+
B(e);
|
|
1565
|
+
let t = `${s}ph_${o}__`;
|
|
1566
|
+
n.set(t, e), c += ` ${t} `;
|
|
1567
|
+
} else if (typeof e == "function") {
|
|
1568
|
+
let t = `${s}fn_${o}__`;
|
|
1569
|
+
a.set(t, e), c += ` ${t} `;
|
|
1570
|
+
} else if (Array.isArray(e) || R(e) || e instanceof Map || L(e)) {
|
|
1571
|
+
let t = `${s}ph_${o}__`;
|
|
1572
|
+
i.set(t, e), c += ` ${t} `;
|
|
1063
1573
|
} else throw Error("Unsupported interpolation value in template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
1064
1574
|
}
|
|
1065
1575
|
return {
|
|
1066
|
-
fullText:
|
|
1576
|
+
fullText: c,
|
|
1067
1577
|
resolver: (e) => n.get(e),
|
|
1068
|
-
numberMap: r
|
|
1578
|
+
numberMap: r,
|
|
1579
|
+
templateCtx: {
|
|
1580
|
+
rawContainerMap: i,
|
|
1581
|
+
functionMap: a
|
|
1582
|
+
}
|
|
1069
1583
|
};
|
|
1070
1584
|
}
|
|
1071
|
-
function
|
|
1072
|
-
let { fullText: n, resolver: r, numberMap: i } =
|
|
1073
|
-
return
|
|
1585
|
+
function Oe(e, ...t) {
|
|
1586
|
+
let { fullText: n, resolver: r, numberMap: i, templateCtx: a } = De(e, t);
|
|
1587
|
+
return we(n) ? Te(n, r, void 0, i, a) : Se(n, r, i, a);
|
|
1074
1588
|
}
|
|
1075
1589
|
//#endregion
|
|
1076
1590
|
//#region src/modeler/lp-writer.ts
|
|
1077
|
-
function
|
|
1591
|
+
function ke(e) {
|
|
1078
1592
|
return typeof e == "object" && !!e && typeof e.lpString == "string" && e.nameToVar instanceof Map && e.nameToConstraint instanceof Map;
|
|
1079
1593
|
}
|
|
1080
|
-
function
|
|
1594
|
+
function H(e, t = "x", n = 0) {
|
|
1081
1595
|
let r = e.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
1082
1596
|
return /^[0-9]/.test(r) && (r = `${t}_${r}`), (!r || r.length === 0) && (r = `${t}_${n}`), r;
|
|
1083
1597
|
}
|
|
1084
|
-
function
|
|
1598
|
+
function Ae(e) {
|
|
1085
1599
|
let t = e.variables || [], n = e.constraints || [], r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
|
|
1086
1600
|
for (let e = 0; e < t.length; e++) {
|
|
1087
1601
|
let n = t[e];
|
|
1088
1602
|
s.set(n, e);
|
|
1089
|
-
let a =
|
|
1603
|
+
let a = H(n.name, "x", e), o = a, l = 1;
|
|
1090
1604
|
for (; c.has(o);) o = `${a}_${l++}`;
|
|
1091
1605
|
c.add(o), i.set(n, o), r.set(o, n);
|
|
1092
1606
|
}
|
|
1093
1607
|
let l = /* @__PURE__ */ new Set();
|
|
1094
1608
|
for (let e = 0; e < n.length; e++) {
|
|
1095
|
-
let t = n[e], r =
|
|
1609
|
+
let t = n[e], r = H(t.name, "c", e + 1), i = r, s = 1;
|
|
1096
1610
|
for (; l.has(i);) i = `${r}_${s++}`;
|
|
1097
1611
|
l.add(i), o.set(t, i), a.set(i, t);
|
|
1098
1612
|
}
|
|
@@ -1105,18 +1619,18 @@ function ye(e) {
|
|
|
1105
1619
|
varOrder: s
|
|
1106
1620
|
};
|
|
1107
1621
|
}
|
|
1108
|
-
function
|
|
1109
|
-
let { sense:
|
|
1110
|
-
|
|
1111
|
-
let
|
|
1112
|
-
if (
|
|
1622
|
+
function je(e, t) {
|
|
1623
|
+
let { sense: n, objective: r, constraints: i, variables: a } = e, o = t?.relax === !0, { nameToVar: s, varToName: c, nameToConstraint: l, constrToName: u, varOrder: d } = Ae(e), f = [];
|
|
1624
|
+
f.push(n && n.toLowerCase() === "maximize" ? "Maximize" : "Minimize");
|
|
1625
|
+
let p = [], m = !0, h = r instanceof S ? r.linearTerms : r.terms;
|
|
1626
|
+
if (h) for (let [e, t] of h) {
|
|
1113
1627
|
if (t === 0) continue;
|
|
1114
|
-
let n =
|
|
1115
|
-
|
|
1628
|
+
let n = c.get(e), r = t >= 0 ? m ? "" : "+ " : "- ", i = Math.abs(t), a = i === 1 ? "" : `${i} `;
|
|
1629
|
+
p.push(`${r}${a}${n}`), m = !1;
|
|
1116
1630
|
}
|
|
1117
|
-
if (
|
|
1118
|
-
let e = [], t = !0,
|
|
1119
|
-
let t =
|
|
1631
|
+
if (r instanceof S && r.quadTerms.size > 0) {
|
|
1632
|
+
let e = [], t = !0, n = Array.from(r.quadTerms.values()).filter((e) => e.coeff !== 0).map((e) => {
|
|
1633
|
+
let t = d.get(e.var1) ?? e.var1.id, n = d.get(e.var2) ?? e.var2.id, [r, i, a, o] = t <= n ? [
|
|
1120
1634
|
e.var1,
|
|
1121
1635
|
e.var2,
|
|
1122
1636
|
t,
|
|
@@ -1135,101 +1649,101 @@ function R(e) {
|
|
|
1135
1649
|
coeff: e.coeff
|
|
1136
1650
|
};
|
|
1137
1651
|
}).sort((e, t) => e.firstIdx - t.firstIdx || e.secondIdx - t.secondIdx);
|
|
1138
|
-
for (let
|
|
1139
|
-
let
|
|
1140
|
-
|
|
1652
|
+
for (let r of n) {
|
|
1653
|
+
let n = 2 * r.coeff, i = n >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(n), o = a === 1 ? "" : `${a} `, s = c.get(r.firstVar), l = c.get(r.secondVar);
|
|
1654
|
+
r.firstVar === r.secondVar ? e.push(`${i}${o}${s} ^ 2`) : e.push(`${i}${o}${s} * ${l}`), t = !1;
|
|
1141
1655
|
}
|
|
1142
1656
|
if (e.length > 0) {
|
|
1143
1657
|
let t = `[ ${e.join(" ")} ] / 2`;
|
|
1144
|
-
|
|
1658
|
+
p.length > 0 ? p.push("+", t) : p.push(t);
|
|
1145
1659
|
}
|
|
1146
1660
|
}
|
|
1147
|
-
let
|
|
1148
|
-
|
|
1149
|
-
for (let e of
|
|
1150
|
-
let t =
|
|
1661
|
+
let g = p.length > 0 ? p.join(" ") : "0";
|
|
1662
|
+
f.push(` obj: ${g}`), f.push("Subject To");
|
|
1663
|
+
for (let e of i) {
|
|
1664
|
+
let t = u.get(e), n = [], r = !0;
|
|
1151
1665
|
for (let [t, i] of e.lhs.terms) {
|
|
1152
1666
|
if (i === 0) continue;
|
|
1153
|
-
let e =
|
|
1154
|
-
n.push(`${a}${
|
|
1667
|
+
let e = c.get(t), a = i >= 0 ? r ? "" : "+ " : "- ", o = Math.abs(i), s = o === 1 ? "" : `${o} `;
|
|
1668
|
+
n.push(`${a}${s}${e}`), r = !1;
|
|
1155
1669
|
}
|
|
1156
1670
|
let i = n.length > 0 ? n.join(" ") : "0", a = e.sense === "==" ? "=" : e.sense;
|
|
1157
|
-
|
|
1158
|
-
}
|
|
1159
|
-
|
|
1160
|
-
let
|
|
1161
|
-
for (let e of
|
|
1162
|
-
let t =
|
|
1163
|
-
if (e.type === "Binary") {
|
|
1164
|
-
|
|
1671
|
+
f.push(` ${t}: ${i} ${a} ${e.rhs}`);
|
|
1672
|
+
}
|
|
1673
|
+
f.push("Bounds");
|
|
1674
|
+
let _ = [], v = [];
|
|
1675
|
+
for (let e of a) {
|
|
1676
|
+
let t = c.get(e);
|
|
1677
|
+
if (!o && e.type === "Binary") {
|
|
1678
|
+
v.push(t);
|
|
1165
1679
|
continue;
|
|
1166
1680
|
}
|
|
1167
|
-
e.type === "Integer" &&
|
|
1681
|
+
!o && e.type === "Integer" && _.push(t);
|
|
1168
1682
|
let n = e.lb === -Infinity, r = e.ub === Infinity;
|
|
1169
|
-
n && r ?
|
|
1683
|
+
n && r ? f.push(` ${t} free`) : n && !r ? f.push(` -infinity <= ${t} <= ${e.ub}`) : !n && r ? (e.lb !== 0 || e.initialValue !== void 0) && f.push(` ${t} >= ${e.lb}`) : f.push(` ${e.lb} <= ${t} <= ${e.ub}`);
|
|
1170
1684
|
}
|
|
1171
|
-
if (
|
|
1172
|
-
|
|
1173
|
-
for (let e = 0; e <
|
|
1685
|
+
if (_.length > 0) {
|
|
1686
|
+
f.push("Generals");
|
|
1687
|
+
for (let e = 0; e < _.length; e += 10) f.push(" " + _.slice(e, e + 10).join(" "));
|
|
1174
1688
|
}
|
|
1175
|
-
if (
|
|
1176
|
-
|
|
1177
|
-
for (let e = 0; e <
|
|
1689
|
+
if (v.length > 0) {
|
|
1690
|
+
f.push("Binary");
|
|
1691
|
+
for (let e = 0; e < v.length; e += 10) f.push(" " + v.slice(e, e + 10).join(" "));
|
|
1178
1692
|
}
|
|
1179
|
-
return
|
|
1180
|
-
lpString:
|
|
1181
|
-
nameToVar:
|
|
1182
|
-
nameToConstraint:
|
|
1693
|
+
return f.push("End"), {
|
|
1694
|
+
lpString: f.join("\n") + "\n",
|
|
1695
|
+
nameToVar: s,
|
|
1696
|
+
nameToConstraint: l
|
|
1183
1697
|
};
|
|
1184
1698
|
}
|
|
1185
1699
|
//#endregion
|
|
1186
1700
|
//#region src/modeler/solvers/registry.ts
|
|
1187
|
-
var
|
|
1188
|
-
|
|
1189
|
-
var
|
|
1190
|
-
function
|
|
1191
|
-
|
|
1701
|
+
var Me = Symbol.for("washi.solverRegistry"), Ne = Symbol.for("washi.defaultSolverFactory"), U = globalThis;
|
|
1702
|
+
U[Me] || (U[Me] = /* @__PURE__ */ new Map());
|
|
1703
|
+
var W = U[Me];
|
|
1704
|
+
function Pe(e, t) {
|
|
1705
|
+
W.set(e.toLowerCase(), t);
|
|
1192
1706
|
}
|
|
1193
|
-
function
|
|
1707
|
+
function Fe(e) {
|
|
1194
1708
|
if (typeof e == "string") {
|
|
1195
|
-
let t =
|
|
1709
|
+
let t = W.get(e.toLowerCase());
|
|
1196
1710
|
if (!t) throw Error(`Solver '${e}' is not registered.`);
|
|
1197
|
-
|
|
1198
|
-
} else
|
|
1711
|
+
U[Ne] = t;
|
|
1712
|
+
} else U[Ne] = typeof e == "function" ? e : () => e;
|
|
1199
1713
|
}
|
|
1200
|
-
function
|
|
1714
|
+
function G(e, t) {
|
|
1201
1715
|
if (!e) {
|
|
1202
|
-
let e =
|
|
1203
|
-
if (!e) throw Error(`No default solver available. Available solvers: ${
|
|
1716
|
+
let e = U[Ne] || W.get("highs");
|
|
1717
|
+
if (!e) throw Error(`No default solver available. Available solvers: ${K().join(", ")}`);
|
|
1204
1718
|
return e(t);
|
|
1205
1719
|
}
|
|
1206
1720
|
if (typeof e == "string") {
|
|
1207
|
-
let n = e.toLowerCase(), r =
|
|
1208
|
-
if (!r) throw Error(n === "glpk" ? `Solver 'glpk' not found. Available solvers: ${
|
|
1721
|
+
let n = e.toLowerCase(), r = W.get(n);
|
|
1722
|
+
if (!r) throw Error(n === "glpk" ? `Solver 'glpk' not found. Available solvers: ${K().join(", ")}. Please import '@ohtaman/washi/solvers/glpk' before selecting this solver.` : n === "z3" ? `Solver 'z3' not found. Available solvers: ${K().join(", ")}. Please import '@ohtaman/washi/solvers/z3' before selecting this solver.` : `Solver '${e}' not found. Available solvers: ${K().join(", ")}`);
|
|
1209
1723
|
return r(t);
|
|
1210
1724
|
}
|
|
1211
1725
|
return e;
|
|
1212
1726
|
}
|
|
1213
|
-
function
|
|
1214
|
-
return Array.from(
|
|
1727
|
+
function K() {
|
|
1728
|
+
return Array.from(W.keys());
|
|
1215
1729
|
}
|
|
1216
1730
|
//#endregion
|
|
1217
1731
|
//#region \0washi-browser-worker-factory
|
|
1218
|
-
function
|
|
1219
|
-
let e =
|
|
1220
|
-
if (new URL(e).origin ===
|
|
1221
|
-
let
|
|
1732
|
+
function Ie() {
|
|
1733
|
+
let e = a("highs-worker.js"), t = typeof window.origin == "string" ? window.origin : window.location?.origin;
|
|
1734
|
+
if (new URL(e).origin === t) return new Worker(e, { type: "module" });
|
|
1735
|
+
let n = URL.createObjectURL(new Blob(["import " + JSON.stringify(e) + ";"], { type: "text/javascript" }));
|
|
1222
1736
|
try {
|
|
1223
|
-
let e = new Worker(
|
|
1224
|
-
return e.addEventListener("message",
|
|
1737
|
+
let e = new Worker(n, { type: "module" }), t = () => URL.revokeObjectURL(n);
|
|
1738
|
+
return e.addEventListener("message", t, { once: !0 }), e.addEventListener("error", t, { once: !0 }), e;
|
|
1225
1739
|
} catch (e) {
|
|
1226
|
-
throw URL.revokeObjectURL(
|
|
1740
|
+
throw URL.revokeObjectURL(n), e;
|
|
1227
1741
|
}
|
|
1228
1742
|
}
|
|
1229
1743
|
//#endregion
|
|
1230
1744
|
//#region src/modeler/solvers/highs/worker-client.ts
|
|
1231
|
-
var
|
|
1232
|
-
function
|
|
1745
|
+
var q = null, Le = 0, J = /* @__PURE__ */ new Map();
|
|
1746
|
+
function Re(e, t) {
|
|
1233
1747
|
return e ? {
|
|
1234
1748
|
Status: "Interrupted",
|
|
1235
1749
|
StatusCode: 17,
|
|
@@ -1253,8 +1767,8 @@ function K(e, t) {
|
|
|
1253
1767
|
Rows: []
|
|
1254
1768
|
};
|
|
1255
1769
|
}
|
|
1256
|
-
function
|
|
1257
|
-
let t =
|
|
1770
|
+
function ze(e) {
|
|
1771
|
+
let t = J.values().next().value;
|
|
1258
1772
|
if (t && !t.dispatched) {
|
|
1259
1773
|
t.dispatched = !0;
|
|
1260
1774
|
try {
|
|
@@ -1266,30 +1780,30 @@ function q(e) {
|
|
|
1266
1780
|
...t.reportProgress ? { reportProgress: !0 } : {}
|
|
1267
1781
|
});
|
|
1268
1782
|
} catch (n) {
|
|
1269
|
-
|
|
1783
|
+
J.delete(t.id), t.cleanupAbort?.(), t.reject(n), ze(e);
|
|
1270
1784
|
}
|
|
1271
1785
|
}
|
|
1272
1786
|
}
|
|
1273
|
-
function
|
|
1274
|
-
let e =
|
|
1275
|
-
e && (
|
|
1276
|
-
for (let e of
|
|
1277
|
-
if (
|
|
1278
|
-
let e =
|
|
1279
|
-
if (e)
|
|
1787
|
+
function Be() {
|
|
1788
|
+
let e = q;
|
|
1789
|
+
e && (q = null, e.terminate());
|
|
1790
|
+
for (let e of J.values()) e.dispatched = !1;
|
|
1791
|
+
if (J.size > 0) {
|
|
1792
|
+
let e = Ve();
|
|
1793
|
+
if (e) ze(e);
|
|
1280
1794
|
else {
|
|
1281
1795
|
let e = /* @__PURE__ */ Error("[WaSHI] Failed to recreate HiGHS Worker after interruption.");
|
|
1282
|
-
for (let t of Array.from(
|
|
1796
|
+
for (let t of Array.from(J.values())) J.delete(t.id), t.cleanupAbort?.(), t.reject(e);
|
|
1283
1797
|
}
|
|
1284
1798
|
}
|
|
1285
1799
|
}
|
|
1286
|
-
function
|
|
1800
|
+
function Ve() {
|
|
1287
1801
|
if (typeof window > "u" || typeof Worker > "u") return null;
|
|
1288
|
-
if (!
|
|
1289
|
-
|
|
1290
|
-
let e =
|
|
1291
|
-
|
|
1292
|
-
let { type: n, id: r, result: i, runTime: a, error: o, progress: s, incumbent: c } = t.data, l =
|
|
1802
|
+
if (!q) try {
|
|
1803
|
+
q = Ie();
|
|
1804
|
+
let e = q;
|
|
1805
|
+
q.onmessage = (t) => {
|
|
1806
|
+
let { type: n, id: r, result: i, runTime: a, error: o, progress: s, incumbent: c } = t.data, l = J.get(r);
|
|
1293
1807
|
if (l) {
|
|
1294
1808
|
if (n === "SOLVE_PROGRESS") {
|
|
1295
1809
|
if (s) {
|
|
@@ -1297,10 +1811,10 @@ function Ee() {
|
|
|
1297
1811
|
try {
|
|
1298
1812
|
l.onProgress?.(s);
|
|
1299
1813
|
} catch (e) {
|
|
1300
|
-
let t =
|
|
1814
|
+
let t = J.get(r);
|
|
1301
1815
|
if (t) {
|
|
1302
|
-
let n =
|
|
1303
|
-
|
|
1816
|
+
let n = J.keys().next().value;
|
|
1817
|
+
J.delete(r), t.cleanupAbort?.(), n === r && Be(), t.reject(e);
|
|
1304
1818
|
}
|
|
1305
1819
|
}
|
|
1306
1820
|
}
|
|
@@ -1310,72 +1824,72 @@ function Ee() {
|
|
|
1310
1824
|
c && (l.lastIncumbent = c);
|
|
1311
1825
|
return;
|
|
1312
1826
|
}
|
|
1313
|
-
|
|
1827
|
+
J.delete(r), l.cleanupAbort?.(), n === "SOLVE_SUCCESS" ? l.resolve({
|
|
1314
1828
|
result: i,
|
|
1315
1829
|
runTime: a
|
|
1316
|
-
}) : l.reject(Error(o || "Worker solve failed")),
|
|
1830
|
+
}) : l.reject(Error(o || "Worker solve failed")), q === e && ze(e);
|
|
1317
1831
|
}
|
|
1318
1832
|
};
|
|
1319
1833
|
let t = (t) => {
|
|
1320
|
-
if (
|
|
1321
|
-
|
|
1322
|
-
for (let e of
|
|
1323
|
-
|
|
1834
|
+
if (q === e) {
|
|
1835
|
+
q = null, e.terminate();
|
|
1836
|
+
for (let e of J.values()) e.cleanupAbort?.(), e.reject(t);
|
|
1837
|
+
J.clear();
|
|
1324
1838
|
}
|
|
1325
1839
|
};
|
|
1326
|
-
|
|
1840
|
+
q.onerror = (e) => t(/* @__PURE__ */ Error(`[WaSHI] HiGHS Worker failed to load or execute. Check Worker assets, CORS and CSP. ${e?.message || ""}`)), q.onmessageerror = () => t(/* @__PURE__ */ Error("[WaSHI] Could not deserialize the HiGHS Worker response."));
|
|
1327
1841
|
} catch {
|
|
1328
|
-
|
|
1842
|
+
q = null;
|
|
1329
1843
|
}
|
|
1330
|
-
return
|
|
1844
|
+
return q;
|
|
1331
1845
|
}
|
|
1332
|
-
async function
|
|
1846
|
+
async function He(t, n = {}) {
|
|
1333
1847
|
if (n.signal?.aborted) return {
|
|
1334
|
-
result:
|
|
1848
|
+
result: Re(),
|
|
1335
1849
|
runTime: 0
|
|
1336
1850
|
};
|
|
1337
1851
|
let r = await i(n.wasmUrl);
|
|
1338
1852
|
if (n.signal?.aborted) return {
|
|
1339
|
-
result:
|
|
1853
|
+
result: Re(),
|
|
1340
1854
|
runTime: 0
|
|
1341
1855
|
};
|
|
1342
|
-
let a = n.useWorker ?? typeof window < "u" ?
|
|
1343
|
-
if (!
|
|
1344
|
-
let { signal:
|
|
1345
|
-
for (let [e, t] of Object.entries(
|
|
1346
|
-
|
|
1347
|
-
let
|
|
1856
|
+
let a = typeof window < "u" ? typeof window.origin == "string" ? window.origin : window.location?.origin : void 0, o = n.useWorker ?? (typeof window < "u" && a !== "null" && !a?.startsWith("file:")) ? Ve() : null;
|
|
1857
|
+
if (!o) return e(t, n);
|
|
1858
|
+
let { signal: s, onProgress: c, ...l } = n, u = {};
|
|
1859
|
+
for (let [e, t] of Object.entries(l)) typeof t != "function" && (u[e] = t);
|
|
1860
|
+
u.wasmUrl = r;
|
|
1861
|
+
let d = !!(c || s), f = `req_${++Le}`, p = performance.now();
|
|
1348
1862
|
return new Promise((e, n) => {
|
|
1349
1863
|
let r = {
|
|
1350
|
-
id:
|
|
1864
|
+
id: f,
|
|
1351
1865
|
lpString: t,
|
|
1352
|
-
workerOptions:
|
|
1353
|
-
reportProgress:
|
|
1354
|
-
startTime:
|
|
1355
|
-
onProgress:
|
|
1866
|
+
workerOptions: u,
|
|
1867
|
+
reportProgress: d,
|
|
1868
|
+
startTime: p,
|
|
1869
|
+
onProgress: c,
|
|
1356
1870
|
resolve: e,
|
|
1357
1871
|
reject: n
|
|
1358
1872
|
};
|
|
1359
|
-
if (
|
|
1873
|
+
if (s) {
|
|
1360
1874
|
let e = () => {
|
|
1361
|
-
let e =
|
|
1875
|
+
let e = J.get(f);
|
|
1362
1876
|
if (!e) return;
|
|
1363
|
-
let t =
|
|
1364
|
-
|
|
1877
|
+
let t = J.keys().next().value;
|
|
1878
|
+
J.delete(f), e.cleanupAbort?.(), t === f && Be();
|
|
1365
1879
|
let n = (performance.now() - e.startTime) / 1e3;
|
|
1366
1880
|
e.resolve({
|
|
1367
|
-
result:
|
|
1881
|
+
result: Re(e.lastIncumbent, e.lastProgress),
|
|
1368
1882
|
runTime: n
|
|
1369
1883
|
});
|
|
1370
1884
|
};
|
|
1371
|
-
|
|
1885
|
+
s.addEventListener("abort", e, { once: !0 }), r.cleanupAbort = () => s.removeEventListener("abort", e);
|
|
1372
1886
|
}
|
|
1373
|
-
|
|
1887
|
+
J.set(f, r), ze(o);
|
|
1374
1888
|
});
|
|
1375
1889
|
}
|
|
1376
1890
|
//#endregion
|
|
1377
1891
|
//#region src/modeler/solvers/highs/solver.ts
|
|
1378
|
-
function
|
|
1892
|
+
function Ue(e, t) {
|
|
1379
1893
|
if (typeof t == "number") switch (t) {
|
|
1380
1894
|
case 0: return "NotSolved";
|
|
1381
1895
|
case 1:
|
|
@@ -1434,8 +1948,8 @@ function Oe(e, t) {
|
|
|
1434
1948
|
let r = n.toLowerCase();
|
|
1435
1949
|
return r.includes("infeasible") && r.includes("unbounded") ? "InfeasibleOrUnbounded" : r.includes("infeasible") ? "Infeasible" : r.includes("unbounded") ? "Unbounded" : r.includes("time limit") || r.includes("timelimit") ? "TimeLimit" : r.includes("iteration limit") || r.includes("iterationlimit") ? "IterationLimit" : r.includes("solution limit") || r.includes("solutionlimit") ? "SolutionLimit" : r.includes("memory limit") || r.includes("memorylimit") ? "MemoryLimit" : r.includes("bound on objective") ? "ObjectiveBound" : r.includes("target for objective") ? "ObjectiveTarget" : r.includes("interrupt") ? "Interrupted" : r.includes("error") ? "Error" : r === "optimal" ? "Optimal" : "Unknown";
|
|
1436
1950
|
}
|
|
1437
|
-
function
|
|
1438
|
-
switch (
|
|
1951
|
+
function We(e, t, n) {
|
|
1952
|
+
switch (Ue(e, t)) {
|
|
1439
1953
|
case "Optimal": return "Optimal";
|
|
1440
1954
|
case "Infeasible": return "Infeasible";
|
|
1441
1955
|
case "Unbounded": return "Unbounded";
|
|
@@ -1452,37 +1966,37 @@ function ke(e, t, n) {
|
|
|
1452
1966
|
default: return "Unknown";
|
|
1453
1967
|
}
|
|
1454
1968
|
}
|
|
1455
|
-
var
|
|
1969
|
+
var Ge = class e {
|
|
1456
1970
|
static capabilities = {
|
|
1457
1971
|
supportsMIP: !0,
|
|
1458
1972
|
supportsQP: !0,
|
|
1459
1973
|
supportsWarmStart: !0
|
|
1460
1974
|
};
|
|
1461
1975
|
name = "HiGHS";
|
|
1462
|
-
version = "1.15.
|
|
1976
|
+
version = "1.15.1";
|
|
1463
1977
|
capabilities = e.capabilities;
|
|
1464
1978
|
options;
|
|
1465
1979
|
constructor(e = {}) {
|
|
1466
1980
|
this.options = e;
|
|
1467
1981
|
}
|
|
1468
1982
|
async solve(e, t = {}, n = {}) {
|
|
1469
|
-
let r =
|
|
1983
|
+
let r = ke(t), i = r ? n : t, a = {
|
|
1470
1984
|
...this.options,
|
|
1471
1985
|
...i
|
|
1472
1986
|
}, o = e.objective.constant || 0;
|
|
1473
1987
|
for (let t of e.variables) A(t);
|
|
1474
|
-
let { lpString: s, nameToVar: c, nameToConstraint: l } = r ? t :
|
|
1988
|
+
let { lpString: s, nameToVar: c, nameToConstraint: l } = r ? t : je(e, { relax: a.relax }), u = Object.create(null), d = !1, f = /* @__PURE__ */ new Set();
|
|
1475
1989
|
for (let [e, t] of c.entries()) {
|
|
1476
1990
|
f.add(t);
|
|
1477
|
-
let n =
|
|
1991
|
+
let n = ae(t);
|
|
1478
1992
|
n !== void 0 && (u[e] = n, d = !0);
|
|
1479
1993
|
}
|
|
1480
1994
|
for (let t = 0; t < e.variables.length; t++) {
|
|
1481
1995
|
let n = e.variables[t];
|
|
1482
1996
|
if (!f.has(n)) {
|
|
1483
|
-
let e =
|
|
1997
|
+
let e = ae(n);
|
|
1484
1998
|
if (e !== void 0) {
|
|
1485
|
-
let r =
|
|
1999
|
+
let r = H(n.name, "x", t);
|
|
1486
2000
|
Object.prototype.hasOwnProperty.call(u, r) || (u[r] = e, d = !0);
|
|
1487
2001
|
}
|
|
1488
2002
|
}
|
|
@@ -1493,13 +2007,13 @@ var J = class e {
|
|
|
1493
2007
|
...o === 0 ? {} : { objectiveOffset: o },
|
|
1494
2008
|
initialValues: d ? u : void 0
|
|
1495
2009
|
});
|
|
1496
|
-
let { result: m, runTime: h } = await
|
|
2010
|
+
let { result: m, runTime: h } = await He(s, p), g = m?.ObjectiveOffsetApplied ? 0 : o, _ = Ue(m?.Status, m?.StatusCode), v = a.relax ? !1 : typeof m?.IsMip == "boolean" ? m.IsMip : e.variables.some((e) => e.type === "Integer" || e.type === "Binary"), y;
|
|
1497
2011
|
if (typeof m?.HasPrimalSolution == "boolean") y = m.HasPrimalSolution;
|
|
1498
2012
|
else {
|
|
1499
2013
|
let e = m?.Columns ? Object.values(m.Columns) : [], t = e.length > 0 && e.some((e) => typeof e?.Primal == "number" && Number.isFinite(e.Primal)), n = typeof m?.ObjectiveValue == "number" && Number.isFinite(m.ObjectiveValue);
|
|
1500
2014
|
y = _ === "Infeasible" || _ === "Unbounded" || _ === "InfeasibleOrUnbounded" || _ === "Error" || _ === "NotSolved" ? !1 : _ === "Optimal" || _ === "Feasible" ? n || t : n && (e.length === 0 || t);
|
|
1501
2015
|
}
|
|
1502
|
-
let b =
|
|
2016
|
+
let b = We(m?.Status, m?.StatusCode, y), x = null;
|
|
1503
2017
|
y && typeof m?.ObjectiveValue == "number" && Number.isFinite(m.ObjectiveValue) && (x = m.ObjectiveValue + g);
|
|
1504
2018
|
let S, C, w;
|
|
1505
2019
|
if (typeof m?.MipDualBound == "number" && Number.isFinite(m.MipDualBound) ? S = m.MipDualBound + g : !v && _ === "Optimal" && x !== null && (S = x), x !== null && S !== void 0 && Number.isFinite(S) && (w = Math.abs(x - S)), g !== 0 && v && x !== null && S !== void 0 && w !== void 0) {
|
|
@@ -1540,7 +2054,7 @@ var J = class e {
|
|
|
1540
2054
|
if (n) {
|
|
1541
2055
|
if (typeof t.Primal == "number" && Number.isFinite(t.Primal)) {
|
|
1542
2056
|
let e = Math.abs(t.Primal) < 1e-9 ? 0 : t.Primal;
|
|
1543
|
-
T(E, n.name, e);
|
|
2057
|
+
!a.relax && (n.type === "Integer" || n.type === "Binary") && Math.abs(e - Math.round(e)) <= 1e-5 && (e = Math.round(e) + 0), T(E, n.name, e);
|
|
1544
2058
|
}
|
|
1545
2059
|
typeof t.Dual == "number" && Number.isFinite(t.Dual) && T(O, n.name, Math.abs(t.Dual) < 1e-9 ? 0 : t.Dual);
|
|
1546
2060
|
}
|
|
@@ -1574,14 +2088,14 @@ var J = class e {
|
|
|
1574
2088
|
raw: m
|
|
1575
2089
|
};
|
|
1576
2090
|
}
|
|
1577
|
-
},
|
|
1578
|
-
function
|
|
1579
|
-
|
|
2091
|
+
}, Ke = Ge;
|
|
2092
|
+
function qe() {
|
|
2093
|
+
Pe("highs", (e) => new Ge(e)), Fe((e) => new Ge(e));
|
|
1580
2094
|
}
|
|
1581
|
-
|
|
2095
|
+
qe();
|
|
1582
2096
|
//#endregion
|
|
1583
2097
|
//#region src/modeler/solvers/mock.ts
|
|
1584
|
-
var
|
|
2098
|
+
var Je = class {
|
|
1585
2099
|
name;
|
|
1586
2100
|
capabilities;
|
|
1587
2101
|
options;
|
|
@@ -1593,7 +2107,7 @@ var Me = class {
|
|
|
1593
2107
|
}, this.options = e;
|
|
1594
2108
|
}
|
|
1595
2109
|
async solve(e, t = {}, n = {}) {
|
|
1596
|
-
let r =
|
|
2110
|
+
let r = ke(t) ? n : t, i = {
|
|
1597
2111
|
...this.options,
|
|
1598
2112
|
...r
|
|
1599
2113
|
}, a = !!(i.values && Object.keys(i.values).length > 0 || i.boolValues && Object.keys(i.boolValues).length > 0);
|
|
@@ -1681,29 +2195,29 @@ var Me = class {
|
|
|
1681
2195
|
};
|
|
1682
2196
|
}
|
|
1683
2197
|
};
|
|
1684
|
-
function
|
|
1685
|
-
|
|
2198
|
+
function Ye() {
|
|
2199
|
+
Pe("mock", (e) => new Je(e));
|
|
1686
2200
|
}
|
|
1687
|
-
|
|
2201
|
+
Ye();
|
|
1688
2202
|
//#endregion
|
|
1689
2203
|
//#region src/modeler/solution-validator.ts
|
|
1690
|
-
function
|
|
2204
|
+
function Xe(e, t) {
|
|
1691
2205
|
if (e === void 0) return 1e-6;
|
|
1692
2206
|
if (typeof e != "number" || !Number.isFinite(e) || e < 0) throw Error(`Invalid ${t}: expected a finite non-negative number, received ${String(e)}.`);
|
|
1693
2207
|
return e;
|
|
1694
2208
|
}
|
|
1695
|
-
function
|
|
1696
|
-
let n =
|
|
2209
|
+
function Ze(e, t = {}) {
|
|
2210
|
+
let n = Xe(t.feasibilityTolerance, "feasibilityTolerance"), r = Xe(t.integralityTolerance, "integralityTolerance"), i = t.evaluateLogicalConstraints === void 0 || !!t.evaluateLogicalConstraints, a = t.values !== void 0 && t.values !== null;
|
|
1697
2211
|
if (t.values !== void 0 && (typeof t.values != "object" || t.values === null || Array.isArray(t.values))) throw Error("Invalid values option: expected a plain object mapping variable names to values.");
|
|
1698
|
-
let o = t.values, s = [], c = Object.create(null), l = [],
|
|
2212
|
+
let o = t.values, s = [], c = Object.create(null), l = [], u = [], p = 0, m = (e) => {
|
|
1699
2213
|
typeof e == "number" && !Number.isNaN(e) && e > p && (p = e);
|
|
1700
2214
|
}, h = (e) => {
|
|
1701
2215
|
s.push(e), Object.prototype.hasOwnProperty.call(c, e.name) || (c[e.name] = []), c[e.name].push(e), e.type !== "missing_value" && e.type !== "unchecked_constraint" && m(e.violation);
|
|
1702
|
-
}, g = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Map(),
|
|
2216
|
+
}, g = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Map(), v = 0, b = 0, x = 0, S = 0;
|
|
1703
2217
|
for (let t of e.variables) {
|
|
1704
2218
|
let e = a ? Object.prototype.hasOwnProperty.call(o, t.name) ? o[t.name] : void 0 : t.value;
|
|
1705
2219
|
if (e == null) {
|
|
1706
|
-
|
|
2220
|
+
u.push(t.name), h({
|
|
1707
2221
|
type: "missing_value",
|
|
1708
2222
|
target: "variable",
|
|
1709
2223
|
name: t.name,
|
|
@@ -1724,9 +2238,9 @@ function Fe(e, t = {}) {
|
|
|
1724
2238
|
});
|
|
1725
2239
|
continue;
|
|
1726
2240
|
}
|
|
1727
|
-
g.set(t, e),
|
|
1728
|
-
let i = t.type === "Binary" || t.type === "BINARY", s = i || t.type === "Integer" || t.type === "INTEGER", c = i ? Math.max(0, t.lb) : t.lb, l = i ? Math.min(1, t.ub) : t.ub,
|
|
1729
|
-
if (!
|
|
2241
|
+
g.set(t, e), v++;
|
|
2242
|
+
let i = t.type === "Binary" || t.type === "BINARY", s = i || t.type === "Integer" || t.type === "INTEGER", c = i ? Math.max(0, t.lb) : t.lb, l = i ? Math.min(1, t.ub) : t.ub, d = typeof t.lb == "number" && !Number.isNaN(t.lb) && t.lb !== Infinity, f = typeof t.ub == "number" && !Number.isNaN(t.ub) && t.ub !== -Infinity;
|
|
2243
|
+
if (!d) h({
|
|
1730
2244
|
type: "lower_bound",
|
|
1731
2245
|
target: "variable",
|
|
1732
2246
|
name: t.name,
|
|
@@ -1748,7 +2262,7 @@ function Fe(e, t = {}) {
|
|
|
1748
2262
|
message: `Variable "${t.name}" value (${e}) violates lower bound (${c}) by ${i}.`
|
|
1749
2263
|
});
|
|
1750
2264
|
}
|
|
1751
|
-
if (!
|
|
2265
|
+
if (!f) h({
|
|
1752
2266
|
type: "upper_bound",
|
|
1753
2267
|
target: "variable",
|
|
1754
2268
|
name: t.name,
|
|
@@ -1770,7 +2284,7 @@ function Fe(e, t = {}) {
|
|
|
1770
2284
|
message: `Variable "${t.name}" value (${e}) violates upper bound (${l}) by ${i}.`
|
|
1771
2285
|
});
|
|
1772
2286
|
}
|
|
1773
|
-
if (
|
|
2287
|
+
if (d && f && c > l && c - e <= n && e - l <= n) {
|
|
1774
2288
|
let n = c - l;
|
|
1775
2289
|
h({
|
|
1776
2290
|
type: "lower_bound",
|
|
@@ -1801,7 +2315,7 @@ function Fe(e, t = {}) {
|
|
|
1801
2315
|
for (let t of e.boolVars) {
|
|
1802
2316
|
let e = a ? Object.prototype.hasOwnProperty.call(o, t.name) ? o[t.name] : void 0 : t.value;
|
|
1803
2317
|
if (e == null) {
|
|
1804
|
-
|
|
2318
|
+
u.push(t.name), h({
|
|
1805
2319
|
type: "missing_value",
|
|
1806
2320
|
target: "bool_variable",
|
|
1807
2321
|
name: t.name,
|
|
@@ -1905,7 +2419,7 @@ function Fe(e, t = {}) {
|
|
|
1905
2419
|
})) : (x++, m(e.violation));
|
|
1906
2420
|
}
|
|
1907
2421
|
let T = (e) => {
|
|
1908
|
-
if (e instanceof
|
|
2422
|
+
if (e instanceof d) return _.has(e) ? {
|
|
1909
2423
|
ok: !0,
|
|
1910
2424
|
value: _.get(e),
|
|
1911
2425
|
violation: 0
|
|
@@ -1913,7 +2427,7 @@ function Fe(e, t = {}) {
|
|
|
1913
2427
|
ok: !1,
|
|
1914
2428
|
reason: `missing or invalid value for Boolean variable "${e.name}"`
|
|
1915
2429
|
};
|
|
1916
|
-
if (e instanceof
|
|
2430
|
+
if (e instanceof y) {
|
|
1917
2431
|
let t = w(e, 0);
|
|
1918
2432
|
if (t.status === "unchecked") return {
|
|
1919
2433
|
ok: !1,
|
|
@@ -1932,7 +2446,7 @@ function Fe(e, t = {}) {
|
|
|
1932
2446
|
violation: 0
|
|
1933
2447
|
};
|
|
1934
2448
|
}
|
|
1935
|
-
if (e instanceof
|
|
2449
|
+
if (e instanceof f) switch (e.op) {
|
|
1936
2450
|
case "not": {
|
|
1937
2451
|
let t = T(e.children[0]);
|
|
1938
2452
|
return t.ok ? {
|
|
@@ -2044,17 +2558,17 @@ function Fe(e, t = {}) {
|
|
|
2044
2558
|
message: `Logical constraint "${r}" evaluated to false.`
|
|
2045
2559
|
});
|
|
2046
2560
|
}
|
|
2047
|
-
let E =
|
|
2561
|
+
let E = v === e.variables.length && b === e.boolVars.length && x === e.constraints.length && S === e.logicalConstraints.length && l.length === 0 && u.length === 0;
|
|
2048
2562
|
return {
|
|
2049
2563
|
valid: E && s.length === 0,
|
|
2050
2564
|
complete: E,
|
|
2051
2565
|
violations: s,
|
|
2052
2566
|
violationsByName: c,
|
|
2053
2567
|
uncheckedConstraints: l,
|
|
2054
|
-
missingVariables:
|
|
2568
|
+
missingVariables: u,
|
|
2055
2569
|
maxViolation: p,
|
|
2056
2570
|
summary: {
|
|
2057
|
-
checkedVariables:
|
|
2571
|
+
checkedVariables: v,
|
|
2058
2572
|
totalVariables: e.variables.length,
|
|
2059
2573
|
checkedBoolVariables: b,
|
|
2060
2574
|
totalBoolVariables: e.boolVars.length,
|
|
@@ -2067,10 +2581,10 @@ function Fe(e, t = {}) {
|
|
|
2067
2581
|
}
|
|
2068
2582
|
//#endregion
|
|
2069
2583
|
//#region src/modeler/big-m.ts
|
|
2070
|
-
function
|
|
2584
|
+
function Qe(e, t) {
|
|
2071
2585
|
if (typeof e != "number" || !Number.isFinite(e) || e <= 0) throw Error(`Invalid Big-M value for indicator constraint "${t}": expected a finite positive number, received ${e}.`);
|
|
2072
2586
|
}
|
|
2073
|
-
function
|
|
2587
|
+
function $e(e, t, n) {
|
|
2074
2588
|
let r = e.constant === void 0 ? 0 : e.constant;
|
|
2075
2589
|
if (!Number.isFinite(t) || !Number.isFinite(r)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": constraint contains non-finite constant (${r}) or right-hand side (${t}).`);
|
|
2076
2590
|
let i = t - r;
|
|
@@ -2081,8 +2595,8 @@ function Y(e, t, n) {
|
|
|
2081
2595
|
}
|
|
2082
2596
|
return i;
|
|
2083
2597
|
}
|
|
2084
|
-
function
|
|
2085
|
-
let r =
|
|
2598
|
+
function et(e, t, n) {
|
|
2599
|
+
let r = $e(e, t, n), i = 0;
|
|
2086
2600
|
for (let [t, r] of e.terms) {
|
|
2087
2601
|
if (r === 0) continue;
|
|
2088
2602
|
let e;
|
|
@@ -2102,8 +2616,8 @@ function Le(e, t, n) {
|
|
|
2102
2616
|
if (!Number.isFinite(o) || !Number.isFinite(r + o)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": derived Big-M (${o}) or shifted right-hand side overflows finite floating-point range. Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
2103
2617
|
return o;
|
|
2104
2618
|
}
|
|
2105
|
-
function
|
|
2106
|
-
let r =
|
|
2619
|
+
function tt(e, t, n) {
|
|
2620
|
+
let r = $e(e, t, n), i = 0;
|
|
2107
2621
|
for (let [t, r] of e.terms) {
|
|
2108
2622
|
if (r === 0) continue;
|
|
2109
2623
|
let e;
|
|
@@ -2123,10 +2637,10 @@ function Re(e, t, n) {
|
|
|
2123
2637
|
if (!Number.isFinite(o) || !Number.isFinite(r - o)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": derived Big-M (${o}) or shifted right-hand side overflows finite floating-point range. Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
2124
2638
|
return o;
|
|
2125
2639
|
}
|
|
2126
|
-
function
|
|
2127
|
-
if (!(e instanceof
|
|
2640
|
+
function Y(e, t, n, r, i, a, o) {
|
|
2641
|
+
if (!(e instanceof M && (e.type === "Binary" || e.type === "Integer" && e.lb === 0 && e.ub === 1))) throw Error(`Indicator variable "${e?.name ?? String(e)}" must be a Binary variable (or Integer variable with bounds [0, 1]), received "${e?.type ?? typeof e}" with bounds [${e?.lb}, ${e?.ub}].`);
|
|
2128
2642
|
if (!Number.isFinite(e.lb) || !Number.isFinite(e.ub) || e.lb < 0 || e.ub > 1 || e.lb > e.ub) throw Error(`Binary indicator variable "${e.name}" has invalid bounds [${e.lb}, ${e.ub}]. Binary variables must stay within [0, 1] with lb <= ub.`);
|
|
2129
|
-
let s =
|
|
2643
|
+
let s = $e(t, r, o);
|
|
2130
2644
|
if (i !== 0 && i !== 1) throw Error(`Invalid activeValue: ${i}. Indicator activation value must be 0 or 1.`);
|
|
2131
2645
|
if (n !== "<=" && n !== ">=") throw Error(`Invalid indicator sense for "${o}": expected "<=" or ">=", received "${String(n)}".`);
|
|
2132
2646
|
if (!Number.isFinite(a) || a < 0) throw Error(`Invalid Big-M value for indicator constraint "${o}": expected a finite non-negative number, received ${a}.`);
|
|
@@ -2137,11 +2651,532 @@ function X(e, t, n, r, i, a, o) {
|
|
|
2137
2651
|
let d = /* @__PURE__ */ new Map();
|
|
2138
2652
|
for (let [e, n] of t.terms) n !== 0 && d.set(e, n);
|
|
2139
2653
|
return l !== 0 && d.set(e, l), {
|
|
2140
|
-
lhs: new
|
|
2654
|
+
lhs: new C(d, 0),
|
|
2141
2655
|
rhs: u
|
|
2142
2656
|
};
|
|
2143
2657
|
}
|
|
2144
2658
|
//#endregion
|
|
2659
|
+
//#region src/modeler/linearizer.ts
|
|
2660
|
+
function X(e, t = 0) {
|
|
2661
|
+
return new C(new Map(e), t);
|
|
2662
|
+
}
|
|
2663
|
+
function nt(e, t, n, r) {
|
|
2664
|
+
let i = [...e], a = [...n], o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map();
|
|
2665
|
+
for (let e of n) s.set(e, e.name);
|
|
2666
|
+
let c = new Set(e.map((e) => e.name)), l = 0;
|
|
2667
|
+
function u(e) {
|
|
2668
|
+
let t;
|
|
2669
|
+
do
|
|
2670
|
+
t = `__washi_${e}_${++l}`;
|
|
2671
|
+
while (c.has(t));
|
|
2672
|
+
return c.add(t), t;
|
|
2673
|
+
}
|
|
2674
|
+
for (let e of t) {
|
|
2675
|
+
let t = e.name;
|
|
2676
|
+
c.has(t) ? t = u(`bool_${e.name}`) : c.add(t);
|
|
2677
|
+
let n = new M({
|
|
2678
|
+
name: t,
|
|
2679
|
+
type: "Binary",
|
|
2680
|
+
lb: 0,
|
|
2681
|
+
ub: 1
|
|
2682
|
+
});
|
|
2683
|
+
o.set(e, n), i.push(n);
|
|
2684
|
+
}
|
|
2685
|
+
function p(e, t) {
|
|
2686
|
+
if (e instanceof rt) return e.wrappedVar;
|
|
2687
|
+
if (e instanceof d) {
|
|
2688
|
+
let n = o.get(e);
|
|
2689
|
+
if (!n) throw Error(`Unregistered BoolVar "${e.name}" in logical constraint "${t}".`);
|
|
2690
|
+
return n;
|
|
2691
|
+
}
|
|
2692
|
+
let n = new M({
|
|
2693
|
+
name: u("expr"),
|
|
2694
|
+
type: "Binary",
|
|
2695
|
+
lb: 0,
|
|
2696
|
+
ub: 1
|
|
2697
|
+
});
|
|
2698
|
+
return i.push(n), h(n, e, t), n;
|
|
2699
|
+
}
|
|
2700
|
+
function m(e, t, n, r) {
|
|
2701
|
+
let i = new y(X([
|
|
2702
|
+
[e, 1],
|
|
2703
|
+
[t, -1],
|
|
2704
|
+
[n, -1]
|
|
2705
|
+
], 0), "<=", 0, `${r}_xor_1`), o = new y(X([
|
|
2706
|
+
[e, 1],
|
|
2707
|
+
[t, -1],
|
|
2708
|
+
[n, 1]
|
|
2709
|
+
], 0), ">=", 0, `${r}_xor_2`), c = new y(X([
|
|
2710
|
+
[e, 1],
|
|
2711
|
+
[n, -1],
|
|
2712
|
+
[t, 1]
|
|
2713
|
+
], 0), ">=", 0, `${r}_xor_3`), l = new y(X([
|
|
2714
|
+
[e, 1],
|
|
2715
|
+
[t, 1],
|
|
2716
|
+
[n, 1]
|
|
2717
|
+
], 0), "<=", 2, `${r}_xor_4`);
|
|
2718
|
+
a.push(i, o, c, l), s.set(i, r), s.set(o, r), s.set(c, r), s.set(l, r);
|
|
2719
|
+
}
|
|
2720
|
+
function h(e, t, n) {
|
|
2721
|
+
if (t instanceof d) {
|
|
2722
|
+
let r = o.get(t), i = new y(X([[e, 1], [r, -1]], 0), "==", 0, `${n}_equiv`);
|
|
2723
|
+
a.push(i), s.set(i, n);
|
|
2724
|
+
return;
|
|
2725
|
+
}
|
|
2726
|
+
if (t instanceof f) {
|
|
2727
|
+
if (t.op === "not") {
|
|
2728
|
+
let r = p(t.children[0], n), i = new y(X([[e, 1], [r, 1]], 0), "==", 1, `${n}_not`);
|
|
2729
|
+
a.push(i), s.set(i, n);
|
|
2730
|
+
return;
|
|
2731
|
+
}
|
|
2732
|
+
if (t.op === "and") {
|
|
2733
|
+
let r = t.children.map((e) => p(e, n));
|
|
2734
|
+
for (let t = 0; t < r.length; t++) {
|
|
2735
|
+
let i = new y(X([[e, 1], [r[t], -1]], 0), "<=", 0, `${n}_and_ub_${t}`);
|
|
2736
|
+
a.push(i), s.set(i, n);
|
|
2737
|
+
}
|
|
2738
|
+
let i = new y(X([[e, 1], ...r.map((e) => [e, -1])], 0), ">=", 1 - r.length, `${n}_and_lb`);
|
|
2739
|
+
a.push(i), s.set(i, n);
|
|
2740
|
+
return;
|
|
2741
|
+
}
|
|
2742
|
+
if (t.op === "or") {
|
|
2743
|
+
let r = t.children.map((e) => p(e, n));
|
|
2744
|
+
for (let t = 0; t < r.length; t++) {
|
|
2745
|
+
let i = new y(X([[e, 1], [r[t], -1]], 0), ">=", 0, `${n}_or_lb_${t}`);
|
|
2746
|
+
a.push(i), s.set(i, n);
|
|
2747
|
+
}
|
|
2748
|
+
let i = new y(X([[e, 1], ...r.map((e) => [e, -1])], 0), "<=", 0, `${n}_or_ub`);
|
|
2749
|
+
a.push(i), s.set(i, n);
|
|
2750
|
+
return;
|
|
2751
|
+
}
|
|
2752
|
+
if (t.op === "implies") {
|
|
2753
|
+
let r = p(t.children[0], n), i = p(t.children[1], n), o = new y(X([
|
|
2754
|
+
[e, 1],
|
|
2755
|
+
[i, -1],
|
|
2756
|
+
[r, 1]
|
|
2757
|
+
], 0), ">=", 0, `${n}_imp_1`), c = new y(X([
|
|
2758
|
+
[e, 1],
|
|
2759
|
+
[r, 1],
|
|
2760
|
+
[i, -1]
|
|
2761
|
+
], 0), "<=", 1, `${n}_imp_2`);
|
|
2762
|
+
a.push(o, c), s.set(o, n), s.set(c, n);
|
|
2763
|
+
return;
|
|
2764
|
+
}
|
|
2765
|
+
if (t.op === "xor") {
|
|
2766
|
+
if (t.children.length === 0) {
|
|
2767
|
+
let t = new y(X([[e, 1]], 0), "==", 0, `${n}_xor_empty`);
|
|
2768
|
+
a.push(t), s.set(t, n);
|
|
2769
|
+
return;
|
|
2770
|
+
}
|
|
2771
|
+
if (t.children.length === 1) {
|
|
2772
|
+
let r = p(t.children[0], n), i = new y(X([[e, 1], [r, -1]], 0), "==", 0, `${n}_xor_single`);
|
|
2773
|
+
a.push(i), s.set(i, n);
|
|
2774
|
+
return;
|
|
2775
|
+
}
|
|
2776
|
+
let r = t.children.map((e) => p(e, n)), o = r[0];
|
|
2777
|
+
for (let e = 1; e < r.length - 1; e++) {
|
|
2778
|
+
let t = new M({
|
|
2779
|
+
name: u(`xor_fold_${e}`),
|
|
2780
|
+
type: "Binary",
|
|
2781
|
+
lb: 0,
|
|
2782
|
+
ub: 1
|
|
2783
|
+
});
|
|
2784
|
+
i.push(t), m(t, o, r[e], `${n}_xor_fold_${e}`), o = t;
|
|
2785
|
+
}
|
|
2786
|
+
m(e, o, r[r.length - 1], n);
|
|
2787
|
+
return;
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
throw Error(`Unsupported logical element in equivalence linearization: ${t}`);
|
|
2791
|
+
}
|
|
2792
|
+
for (let e of r) {
|
|
2793
|
+
let t = e.name, n = e.expr;
|
|
2794
|
+
g(n, t);
|
|
2795
|
+
}
|
|
2796
|
+
function g(e, t) {
|
|
2797
|
+
if (e instanceof d) {
|
|
2798
|
+
let n = new y(X([[o.get(e), 1]], 0), ">=", 1, t);
|
|
2799
|
+
a.push(n), s.set(n, t);
|
|
2800
|
+
return;
|
|
2801
|
+
}
|
|
2802
|
+
if (e instanceof f) {
|
|
2803
|
+
if (e.op === "not") {
|
|
2804
|
+
let n = e.children[0];
|
|
2805
|
+
if (n instanceof d) {
|
|
2806
|
+
let e = new y(X([[o.get(n), 1]], 0), "<=", 0, t);
|
|
2807
|
+
a.push(e), s.set(e, t);
|
|
2808
|
+
return;
|
|
2809
|
+
}
|
|
2810
|
+
let r = new y(X([[p(n, t), 1]], 0), "<=", 0, t);
|
|
2811
|
+
a.push(r), s.set(r, t);
|
|
2812
|
+
return;
|
|
2813
|
+
}
|
|
2814
|
+
if (e.op === "and") {
|
|
2815
|
+
for (let n = 0; n < e.children.length; n++) g(e.children[n], `${t}_and_${n}`);
|
|
2816
|
+
return;
|
|
2817
|
+
}
|
|
2818
|
+
if (e.op === "or") {
|
|
2819
|
+
if (e.children.every((e) => e instanceof d || e instanceof f)) {
|
|
2820
|
+
let n = new y(X(e.children.map((e) => p(e, t)).map((e) => [e, 1]), 0), ">=", 1, t);
|
|
2821
|
+
a.push(n), s.set(n, t);
|
|
2822
|
+
return;
|
|
2823
|
+
}
|
|
2824
|
+
let n = [];
|
|
2825
|
+
for (let r = 0; r < e.children.length; r++) {
|
|
2826
|
+
let o = e.children[r], c = new M({
|
|
2827
|
+
name: u(`or_branch_${r}`),
|
|
2828
|
+
type: "Binary",
|
|
2829
|
+
lb: 0,
|
|
2830
|
+
ub: 1
|
|
2831
|
+
});
|
|
2832
|
+
if (i.push(c), n.push(c), o instanceof y) _(c, o, 1, `${t}_or_branch_${r}`, t);
|
|
2833
|
+
else {
|
|
2834
|
+
let e = p(o, t), n = new y(X([[c, 1], [e, -1]], 0), "<=", 0, `${t}_or_bool_${r}`);
|
|
2835
|
+
a.push(n), s.set(n, t);
|
|
2836
|
+
}
|
|
2837
|
+
}
|
|
2838
|
+
let r = new y(X(n.map((e) => [e, 1]), 0), ">=", 1, t);
|
|
2839
|
+
a.push(r), s.set(r, t);
|
|
2840
|
+
return;
|
|
2841
|
+
}
|
|
2842
|
+
if (e.op === "xor") {
|
|
2843
|
+
if (e.children.length === 0) {
|
|
2844
|
+
let e = new M({
|
|
2845
|
+
name: u("unsat"),
|
|
2846
|
+
type: "Binary",
|
|
2847
|
+
lb: 0,
|
|
2848
|
+
ub: 0
|
|
2849
|
+
});
|
|
2850
|
+
i.push(e);
|
|
2851
|
+
let n = new y(X([[e, 1]], 0), ">=", 1, t);
|
|
2852
|
+
a.push(n), s.set(n, t);
|
|
2853
|
+
return;
|
|
2854
|
+
}
|
|
2855
|
+
if (e.children.length === 1) {
|
|
2856
|
+
g(e.children[0], t);
|
|
2857
|
+
return;
|
|
2858
|
+
}
|
|
2859
|
+
let n = e.children.map((e) => p(e, t));
|
|
2860
|
+
if (n.length === 2) {
|
|
2861
|
+
let e = new y(X([[n[0], 1], [n[1], 1]], 0), "==", 1, t);
|
|
2862
|
+
a.push(e), s.set(e, t);
|
|
2863
|
+
return;
|
|
2864
|
+
}
|
|
2865
|
+
let r = n[0];
|
|
2866
|
+
for (let e = 1; e < n.length - 1; e++) {
|
|
2867
|
+
let a = new M({
|
|
2868
|
+
name: u(`xor_fold_${e}`),
|
|
2869
|
+
type: "Binary",
|
|
2870
|
+
lb: 0,
|
|
2871
|
+
ub: 1
|
|
2872
|
+
});
|
|
2873
|
+
i.push(a), m(a, r, n[e], `${t}_xor_fold_${e}`), r = a;
|
|
2874
|
+
}
|
|
2875
|
+
let o = n[n.length - 1], c = new y(X([[r, 1], [o, 1]], 0), "==", 1, t);
|
|
2876
|
+
a.push(c), s.set(c, t);
|
|
2877
|
+
return;
|
|
2878
|
+
}
|
|
2879
|
+
if (e.op === "implies") {
|
|
2880
|
+
let [n, r] = e.children;
|
|
2881
|
+
if (n instanceof y && n.lhs.terms.size === 1 && n.lhs.constant === 0) {
|
|
2882
|
+
let [[e, i]] = Array.from(n.lhs.terms.entries());
|
|
2883
|
+
if ((e.type === "Binary" || e.type === "Integer" && e.lb === 0 && e.ub === 1) && i === 1) {
|
|
2884
|
+
let i = null;
|
|
2885
|
+
if (n.sense === "==" && n.rhs === 1 ? i = 1 : n.sense === "==" && n.rhs === 0 || n.sense === "<=" && n.rhs === 0 ? i = 0 : n.sense === ">=" && n.rhs === 1 && (i = 1), i !== null && r instanceof y) {
|
|
2886
|
+
_(e, r, i, t, t);
|
|
2887
|
+
return;
|
|
2888
|
+
}
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
let c;
|
|
2892
|
+
if (n instanceof y ? (c = new M({
|
|
2893
|
+
name: u("ante"),
|
|
2894
|
+
type: "Binary",
|
|
2895
|
+
lb: 0,
|
|
2896
|
+
ub: 1
|
|
2897
|
+
}), i.push(c), _(c, n, 1, `${t}_ante_active`, t)) : c = p(n, t), r instanceof y) {
|
|
2898
|
+
_(c, r, 1, t, t);
|
|
2899
|
+
return;
|
|
2900
|
+
}
|
|
2901
|
+
if (r instanceof d) {
|
|
2902
|
+
let e = new y(X([[o.get(r), 1], [c, -1]], 0), ">=", 0, t);
|
|
2903
|
+
a.push(e), s.set(e, t);
|
|
2904
|
+
return;
|
|
2905
|
+
}
|
|
2906
|
+
if (r instanceof f) {
|
|
2907
|
+
if (r.op === "and") {
|
|
2908
|
+
for (let e = 0; e < r.children.length; e++) g(new f("implies", [c instanceof M ? new rt(c) : n, r.children[e]]), `${t}_and_${e}`);
|
|
2909
|
+
return;
|
|
2910
|
+
}
|
|
2911
|
+
if (r.op === "not") {
|
|
2912
|
+
let e = r.children[0], n = p(e, t), i = new y(X([[c, 1], [n, 1]], 0), "<=", 1, t);
|
|
2913
|
+
a.push(i), s.set(i, t);
|
|
2914
|
+
return;
|
|
2915
|
+
}
|
|
2916
|
+
let e = new y(X([[p(r, t), 1], [c, -1]], 0), ">=", 0, t);
|
|
2917
|
+
a.push(e), s.set(e, t);
|
|
2918
|
+
return;
|
|
2919
|
+
}
|
|
2920
|
+
}
|
|
2921
|
+
}
|
|
2922
|
+
throw Error(`Unsupported top-level logical constraint "${t}": ${e}`);
|
|
2923
|
+
}
|
|
2924
|
+
function _(e, t, n, r, i) {
|
|
2925
|
+
let { lhs: o, sense: c, rhs: l } = t;
|
|
2926
|
+
if (c === "<=" || c === ">=") {
|
|
2927
|
+
let t = Y(e, o, c, l, n, c === "<=" ? et(o, l, r) : tt(o, l, r), r), u = new y(t.lhs, c, t.rhs, r);
|
|
2928
|
+
a.push(u), s.set(u, i);
|
|
2929
|
+
} else {
|
|
2930
|
+
let t = et(o, l, `${r}_le`), c = tt(o, l, `${r}_ge`), u = Y(e, o, "<=", l, n, t, `${r}_le`), d = Y(e, o, ">=", l, n, c, `${r}_ge`), f = new y(u.lhs, "<=", u.rhs, `${r}_le`), p = new y(d.lhs, ">=", d.rhs, `${r}_ge`);
|
|
2931
|
+
a.push(f, p), s.set(f, i), s.set(p, i);
|
|
2932
|
+
}
|
|
2933
|
+
}
|
|
2934
|
+
return {
|
|
2935
|
+
variables: i,
|
|
2936
|
+
constraints: a,
|
|
2937
|
+
boolVarToBinary: o,
|
|
2938
|
+
constraintToOriginalName: s
|
|
2939
|
+
};
|
|
2940
|
+
}
|
|
2941
|
+
var rt = class extends d {
|
|
2942
|
+
wrappedVar;
|
|
2943
|
+
constructor(e) {
|
|
2944
|
+
super(e.name), this.wrappedVar = e;
|
|
2945
|
+
}
|
|
2946
|
+
};
|
|
2947
|
+
//#endregion
|
|
2948
|
+
//#region src/decomposition/column-generation.ts
|
|
2949
|
+
async function it(e) {
|
|
2950
|
+
let t = e.master;
|
|
2951
|
+
if (!t) throw Error("A master Model must be provided for solveColumnGeneration.");
|
|
2952
|
+
let { pricing: n, maxIterations: r = 100, reducedCostTolerance: i = 1e-6, finalizeAsMIP: a = !0, solver: o, solverOptions: s, onIteration: c } = e, l = t.sense.toLowerCase() === "maximize", u = n;
|
|
2953
|
+
if (!u) throw Error("The 'pricing' callback must be provided in ColumnGenerationOptions.");
|
|
2954
|
+
let d = [], f = null, p = 0, m = t.status;
|
|
2955
|
+
for (let e = 1; e <= r; e++) {
|
|
2956
|
+
p = e;
|
|
2957
|
+
let n = await t.relax(o, s);
|
|
2958
|
+
if (m = n, n !== "Optimal" && n !== "Feasible" || !t.solution) break;
|
|
2959
|
+
f = t.objectiveValue;
|
|
2960
|
+
let r = t.solution, a = r.duals || {}, h = (e) => typeof e == "string" ? a[e] ?? 0 : e.dual ?? (e.name ? a[e.name] ?? 0 : 0), g = await u({
|
|
2961
|
+
iteration: e,
|
|
2962
|
+
duals: a,
|
|
2963
|
+
getDual: h,
|
|
2964
|
+
masterSolution: r,
|
|
2965
|
+
reducedCostTolerance: i,
|
|
2966
|
+
master: t
|
|
2967
|
+
}), _ = [];
|
|
2968
|
+
g && (Array.isArray(g) ? _.push(...g) : _.push(g));
|
|
2969
|
+
let v = [];
|
|
2970
|
+
for (let e of _) {
|
|
2971
|
+
let t = e.reducedCost;
|
|
2972
|
+
if (typeof t != "number" || !Number.isFinite(t)) {
|
|
2973
|
+
let n = 0, r = e.coefficients;
|
|
2974
|
+
if (Array.isArray(r)) for (let e of r) Array.isArray(e) ? n += e[1] * h(e[0]) : e && typeof e == "object" && (n += e.coeff * h(e.constraint));
|
|
2975
|
+
else if (r instanceof Map) for (let [e, t] of r.entries()) n += t * h(e);
|
|
2976
|
+
else if (r && typeof r == "object") for (let [e, t] of Object.entries(r)) n += t * h(e);
|
|
2977
|
+
t = e.cost - n;
|
|
2978
|
+
}
|
|
2979
|
+
(l ? t > i : t < -i) && v.push(e);
|
|
2980
|
+
}
|
|
2981
|
+
if (c && c({
|
|
2982
|
+
iteration: e,
|
|
2983
|
+
relaxationObjective: f,
|
|
2984
|
+
columnsAdded: d.length + v.length,
|
|
2985
|
+
proposedColumns: v
|
|
2986
|
+
}), v.length === 0) break;
|
|
2987
|
+
for (let e of v) {
|
|
2988
|
+
let n = t.addColumn({
|
|
2989
|
+
name: e.name,
|
|
2990
|
+
type: e.type || "Continuous",
|
|
2991
|
+
lb: e.lb,
|
|
2992
|
+
ub: e.ub,
|
|
2993
|
+
cost: e.cost,
|
|
2994
|
+
coefficients: e.coefficients
|
|
2995
|
+
});
|
|
2996
|
+
d.push({
|
|
2997
|
+
variable: n,
|
|
2998
|
+
proposal: e
|
|
2999
|
+
});
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
let h = f;
|
|
3003
|
+
a && (m === "Optimal" || m === "Feasible") && (m = await t.solve(o, s), h = t.objectiveValue);
|
|
3004
|
+
let g = {};
|
|
3005
|
+
for (let e of t.variables) e.value !== null && (g[e.name] = e.value);
|
|
3006
|
+
let _ = {
|
|
3007
|
+
status: m,
|
|
3008
|
+
objectiveValue: h,
|
|
3009
|
+
relaxationObjectiveValue: f,
|
|
3010
|
+
iterations: p,
|
|
3011
|
+
columnsAdded: d.length,
|
|
3012
|
+
generatedColumns: d,
|
|
3013
|
+
master: t,
|
|
3014
|
+
values: g
|
|
3015
|
+
};
|
|
3016
|
+
return t.decomposition = _, _;
|
|
3017
|
+
}
|
|
3018
|
+
//#endregion
|
|
3019
|
+
//#region src/modeler/objective.ts
|
|
3020
|
+
function at(e, t) {
|
|
3021
|
+
let n = e;
|
|
3022
|
+
if (n instanceof y || typeof n == "object" && n && "sense" in n && "lhs" in n && "rhs" in n) throw Error(`Cannot use a Constraint as an objective in ${t}(). Use m.constraint(expr\`... <= ...\`) for constraints, or supply an unconstrained arithmetic expression to ${t}(), e.g. m.objective(${t}(expr\`30 * \${x}\`)).`);
|
|
3023
|
+
if (typeof n == "string" && /(<=|>=|==|=<|=>|=)/.test(n)) throw Error(`Cannot use a comparison constraint as an objective in ${t}(). Use m.constraint(expr\`... <= ...\`) for constraints, or supply an unconstrained arithmetic expression to ${t}(), e.g. m.objective(${t}(expr\`30 * \${x}\`)).`);
|
|
3024
|
+
if (typeof n == "number") {
|
|
3025
|
+
if (!Number.isFinite(n)) throw Error(`Invalid non-finite objective constant "${n}" passed to ${t}().`);
|
|
3026
|
+
return n;
|
|
3027
|
+
}
|
|
3028
|
+
if (typeof n == "string" || n instanceof C || n instanceof S || n instanceof M || 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;
|
|
3029
|
+
throw Error(`Invalid expression passed to ${t}(): expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.`);
|
|
3030
|
+
}
|
|
3031
|
+
function ot(e) {
|
|
3032
|
+
return {
|
|
3033
|
+
expr: at(e, "maximize"),
|
|
3034
|
+
sense: "Maximize"
|
|
3035
|
+
};
|
|
3036
|
+
}
|
|
3037
|
+
function st(e) {
|
|
3038
|
+
return {
|
|
3039
|
+
expr: at(e, "minimize"),
|
|
3040
|
+
sense: "Minimize"
|
|
3041
|
+
};
|
|
3042
|
+
}
|
|
3043
|
+
//#endregion
|
|
3044
|
+
//#region src/decomposition/benders.ts
|
|
3045
|
+
function ct(e) {
|
|
3046
|
+
return !!(e && typeof e == "object" && "constraints" in e && "variables" in e && typeof e.solve == "function");
|
|
3047
|
+
}
|
|
3048
|
+
async function lt(e, t, n, r, i, a, o, s, c = 1) {
|
|
3049
|
+
let l = [];
|
|
3050
|
+
for (let r = 0; r < t.length; r++) {
|
|
3051
|
+
let a = t[r], o = a.lhs, s = a.sense, u = a.rhs - (o.constant || 0), d = [], f = [], p = 0;
|
|
3052
|
+
for (let [e, t] of o.terms.entries()) if (e.ownerModel === n || n.getVarByName(e.name) !== void 0) {
|
|
3053
|
+
f.push([e, t]);
|
|
3054
|
+
let n = i[e.name] ?? 0;
|
|
3055
|
+
p += t * n;
|
|
3056
|
+
} else d.push([e, t]);
|
|
3057
|
+
let m = u - p, h = new C();
|
|
3058
|
+
for (let [e, t] of d) h.addTerm(e, t);
|
|
3059
|
+
let g = new y(h, s, m, `__benders_link_${c}_${r}`);
|
|
3060
|
+
e.constraint(g), l.push({
|
|
3061
|
+
origConstraint: a,
|
|
3062
|
+
subConstr: g,
|
|
3063
|
+
masterTerms: f,
|
|
3064
|
+
baseRhs: u
|
|
3065
|
+
});
|
|
3066
|
+
}
|
|
3067
|
+
let u = await e.solve(o, {
|
|
3068
|
+
...s,
|
|
3069
|
+
relax: !0
|
|
3070
|
+
});
|
|
3071
|
+
if (u !== "Optimal" && u !== "Feasible") return null;
|
|
3072
|
+
let d = e.objectiveValue ?? 0, f = i[r.name] ?? 0, p = 1e-4;
|
|
3073
|
+
if (!(a ? f < d - p : f > d + p)) return null;
|
|
3074
|
+
let m = 0, h = /* @__PURE__ */ new Map(), g = new Set(l.map((e) => e.subConstr.name));
|
|
3075
|
+
for (let t of e.constraints) {
|
|
3076
|
+
if (g.has(t.name)) continue;
|
|
3077
|
+
let n = e.solution?.duals[t.name] ?? t.dual ?? 0;
|
|
3078
|
+
if (Math.abs(n) > 1e-12) {
|
|
3079
|
+
let e = t.rhs - (t.lhs.constant || 0);
|
|
3080
|
+
m += n * e;
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
for (let t of l) {
|
|
3084
|
+
let n = e.solution?.duals[t.subConstr.name] ?? t.subConstr.dual ?? 0;
|
|
3085
|
+
if (Math.abs(n) > 1e-12) {
|
|
3086
|
+
m += n * t.baseRhs;
|
|
3087
|
+
for (let [e, r] of t.masterTerms) {
|
|
3088
|
+
let t = h.get(e) ?? 0;
|
|
3089
|
+
h.set(e, t + n * r);
|
|
3090
|
+
}
|
|
3091
|
+
}
|
|
3092
|
+
}
|
|
3093
|
+
let _ = new C();
|
|
3094
|
+
_.addTerm(r, 1);
|
|
3095
|
+
for (let [e, t] of h.entries()) Math.abs(t) > 1e-12 && _.addTerm(e, t);
|
|
3096
|
+
let v = new y(_, a ? ">=" : "<=", m, `__benders_opt_cut_${c}`), b = (n.objectiveValue ?? 0) - f + d;
|
|
3097
|
+
return {
|
|
3098
|
+
kind: "optimality",
|
|
3099
|
+
constraint: v,
|
|
3100
|
+
name: v.name,
|
|
3101
|
+
subproblemObjective: b
|
|
3102
|
+
};
|
|
3103
|
+
}
|
|
3104
|
+
async function ut(e) {
|
|
3105
|
+
let t = e.master;
|
|
3106
|
+
if (!t) throw Error("A master Model must be provided for solveBenders.");
|
|
3107
|
+
let { subproblem: n, maxIterations: r = 100, gapTolerance: i = 1e-4, solver: a, solverOptions: o, onIteration: s } = e, c;
|
|
3108
|
+
e.theta && (c = typeof e.theta == "string" ? t.getVarByName(e.theta) : e.theta), c ||= t.variables.find((e) => e.name === "theta" || e.name === "__benders_theta");
|
|
3109
|
+
let l = 0, u = 0, d = t.status, f, p, m, h = {}, g = null;
|
|
3110
|
+
for (let e = 1; e <= r; e++) {
|
|
3111
|
+
u = e;
|
|
3112
|
+
let r = await t.solve(a, o);
|
|
3113
|
+
if (d = r, r !== "Optimal" && r !== "Feasible") break;
|
|
3114
|
+
let _ = t.objectiveValue, v = t.sense.toLowerCase() === "minimize";
|
|
3115
|
+
v ? f = _ === null ? f : _ : p = _ === null ? p : _;
|
|
3116
|
+
let y = {};
|
|
3117
|
+
for (let e of t.variables) e.value !== null && (y[e.name] = e.value);
|
|
3118
|
+
let b = await n({
|
|
3119
|
+
iteration: e,
|
|
3120
|
+
masterValues: y,
|
|
3121
|
+
getMasterValue: (e) => typeof e == "string" ? y[e] ?? 0 : e.value ?? (e.name ? y[e.name] ?? 0 : 0),
|
|
3122
|
+
masterObjective: _,
|
|
3123
|
+
lowerBound: f,
|
|
3124
|
+
upperBound: p,
|
|
3125
|
+
master: t
|
|
3126
|
+
}), x = [];
|
|
3127
|
+
if (b) {
|
|
3128
|
+
if (ct(b)) {
|
|
3129
|
+
let n = b, r = n.linkingConstraints;
|
|
3130
|
+
c || (c = t.continuous("__benders_theta", { lb: 0 }), v ? t.objective(st(t.objectiveExpr.add(c))) : t.objective(ot(t.objectiveExpr.sub(c))));
|
|
3131
|
+
let i = await lt(n, r, t, c, y, v, a, o, e);
|
|
3132
|
+
i && x.push(i);
|
|
3133
|
+
} else Array.isArray(b) ? x.push(...b) : x.push(b);
|
|
3134
|
+
}
|
|
3135
|
+
for (let e of x) if (typeof e.subproblemObjective == "number" && Number.isFinite(e.subproblemObjective)) {
|
|
3136
|
+
if (v) {
|
|
3137
|
+
let t = e.subproblemObjective;
|
|
3138
|
+
(p === void 0 || t < p) && (p = t, g = t, h = { ...y });
|
|
3139
|
+
} else {
|
|
3140
|
+
let t = e.subproblemObjective;
|
|
3141
|
+
(f === void 0 || t > f) && (f = t, g = t, h = { ...y });
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
3144
|
+
if (f !== void 0 && p !== void 0) {
|
|
3145
|
+
let e = Math.abs(p) + 1e-10;
|
|
3146
|
+
m = Math.abs(p - f) / e;
|
|
3147
|
+
}
|
|
3148
|
+
if (s && s({
|
|
3149
|
+
iteration: e,
|
|
3150
|
+
masterObjective: _,
|
|
3151
|
+
lowerBound: f,
|
|
3152
|
+
upperBound: p,
|
|
3153
|
+
cutsAdded: l + x.length,
|
|
3154
|
+
proposedCuts: x
|
|
3155
|
+
}), x.length === 0) {
|
|
3156
|
+
g = _, h = { ...y };
|
|
3157
|
+
break;
|
|
3158
|
+
}
|
|
3159
|
+
if (m !== void 0 && m <= i) break;
|
|
3160
|
+
for (let e of x) t.constraint(e.constraint, e.name), l++;
|
|
3161
|
+
}
|
|
3162
|
+
let _ = Object.keys(h).length > 0 ? h : (() => {
|
|
3163
|
+
let e = {};
|
|
3164
|
+
for (let n of t.variables) n.value !== null && (e[n.name] = n.value);
|
|
3165
|
+
return e;
|
|
3166
|
+
})(), v = g === null ? t.objectiveValue : g, y = {
|
|
3167
|
+
status: d,
|
|
3168
|
+
objectiveValue: v,
|
|
3169
|
+
lowerBound: f,
|
|
3170
|
+
upperBound: p,
|
|
3171
|
+
gap: m,
|
|
3172
|
+
iterations: u,
|
|
3173
|
+
cutsAdded: l,
|
|
3174
|
+
master: t,
|
|
3175
|
+
values: _
|
|
3176
|
+
};
|
|
3177
|
+
return t.decomposition = y, y;
|
|
3178
|
+
}
|
|
3179
|
+
//#endregion
|
|
2145
3180
|
//#region src/modeler/model.ts
|
|
2146
3181
|
function Z(e) {
|
|
2147
3182
|
return Array.isArray(e) || typeof e == "object" && !!e && !(e instanceof String) && typeof e[Symbol.iterator] == "function";
|
|
@@ -2149,10 +3184,13 @@ function Z(e) {
|
|
|
2149
3184
|
function Q(e) {
|
|
2150
3185
|
return typeof e == "object" && !!e && !Array.isArray(e) && !(e instanceof String) && typeof e[Symbol.iterator] != "function";
|
|
2151
3186
|
}
|
|
3187
|
+
function dt(e) {
|
|
3188
|
+
return e instanceof M || typeof e == "object" && !!e && !(e instanceof u) && !(e instanceof y) && "id" in e && "name" in e && "lb" in e && "ub" in e && !("terms" in e) && !("quadTerms" in e) && !("sense" in e);
|
|
3189
|
+
}
|
|
2152
3190
|
function $(e, t) {
|
|
2153
3191
|
if (!Number.isInteger(e) || e < 0) throw Error(`Invalid count (${e}) for ${t} variable creation: count must be a non-negative integer.`);
|
|
2154
3192
|
}
|
|
2155
|
-
var
|
|
3193
|
+
var ft = class {
|
|
2156
3194
|
name;
|
|
2157
3195
|
_sense;
|
|
2158
3196
|
_objectiveExpr;
|
|
@@ -2161,6 +3199,7 @@ var ze = class {
|
|
|
2161
3199
|
boolVars = [];
|
|
2162
3200
|
logicalConstraints = [];
|
|
2163
3201
|
unsatCore = void 0;
|
|
3202
|
+
_conflicts = void 0;
|
|
2164
3203
|
values = /* @__PURE__ */ new Map();
|
|
2165
3204
|
varMapByName = /* @__PURE__ */ new Map();
|
|
2166
3205
|
varPrefixCounters = /* @__PURE__ */ new Map();
|
|
@@ -2181,6 +3220,8 @@ var ze = class {
|
|
|
2181
3220
|
runTime = 0;
|
|
2182
3221
|
solution = null;
|
|
2183
3222
|
solver = null;
|
|
3223
|
+
decomposition;
|
|
3224
|
+
_linkingConstraints;
|
|
2184
3225
|
hasSolutionState = !1;
|
|
2185
3226
|
modelRevision = 0;
|
|
2186
3227
|
activeOperationId = 0;
|
|
@@ -2192,13 +3233,13 @@ var ze = class {
|
|
|
2192
3233
|
n = typeof e == "string" ? {
|
|
2193
3234
|
...t,
|
|
2194
3235
|
name: e
|
|
2195
|
-
} : e, this.name = n.name || "OptimizationModel", this._sense =
|
|
3236
|
+
} : e, this.name = n.name || "OptimizationModel", this._sense = s(n.sense), this._objectiveExpr = new C(), n.solver && (this.solver = G(n.solver));
|
|
2196
3237
|
}
|
|
2197
3238
|
get sense() {
|
|
2198
3239
|
return this._sense;
|
|
2199
3240
|
}
|
|
2200
3241
|
set sense(e) {
|
|
2201
|
-
let t =
|
|
3242
|
+
let t = s(e);
|
|
2202
3243
|
this._sense !== t && (this._sense = t, this.recordModelMutation());
|
|
2203
3244
|
}
|
|
2204
3245
|
get objectiveExpr() {
|
|
@@ -2208,7 +3249,10 @@ var ze = class {
|
|
|
2208
3249
|
this.applyObjective(e);
|
|
2209
3250
|
}
|
|
2210
3251
|
get conflicts() {
|
|
2211
|
-
return this.unsatCore;
|
|
3252
|
+
return this._conflicts ?? this.unsatCore;
|
|
3253
|
+
}
|
|
3254
|
+
set conflicts(e) {
|
|
3255
|
+
this._conflicts = e;
|
|
2212
3256
|
}
|
|
2213
3257
|
get numVars() {
|
|
2214
3258
|
return this.variables.length;
|
|
@@ -2218,7 +3262,7 @@ var ze = class {
|
|
|
2218
3262
|
}
|
|
2219
3263
|
clearSolutionFields() {
|
|
2220
3264
|
if (this.hasSolutionState || this.status !== "NotSolved" || this.terminationStatus !== "NotSolved" || this.hasPrimalSolution || this.solution !== null || this.unsatCore !== void 0) {
|
|
2221
|
-
this.hasSolutionState = !1, this.status = "NotSolved", this.terminationStatus = "NotSolved", this.hasPrimalSolution = !1, this.objectiveValue = null, this.objectiveBound = void 0, this.relGap = void 0, this.mipGap = void 0, this.absGap = void 0, this.solution = null, this.runTime = 0, this.unsatCore = void 0, this.values.clear();
|
|
3265
|
+
this.hasSolutionState = !1, this.status = "NotSolved", this.terminationStatus = "NotSolved", this.hasPrimalSolution = !1, this.objectiveValue = null, this.objectiveBound = void 0, this.relGap = void 0, this.mipGap = void 0, this.absGap = void 0, this.solution = null, this.runTime = 0, this.unsatCore = void 0, this._conflicts = void 0, this.values.clear();
|
|
2222
3266
|
for (let e of this.variables) e.value = null, e.reducedCost = null;
|
|
2223
3267
|
for (let e of this.boolVars) e.value = null;
|
|
2224
3268
|
for (let e of this.constraints) e.dual = null, e.slack = null;
|
|
@@ -2250,7 +3294,7 @@ var ze = class {
|
|
|
2250
3294
|
this.batchDepth = 0, this.batchMutated = !1;
|
|
2251
3295
|
for (let e = t; e < this.variables.length; e++) {
|
|
2252
3296
|
let t = this.variables[e];
|
|
2253
|
-
this.varMapByName.delete(t.name), t.ownerModel = null,
|
|
3297
|
+
this.varMapByName.delete(t.name), t.ownerModel = null, ne(t, this);
|
|
2254
3298
|
}
|
|
2255
3299
|
this.variables.length = t;
|
|
2256
3300
|
for (let e = n; e < this.boolVars.length; e++) {
|
|
@@ -2343,6 +3387,37 @@ var ze = class {
|
|
|
2343
3387
|
continuous(e, t, n) {
|
|
2344
3388
|
return this.createDomainVars("Continuous", e, t, n);
|
|
2345
3389
|
}
|
|
3390
|
+
addColumn(e) {
|
|
3391
|
+
let t = e.type || "Continuous", n = this.addVar({
|
|
3392
|
+
name: e.name,
|
|
3393
|
+
type: t,
|
|
3394
|
+
lb: e.lb,
|
|
3395
|
+
ub: e.ub
|
|
3396
|
+
});
|
|
3397
|
+
if (typeof e.cost == "number" && e.cost !== 0 && (this._objectiveExpr = this._objectiveExpr.add(n.mul(e.cost)), this.recordModelMutation()), e.coefficients) {
|
|
3398
|
+
if (Array.isArray(e.coefficients)) {
|
|
3399
|
+
for (let t of e.coefficients) if (Array.isArray(t)) {
|
|
3400
|
+
let [e, r] = t, i = typeof e == "string" ? this.getConstraintByName(e) : e;
|
|
3401
|
+
if (!i) throw Error(`Constraint '${String(e)}' not found in model when adding column`);
|
|
3402
|
+
i.addTerm(n, r);
|
|
3403
|
+
} else if (typeof t == "object" && t) {
|
|
3404
|
+
let e = typeof t.constraint == "string" ? this.getConstraintByName(t.constraint) : t.constraint;
|
|
3405
|
+
if (!e) throw Error(`Constraint '${String(t.constraint)}' not found in model when adding column`);
|
|
3406
|
+
e.addTerm(n, t.coeff);
|
|
3407
|
+
}
|
|
3408
|
+
} else if (e.coefficients instanceof Map) for (let [t, r] of e.coefficients.entries()) {
|
|
3409
|
+
let e = typeof t == "string" ? this.getConstraintByName(t) : t;
|
|
3410
|
+
if (!e) throw Error(`Constraint '${String(t)}' not found in model when adding column`);
|
|
3411
|
+
e.addTerm(n, r);
|
|
3412
|
+
}
|
|
3413
|
+
else if (typeof e.coefficients == "object") for (let [t, r] of Object.entries(e.coefficients)) {
|
|
3414
|
+
let e = this.getConstraintByName(t);
|
|
3415
|
+
if (!e) throw Error(`Constraint '${t}' not found in model when adding column`);
|
|
3416
|
+
e.addTerm(n, r);
|
|
3417
|
+
}
|
|
3418
|
+
}
|
|
3419
|
+
return n;
|
|
3420
|
+
}
|
|
2346
3421
|
bool(e, t, n) {
|
|
2347
3422
|
let r = typeof e == "number", i = typeof t == "number", a = Z(e), o = Z(t);
|
|
2348
3423
|
if (i || o) {
|
|
@@ -2418,19 +3493,19 @@ var ze = class {
|
|
|
2418
3493
|
let n = typeof e == "string" ? e.trim() : void 0, r = typeof t == "string" ? t.trim() : "", i = r.length > 0 ? r : "p", a = n && n.length > 0 ? n : this.getNextBoolVarName(i);
|
|
2419
3494
|
if (this.hasVarName(a)) throw Error(`Variable with name '${a}' already exists in model`);
|
|
2420
3495
|
if (this.hasConstraintName(a)) throw Error(`Boolean variable name '${a}' conflicts with an existing constraint in model`);
|
|
2421
|
-
let o = new
|
|
3496
|
+
let o = new d(a);
|
|
2422
3497
|
return this.boolVars.push(o), this.boolVarMapByName.set(o.name, o), this.recordModelMutation(), o;
|
|
2423
3498
|
}
|
|
2424
3499
|
addVar(e) {
|
|
2425
3500
|
let t = e || {}, n = typeof t.name == "string" ? t.name.trim() : void 0, r = n && n.length > 0 ? n : void 0, i = typeof t.prefix == "string" ? t.prefix.trim() : "", a = i.length > 0 ? i : "x", o = this.varPrefixCounters.get(a), s = r ?? this.getNextVarName(a);
|
|
2426
3501
|
try {
|
|
2427
3502
|
if (this.hasVarName(s)) throw Error(`Variable with name '${s}' already exists in model`);
|
|
2428
|
-
let e = new
|
|
3503
|
+
let e = new M({
|
|
2429
3504
|
...t,
|
|
2430
3505
|
name: s,
|
|
2431
3506
|
prefix: a
|
|
2432
3507
|
});
|
|
2433
|
-
return e.hasExplicitName = r !== void 0, A(e),
|
|
3508
|
+
return e.hasExplicitName = r !== void 0, A(e), ee(e, this), e.ownerModel = this, this.variables.push(e), this.varMapByName.set(e.name, e), this.recordModelMutation(), e;
|
|
2434
3509
|
} catch (e) {
|
|
2435
3510
|
throw r === void 0 && (o === void 0 ? this.varPrefixCounters.delete(a) : this.varPrefixCounters.set(a, o)), e;
|
|
2436
3511
|
}
|
|
@@ -2448,37 +3523,43 @@ var ze = class {
|
|
|
2448
3523
|
return this.logicalConstrMapByName.get(e);
|
|
2449
3524
|
}
|
|
2450
3525
|
objective(e) {
|
|
2451
|
-
|
|
3526
|
+
if (arguments.length === 0) return this.objectiveExpr;
|
|
3527
|
+
let t = e;
|
|
3528
|
+
if (t instanceof y || typeof t == "object" && t && "sense" in t && "lhs" in t && "rhs" in t || typeof t == "string" && /(<=|>=|==|=<|=>|=)/.test(t)) throw Error("Cannot use a Constraint as an objective. Did you mean to use m.constraint(expr`... <= ...`)? To set an objective, wrap an unconstrained expression with maximize(...) or minimize(...), e.g. m.objective(maximize(expr`30 * ${x}`)).");
|
|
3529
|
+
if (typeof t != "object" || !t || !("expr" in t) || !("sense" in t)) throw Error("m.objective(...) expects an ObjectiveSpec created with maximize(...) or minimize(...), e.g. m.objective(maximize(expr`30 * ${x}`)).");
|
|
3530
|
+
return this.applyObjective(t.expr, t.sense), this;
|
|
2452
3531
|
}
|
|
2453
3532
|
applyObjective(e, t) {
|
|
2454
|
-
if (e instanceof
|
|
2455
|
-
let n = t === void 0 ? this.sense :
|
|
2456
|
-
if (typeof e == "string") r =
|
|
2457
|
-
else if (typeof e == "number") r = new
|
|
2458
|
-
else if (e instanceof x) r = e.clone();
|
|
3533
|
+
if (e instanceof y || typeof e == "object" && e && "sense" in e && "lhs" in e && "rhs" in e || typeof e == "string" && /(<=|>=|==|=<|=>|=)/.test(e)) throw Error(typeof e == "string" ? "Cannot use a comparison constraint as an objective. Did you mean to use m.constraint(expr`... <= ...`)? To set an objective, wrap an unconstrained expression with maximize(...) or minimize(...), e.g. m.objective(maximize(expr`30 * ${x}`))." : "Cannot use a Constraint as an objective. Did you mean to use m.constraint(expr`... <= ...`)? To set an objective, wrap an unconstrained expression with maximize(...) or minimize(...), e.g. m.objective(maximize(expr`30 * ${x}`)).");
|
|
3534
|
+
let n = t === void 0 ? this.sense : s(t), r;
|
|
3535
|
+
if (typeof e == "string") r = Ce(e, (e) => this.getVarByName(e));
|
|
3536
|
+
else if (typeof e == "number") r = new C(/* @__PURE__ */ new Map(), e);
|
|
2459
3537
|
else if (e instanceof S) r = e.clone();
|
|
3538
|
+
else if (e instanceof C) r = e.clone();
|
|
2460
3539
|
else if (typeof e == "object" && e && "quadTerms" in e && e.quadTerms instanceof Map && "linearTerms" in e && e.linearTerms instanceof Map && typeof e.constant == "number") {
|
|
2461
3540
|
let t = e;
|
|
2462
|
-
r = new
|
|
3541
|
+
r = new S(t.linearTerms, t.quadTerms, t.constant);
|
|
2463
3542
|
} else if (typeof e == "object" && e && "terms" in e && e.terms instanceof Map && typeof e.constant == "number") {
|
|
2464
3543
|
let t = e;
|
|
2465
|
-
r = new
|
|
2466
|
-
} else if (e instanceof
|
|
3544
|
+
r = new C(t.terms, t.constant);
|
|
3545
|
+
} else if (e instanceof M || typeof e == "object" && e && "id" in e && "name" in e && "lb" in e && "ub" in e) r = new C(/* @__PURE__ */ new Map([[e, 1]]), 0);
|
|
2467
3546
|
else throw Error("Invalid objective expression: expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.");
|
|
2468
|
-
|
|
3547
|
+
oe(r, this.name, (e) => this.varMapByName.get(e.name) === e), this._sense = n, this._objectiveExpr = r, this.recordModelMutation();
|
|
2469
3548
|
}
|
|
2470
3549
|
constraint(e, t) {
|
|
2471
3550
|
if (Array.isArray(e)) return this.runTransactionalBatch(() => {
|
|
2472
|
-
|
|
2473
|
-
|
|
3551
|
+
let t = [];
|
|
3552
|
+
for (let n of e) t.push(this.constraint(n));
|
|
3553
|
+
return t;
|
|
2474
3554
|
});
|
|
2475
|
-
if (e instanceof
|
|
2476
|
-
if (e instanceof
|
|
2477
|
-
|
|
3555
|
+
if (e instanceof S || typeof e == "object" && e && "quadTerms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a quadratic expression as a constraint.");
|
|
3556
|
+
if (e instanceof C || 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().");
|
|
3557
|
+
if (dt(e)) throw Error(`Cannot add numeric variable "${e.name}" directly as a constraint without a comparison operator (<=, >=, ==). Numeric variables require a comparison such as expr\`\${x} <= 10\` or x.le(10), whereas propositional BoolVar variables must be created with m.bool().`);
|
|
3558
|
+
return this.addConstraint(e, t);
|
|
2478
3559
|
}
|
|
2479
3560
|
getValues(e) {
|
|
2480
3561
|
if (e == null) return null;
|
|
2481
|
-
if (e instanceof
|
|
3562
|
+
if (e instanceof M || e instanceof d) return e.value;
|
|
2482
3563
|
if (Array.isArray(e)) return e.map((e) => this.getValues(e));
|
|
2483
3564
|
if (typeof e == "object") {
|
|
2484
3565
|
let t = {};
|
|
@@ -2488,9 +3569,10 @@ var ze = class {
|
|
|
2488
3569
|
return null;
|
|
2489
3570
|
}
|
|
2490
3571
|
addConstraint(e, t) {
|
|
2491
|
-
if (e instanceof
|
|
2492
|
-
if (e instanceof
|
|
2493
|
-
if (e
|
|
3572
|
+
if (e instanceof S || typeof e == "object" && e && "quadTerms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a quadratic expression as a constraint.");
|
|
3573
|
+
if (e instanceof C || 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().");
|
|
3574
|
+
if (dt(e)) throw Error(`Cannot add numeric variable "${e.name}" directly as a constraint without a comparison operator (<=, >=, ==). Numeric variables require a comparison such as expr\`\${x} <= 10\` or x.le(10), whereas propositional BoolVar variables must be created with m.bool().`);
|
|
3575
|
+
if (e instanceof u) {
|
|
2494
3576
|
let n = typeof t == "string" && t.trim().length > 0 ? t.trim() : void 0;
|
|
2495
3577
|
if (n !== void 0) {
|
|
2496
3578
|
if (this.hasConstraintName(n)) throw Error(`Constraint with name '${n}' already exists in model`);
|
|
@@ -2498,19 +3580,20 @@ var ze = class {
|
|
|
2498
3580
|
}
|
|
2499
3581
|
let r = this.logicalConstrCounter, i = n ?? this.getNextLogicalConstrName();
|
|
2500
3582
|
try {
|
|
2501
|
-
|
|
3583
|
+
se(e, i, this.name, (e) => this.varMapByName.get(e.name) === e, (e) => this.boolVarMapByName.get(e.name) === e, this);
|
|
2502
3584
|
} catch (e) {
|
|
2503
3585
|
throw n === void 0 && (this.logicalConstrCounter = r), e;
|
|
2504
3586
|
}
|
|
2505
|
-
|
|
3587
|
+
k(e, this, this.batchDepth > 0 ? this.batchUndoActions : void 0);
|
|
2506
3588
|
let a = {
|
|
2507
3589
|
name: i,
|
|
2508
3590
|
expr: e
|
|
2509
3591
|
};
|
|
2510
3592
|
return this.logicalConstraints.push(a), this.logicalConstrMapByName.set(i, a), this.recordModelMutation(), e;
|
|
2511
3593
|
}
|
|
2512
|
-
let n = typeof e == "string" ?
|
|
2513
|
-
n
|
|
3594
|
+
let n = typeof e == "string" ? Ee(e, (e) => this.getVarByName(e), t) : e;
|
|
3595
|
+
if (typeof n != "object" || !n || !("sense" in n) || !("lhs" in n) || !("rhs" in n)) throw Error("Invalid constraint passed to m.constraint(...): expected a linear Constraint (e.g. expr`${x} <= 10` or x.le(10)), a propositional BoolVar/BoolExpr (created with m.bool()), or an array of constraints.");
|
|
3596
|
+
n.ownerModel && n.ownerModel !== this && (j(n, this.name, (e) => this.varMapByName.get(e.name) === e, n.name), te(n, this));
|
|
2514
3597
|
let r = typeof t == "string" && t.trim().length > 0 ? t.trim() : n.hasExplicitName ? n.name.trim() : void 0;
|
|
2515
3598
|
if (r !== void 0) {
|
|
2516
3599
|
if (this.hasConstraintName(r)) throw Error(`Constraint with name '${r}' already exists in model`);
|
|
@@ -2518,54 +3601,55 @@ var ze = class {
|
|
|
2518
3601
|
}
|
|
2519
3602
|
let i = this.constrPrefixCounters.get("c"), a = r ?? this.getNextConstrName("c"), o;
|
|
2520
3603
|
try {
|
|
2521
|
-
j(n, this.name, (e) => this.varMapByName.get(e.name) === e, a), o =
|
|
3604
|
+
j(n, this.name, (e) => this.varMapByName.get(e.name) === e, a), o = te(n, this);
|
|
2522
3605
|
} catch (e) {
|
|
2523
3606
|
throw r === void 0 && (i === void 0 ? this.constrPrefixCounters.delete("c") : this.constrPrefixCounters.set("c", i)), e;
|
|
2524
3607
|
}
|
|
2525
|
-
let s = n.name, c = n.hasExplicitName,
|
|
3608
|
+
let s = n.name, c = n.hasExplicitName, l = n.ownerModel, d = o;
|
|
2526
3609
|
return this.batchUndoActions.push(() => {
|
|
2527
|
-
n.ownerModel =
|
|
3610
|
+
n.ownerModel = l, n._assignModelName(s, c), re(n, this, d);
|
|
2528
3611
|
}), this.batchDepth === 0 && (this.batchUndoActions = []), n._assignModelName(a, !0), n.ownerModel = this, this.constraints.push(n), this.constrMapByName.set(n.name, n), this.recordModelMutation(), n;
|
|
2529
3612
|
}
|
|
2530
3613
|
indicator(e, t, n = {}) {
|
|
2531
|
-
if (
|
|
2532
|
-
if (!(e
|
|
2533
|
-
if (
|
|
2534
|
-
if (
|
|
3614
|
+
if (e instanceof u) throw Error("Invalid binary variable passed to indicator(): received a propositional BoolVar/BoolExpr, but m.indicator() requires a 0-1 numeric binary Var created with m.binary(). For general boolean logic with m.bool(), use m.constraint(implies(flag, expr`${x} <= 10`)) with the Z3 solver.");
|
|
3615
|
+
if (!(e instanceof M)) throw Error("Invalid binary variable passed to indicator(). Expected a 0-1 binary Var instance created with m.binary() (or use implies(flag, ...) with m.bool() and the Z3 solver for general boolean logic).");
|
|
3616
|
+
if (!(e.type === "Binary" || e.type === "Integer" && e.lb === 0 && e.ub === 1)) throw Error(`Invalid variable "${e.name}" passed to indicator(): variable has type "${e.type}" with bounds [${e.lb}, ${e.ub}]. Indicator activation variable must be a Binary variable created with m.binary() (or Integer variable with bounds [0, 1]).`);
|
|
3617
|
+
if (t instanceof S || typeof t == "object" && t && "quadTerms" in t) throw Error("Quadratic expressions or constraints are not supported in indicator constraints (only linear Constraints with <=, >=, or == such as expr`${x} <= 10` are allowed).");
|
|
3618
|
+
if (typeof t != "object" || !t || !("sense" in t) || !("lhs" in t) || !("rhs" in t)) throw Error("Invalid constraint expression passed to indicator(). Expression must include a comparison operator (<=, >=, ==), e.g. m.indicator(b, expr`${x} <= 10`). For general boolean logic (such as BoolVar or implies/and/or/not), use m.constraint(implies(flag, ...)) with the Z3 solver.");
|
|
2535
3619
|
let r = t, i = n.activeValue === void 0 ? 1 : n.activeValue;
|
|
2536
3620
|
if (i !== 0 && i !== 1) throw Error(`Invalid activeValue: ${i}. Indicator activeValue must be 0 or 1.`);
|
|
2537
3621
|
if (this.varMapByName.get(e.name) !== e) throw Error(`Variable "${e.name}" passed to indicator() does not belong to model "${this.name}". All variables must belong to the model by object identity.`);
|
|
2538
|
-
let a = typeof n.name == "string" && n.name.trim().length > 0 ? n.name.trim() : void 0, o = this.constrPrefixCounters.get("c"), { lhs: s, sense: c, rhs: l } = r,
|
|
2539
|
-
if (a !== void 0)
|
|
2540
|
-
else if (r.hasExplicitName)
|
|
3622
|
+
let a = typeof n.name == "string" && n.name.trim().length > 0 ? n.name.trim() : void 0, o = this.constrPrefixCounters.get("c"), { lhs: s, sense: c, rhs: l } = r, d, f, p;
|
|
3623
|
+
if (a !== void 0) d = a, f = c === "==" ? `${d}_le` : d, p = c === "==" ? `${d}_ge` : d;
|
|
3624
|
+
else if (r.hasExplicitName) d = `ind_${e.name}_${r.name.trim()}`, f = c === "==" ? `${d}_le` : d, p = c === "==" ? `${d}_ge` : d;
|
|
2541
3625
|
else do {
|
|
2542
3626
|
let t = this.getNextConstrName("c");
|
|
2543
|
-
|
|
2544
|
-
} while ((c === "<=" || c === "==") && (this.hasConstraintName(
|
|
2545
|
-
let
|
|
3627
|
+
d = `ind_${e.name}_${t}`, f = c === "==" ? `${d}_le` : d, p = c === "==" ? `${d}_ge` : d;
|
|
3628
|
+
} while ((c === "<=" || c === "==") && (this.hasConstraintName(f) || this.hasBoolVarName(f)) || (c === ">=" || c === "==") && (this.hasConstraintName(p) || this.hasBoolVarName(p)));
|
|
3629
|
+
let m = [];
|
|
2546
3630
|
try {
|
|
2547
|
-
if ((c === "<=" || c === "==") && (this.hasConstraintName(
|
|
2548
|
-
if ((c === ">=" || c === "==") && (this.hasConstraintName(
|
|
2549
|
-
n.M !== void 0 &&
|
|
3631
|
+
if ((c === "<=" || c === "==") && (this.hasConstraintName(f) || this.hasBoolVarName(f))) throw Error(this.hasBoolVarName(f) ? `Constraint name '${f}' conflicts with an existing Boolean variable in model` : `Constraint with name '${f}' already exists in model`);
|
|
3632
|
+
if ((c === ">=" || c === "==") && (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`);
|
|
3633
|
+
n.M !== void 0 && Qe(n.M, d);
|
|
2550
3634
|
let t = (e) => this.varMapByName.get(e.name) === e;
|
|
2551
|
-
for (let [e] of s.terms) if (!t(e)) throw Error(`Variable "${e.name}" in constraint "${
|
|
3635
|
+
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.`);
|
|
2552
3636
|
if (c === "<=" || c === "==") {
|
|
2553
|
-
let t =
|
|
2554
|
-
|
|
3637
|
+
let t = Y(e, s, "<=", l, i, n.M === void 0 ? et(s, l, f) : n.M, f);
|
|
3638
|
+
m.push([new y(t.lhs, "<=", t.rhs, f), f]);
|
|
2555
3639
|
}
|
|
2556
3640
|
if (c === ">=" || c === "==") {
|
|
2557
|
-
let t =
|
|
2558
|
-
|
|
3641
|
+
let t = Y(e, s, ">=", l, i, n.M === void 0 ? tt(s, l, p) : n.M, p);
|
|
3642
|
+
m.push([new y(t.lhs, ">=", t.rhs, p), p]);
|
|
2559
3643
|
}
|
|
2560
|
-
for (let [e, n] of
|
|
3644
|
+
for (let [e, n] of m) j(e, this.name, t, n);
|
|
2561
3645
|
} catch (e) {
|
|
2562
3646
|
throw o === void 0 ? this.constrPrefixCounters.delete("c") : this.constrPrefixCounters.set("c", o), e;
|
|
2563
3647
|
}
|
|
2564
|
-
return this.runTransactionalBatch(() =>
|
|
3648
|
+
return this.runTransactionalBatch(() => m.map(([e, t]) => this.addConstraint(e, t)));
|
|
2565
3649
|
}
|
|
2566
3650
|
toLpString() {
|
|
2567
3651
|
this.validateIntegrity();
|
|
2568
|
-
let { lpString: e } =
|
|
3652
|
+
let { lpString: e } = je({
|
|
2569
3653
|
name: this.name,
|
|
2570
3654
|
sense: this.sense,
|
|
2571
3655
|
objective: this.objectiveExpr,
|
|
@@ -2575,7 +3659,7 @@ var ze = class {
|
|
|
2575
3659
|
return e;
|
|
2576
3660
|
}
|
|
2577
3661
|
validateIntegrity() {
|
|
2578
|
-
|
|
3662
|
+
ce(this);
|
|
2579
3663
|
}
|
|
2580
3664
|
ensureExecutionValid(e, t, n) {
|
|
2581
3665
|
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.`);
|
|
@@ -2595,6 +3679,9 @@ var ze = class {
|
|
|
2595
3679
|
let t = e.status, n = e.terminationStatus ?? t, r = e.values || {}, i = e.boolValues || {};
|
|
2596
3680
|
return t !== "Infeasible" && t !== "Unsat" && t !== "Unbounded" && t !== "Error" && t !== "NotSolved" && n !== "Infeasible" && n !== "Unsat" && n !== "Unbounded" && n !== "InfeasibleOrUnbounded" && n !== "Error" && n !== "NotSolved" && (t === "Optimal" || t === "Feasible" || t === "Sat" || n === "Optimal" || n === "Feasible" || n === "Sat" || typeof e.objectiveValue == "number" && Number.isFinite(e.objectiveValue) || Object.values(r).some((e) => typeof e == "number" && Number.isFinite(e) || typeof e == "boolean") || Object.values(i).some((e) => typeof e == "boolean"));
|
|
2597
3681
|
}
|
|
3682
|
+
normalizePrimalValue(e, t, n, r) {
|
|
3683
|
+
return (r.relax ?? n.options?.relax) !== !0 && (e.type === "Integer" || e.type === "Binary") && Math.abs(t - Math.round(t)) <= 1e-5 ? Math.round(t) + 0 : t;
|
|
3684
|
+
}
|
|
2598
3685
|
resolveSolverAndOptions(e, t) {
|
|
2599
3686
|
if (e && typeof e == "object" && "solve" in e && typeof e.solve == "function") {
|
|
2600
3687
|
let { solver: n, ...r } = t || {};
|
|
@@ -2613,27 +3700,44 @@ var ze = class {
|
|
|
2613
3700
|
if (typeof e == "string") {
|
|
2614
3701
|
let { solver: n, ...r } = t || {};
|
|
2615
3702
|
return {
|
|
2616
|
-
activeSolver:
|
|
3703
|
+
activeSolver: G(e, r),
|
|
2617
3704
|
activeOptions: r
|
|
2618
3705
|
};
|
|
2619
3706
|
}
|
|
2620
3707
|
let { solver: n, ...r } = e || {};
|
|
2621
3708
|
return n ? {
|
|
2622
|
-
activeSolver:
|
|
3709
|
+
activeSolver: G(n, r),
|
|
2623
3710
|
activeOptions: r
|
|
2624
3711
|
} : {
|
|
2625
|
-
activeSolver: this.solver ||
|
|
3712
|
+
activeSolver: this.solver || G(),
|
|
2626
3713
|
activeOptions: r
|
|
2627
3714
|
};
|
|
2628
3715
|
}
|
|
3716
|
+
async relax(e, t) {
|
|
3717
|
+
let n = typeof e == "object" && !!e && !("solve" in e), r = n ? {
|
|
3718
|
+
...e,
|
|
3719
|
+
relax: !0
|
|
3720
|
+
} : {
|
|
3721
|
+
...t || {},
|
|
3722
|
+
relax: !0
|
|
3723
|
+
}, i = n ? void 0 : e;
|
|
3724
|
+
return i ? this.solve(i, r) : this.solve(r);
|
|
3725
|
+
}
|
|
2629
3726
|
async solve(e, t) {
|
|
2630
3727
|
let n = ++this.activeOperationId, r = this.modelRevision;
|
|
2631
3728
|
this.clearSolutionFields(), this.validateIntegrity();
|
|
2632
3729
|
let { activeSolver: i, activeOptions: a } = this.resolveSolverAndOptions(e, t);
|
|
2633
|
-
if (this._objectiveExpr instanceof
|
|
2634
|
-
|
|
2635
|
-
if (this.
|
|
2636
|
-
|
|
3730
|
+
if (this._objectiveExpr instanceof S && 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.`);
|
|
3731
|
+
let o, s = null;
|
|
3732
|
+
if (this.logicalConstraints.length > 0 && i.capabilities?.supportsSMT !== !0 ? (s = nt(this.variables, this.boolVars, this.constraints, this.logicalConstraints), o = {
|
|
3733
|
+
name: this.name,
|
|
3734
|
+
sense: this.sense,
|
|
3735
|
+
objective: this._objectiveExpr,
|
|
3736
|
+
constraints: s.constraints,
|
|
3737
|
+
variables: s.variables,
|
|
3738
|
+
logicalConstraints: [],
|
|
3739
|
+
boolVars: []
|
|
3740
|
+
}) : o = {
|
|
2637
3741
|
name: this.name,
|
|
2638
3742
|
sense: this.sense,
|
|
2639
3743
|
objective: this._objectiveExpr,
|
|
@@ -2641,53 +3745,68 @@ var ze = class {
|
|
|
2641
3745
|
variables: this.variables,
|
|
2642
3746
|
logicalConstraints: this.logicalConstraints,
|
|
2643
3747
|
boolVars: this.boolVars
|
|
2644
|
-
},
|
|
3748
|
+
}, 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.`);
|
|
3749
|
+
let c = this.wrapSolveOptions(a, r, n), l;
|
|
2645
3750
|
try {
|
|
2646
|
-
|
|
3751
|
+
l = await i.solve(o, c);
|
|
2647
3752
|
} catch (e) {
|
|
2648
3753
|
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
2649
3754
|
}
|
|
2650
|
-
this.ensureExecutionValid(r, n, "solve"), this.runTime =
|
|
2651
|
-
let
|
|
2652
|
-
this.hasPrimalSolution =
|
|
2653
|
-
let
|
|
2654
|
-
this.relGap =
|
|
2655
|
-
let
|
|
3755
|
+
this.ensureExecutionValid(r, n, "solve"), this.runTime = l.runTime ?? 0, this.status = l.status, this.terminationStatus = l.terminationStatus ?? l.status;
|
|
3756
|
+
let u = this.hasPrimalFromResult(l);
|
|
3757
|
+
this.hasPrimalSolution = u, this.objectiveValue = u && typeof l.objectiveValue == "number" && Number.isFinite(l.objectiveValue) ? l.objectiveValue : null, this.objectiveBound = typeof l.objectiveBound == "number" && Number.isFinite(l.objectiveBound) ? l.objectiveBound : void 0;
|
|
3758
|
+
let d = typeof l.relGap == "number" && Number.isFinite(l.relGap) ? l.relGap : typeof l.mipGap == "number" && Number.isFinite(l.mipGap) ? l.mipGap : void 0;
|
|
3759
|
+
this.relGap = d, this.mipGap = d, this.absGap = typeof l.absGap == "number" && Number.isFinite(l.absGap) ? l.absGap : this.objectiveValue !== null && this.objectiveBound !== void 0 ? Math.abs(this.objectiveValue - this.objectiveBound) : void 0;
|
|
3760
|
+
let f = (e, t, n) => {
|
|
2656
3761
|
Object.defineProperty(e, t, {
|
|
2657
3762
|
value: n,
|
|
2658
3763
|
enumerable: !0,
|
|
2659
3764
|
writable: !0,
|
|
2660
3765
|
configurable: !0
|
|
2661
3766
|
});
|
|
2662
|
-
},
|
|
2663
|
-
if (this.values.clear(),
|
|
2664
|
-
for (let [e, t] of Object.entries(
|
|
3767
|
+
}, p = {}, m = {}, h = {}, g = {};
|
|
3768
|
+
if (this.values.clear(), u && l.values) {
|
|
3769
|
+
for (let [e, t] of Object.entries(l.values)) if (typeof t == "number" && Number.isFinite(t)) {
|
|
2665
3770
|
let n = this.getVarByName(e), r = this.getBoolVarByName(e);
|
|
2666
|
-
|
|
3771
|
+
if (n) {
|
|
3772
|
+
let e = this.normalizePrimalValue(n, t, i, a);
|
|
3773
|
+
n.value = e, f(p, n.name, e), this.values.set(n.name, e);
|
|
3774
|
+
}
|
|
3775
|
+
r && (r.value = !!t, this.values.set(r.name, t)), !n && !r && this.values.set(e, t);
|
|
2667
3776
|
} else if (typeof t == "boolean") {
|
|
2668
3777
|
let n = t, r = this.getBoolVarByName(e);
|
|
2669
|
-
r ? (r.value = n,
|
|
3778
|
+
r ? (r.value = n, f(p, r.name, +!!n), this.values.set(r.name, n)) : this.values.set(e, n);
|
|
3779
|
+
}
|
|
3780
|
+
if (s) for (let e of this.boolVars) {
|
|
3781
|
+
let t = s.boolVarToBinary.get(e);
|
|
3782
|
+
if (t && l.values) {
|
|
3783
|
+
let n = l.values[t.name];
|
|
3784
|
+
if (typeof n == "number" && Number.isFinite(n)) {
|
|
3785
|
+
let t = Math.round(n) === 1;
|
|
3786
|
+
e.value = t, f(p, e.name, +!!t), this.values.set(e.name, t);
|
|
3787
|
+
}
|
|
3788
|
+
}
|
|
2670
3789
|
}
|
|
2671
3790
|
}
|
|
2672
|
-
if (
|
|
3791
|
+
if (u && l.boolValues) for (let [e, t] of Object.entries(l.boolValues)) {
|
|
2673
3792
|
if (typeof t != "boolean") continue;
|
|
2674
3793
|
let n = this.getBoolVarByName(e);
|
|
2675
3794
|
n ? (n.value = t, this.values.has(n.name) || this.values.set(n.name, t)) : this.values.has(e) || this.values.set(e, t);
|
|
2676
3795
|
}
|
|
2677
|
-
if (
|
|
3796
|
+
if (u && l.reducedCosts) for (let [e, t] of Object.entries(l.reducedCosts)) {
|
|
2678
3797
|
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
2679
3798
|
let n = this.getVarByName(e);
|
|
2680
|
-
n && (n.reducedCost = t,
|
|
3799
|
+
n && (n.reducedCost = t, f(h, n.name, t));
|
|
2681
3800
|
}
|
|
2682
|
-
if (
|
|
3801
|
+
if (l.duals) for (let [e, t] of Object.entries(l.duals)) {
|
|
2683
3802
|
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
2684
3803
|
let n = this.getConstraintByName(e);
|
|
2685
|
-
n && (n.dual = t,
|
|
3804
|
+
n && (n.dual = t, f(m, n.name, t));
|
|
2686
3805
|
}
|
|
2687
|
-
if (
|
|
3806
|
+
if (l.slacks) for (let [e, t] of Object.entries(l.slacks)) {
|
|
2688
3807
|
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
2689
3808
|
let n = this.getConstraintByName(e);
|
|
2690
|
-
n && (n.slack = t,
|
|
3809
|
+
n && (n.slack = t, f(g, n.name, t));
|
|
2691
3810
|
}
|
|
2692
3811
|
return this.solution = {
|
|
2693
3812
|
status: this.status,
|
|
@@ -2700,19 +3819,18 @@ var ze = class {
|
|
|
2700
3819
|
mipGap: this.mipGap
|
|
2701
3820
|
},
|
|
2702
3821
|
...this.absGap === void 0 ? {} : { absGap: this.absGap },
|
|
2703
|
-
values:
|
|
2704
|
-
duals:
|
|
2705
|
-
reducedCosts:
|
|
2706
|
-
slacks:
|
|
3822
|
+
values: p,
|
|
3823
|
+
duals: m,
|
|
3824
|
+
reducedCosts: h,
|
|
3825
|
+
slacks: g,
|
|
2707
3826
|
runTime: this.runTime,
|
|
2708
|
-
raw:
|
|
3827
|
+
raw: l.raw
|
|
2709
3828
|
}, this.hasSolutionState = !0, this.status;
|
|
2710
3829
|
}
|
|
2711
3830
|
async check(e, t) {
|
|
2712
3831
|
let n = ++this.activeOperationId, r = this.modelRevision;
|
|
2713
3832
|
this.clearSolutionFields(), this.validateIntegrity();
|
|
2714
3833
|
let { activeSolver: i, activeOptions: a } = this.resolveSolverAndOptions(e, t);
|
|
2715
|
-
if (this.logicalConstraints.length > 0 && i.capabilities?.supportsSMT !== !0) throw Error(`Solver "${i.name}" does not support SMT / logical constraints (or, implies, not, xor). Please use an SMT-capable solver such as Z3.`);
|
|
2716
3834
|
if (this.variables.some((e) => e.initialValue !== void 0) && i.capabilities?.supportsWarmStart !== !0) throw Error(`Solver "${i.name}" does not support primal initial values (initialValue). Please use a solver with warm-start support such as HiGHS.`);
|
|
2717
3835
|
let o = this.wrapSolveOptions(a, r, n), s = (e, t, n) => {
|
|
2718
3836
|
Object.defineProperty(e, t, {
|
|
@@ -2735,13 +3853,17 @@ var ze = class {
|
|
|
2735
3853
|
} catch (e) {
|
|
2736
3854
|
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
2737
3855
|
}
|
|
2738
|
-
this.ensureExecutionValid(r, n, "check"), this.status = e.status, this.terminationStatus = a.signal?.aborted ? "Interrupted" : e.status, this.hasPrimalSolution = e.status === "Sat", this.runTime = e.runTime ?? 0, this.unsatCore = e.unsatCore === void 0 ? void 0 : Object.freeze([...e.unsatCore]);
|
|
3856
|
+
this.ensureExecutionValid(r, n, "check"), this.status = e.status, this.terminationStatus = a.signal?.aborted ? "Interrupted" : e.status, this.hasPrimalSolution = e.status === "Sat", this.runTime = e.runTime ?? 0, this.unsatCore = e.unsatCore === void 0 ? void 0 : Object.freeze([...e.unsatCore]), this.conflicts = e.conflicts === void 0 ? this.unsatCore : Object.freeze([...e.conflicts]);
|
|
2739
3857
|
let t = {};
|
|
2740
3858
|
if (e.values && e.status === "Sat") {
|
|
2741
3859
|
for (let [n, r] of Object.entries(e.values)) if (typeof r == "number") {
|
|
2742
3860
|
if (!Number.isFinite(r)) continue;
|
|
2743
|
-
let e = this.getVarByName(n),
|
|
2744
|
-
|
|
3861
|
+
let e = this.getVarByName(n), o = this.getBoolVarByName(n);
|
|
3862
|
+
if (e) {
|
|
3863
|
+
let n = this.normalizePrimalValue(e, r, i, a);
|
|
3864
|
+
e.value = n, this.values.set(e.name, n), s(t, e.name, n);
|
|
3865
|
+
}
|
|
3866
|
+
o && (o.value = !!r, this.values.set(o.name, o.value), s(t, o.name, o.value)), !e && !o && (this.values.set(n, r), s(t, n, r));
|
|
2745
3867
|
} else if (typeof r == "boolean") {
|
|
2746
3868
|
let e = this.getBoolVarByName(n);
|
|
2747
3869
|
e ? (e.value = r, this.values.set(e.name, r), s(t, e.name, r)) : (this.values.set(n, r), s(t, n, r));
|
|
@@ -2751,81 +3873,127 @@ var ze = class {
|
|
|
2751
3873
|
status: e.status,
|
|
2752
3874
|
values: t,
|
|
2753
3875
|
unsatCore: this.unsatCore,
|
|
2754
|
-
conflicts: this.
|
|
3876
|
+
conflicts: this.conflicts,
|
|
2755
3877
|
runTime: this.runTime
|
|
2756
3878
|
};
|
|
2757
3879
|
}
|
|
2758
|
-
let l = {
|
|
2759
|
-
|
|
3880
|
+
let l = this.logicalConstraints.length > 0 || this.boolVars.length > 0 ? nt(this.variables, this.boolVars, this.constraints, this.logicalConstraints) : {
|
|
3881
|
+
variables: [...this.variables],
|
|
3882
|
+
constraints: [...this.constraints],
|
|
3883
|
+
boolVarToBinary: /* @__PURE__ */ new Map(),
|
|
3884
|
+
constraintToOriginalName: new Map(this.constraints.map((e) => [e, e.name]))
|
|
3885
|
+
}, u = [], d = [], f = [], p = /* @__PURE__ */ new Map(), m = 0;
|
|
3886
|
+
for (let e of l.constraints) {
|
|
3887
|
+
let t = l.constraintToOriginalName.get(e) ?? e.name, { lhs: n, sense: r, rhs: i } = e;
|
|
3888
|
+
if (r === "<=") {
|
|
3889
|
+
let r = new M({
|
|
3890
|
+
name: `__slack_${++m}`,
|
|
3891
|
+
type: "Continuous",
|
|
3892
|
+
lb: 0,
|
|
3893
|
+
ub: Infinity
|
|
3894
|
+
});
|
|
3895
|
+
d.push(r), f.push([r, 1]), p.set(r, t);
|
|
3896
|
+
let a = n.clone().add(new C(/* @__PURE__ */ new Map([[r, -1]]), 0));
|
|
3897
|
+
u.push(new y(a, "<=", i, `${e.name}_slack`));
|
|
3898
|
+
} else if (r === ">=") {
|
|
3899
|
+
let r = new M({
|
|
3900
|
+
name: `__slack_${++m}`,
|
|
3901
|
+
type: "Continuous",
|
|
3902
|
+
lb: 0,
|
|
3903
|
+
ub: Infinity
|
|
3904
|
+
});
|
|
3905
|
+
d.push(r), f.push([r, 1]), p.set(r, t);
|
|
3906
|
+
let a = n.clone().add(new C(/* @__PURE__ */ new Map([[r, 1]]), 0));
|
|
3907
|
+
u.push(new y(a, ">=", i, `${e.name}_slack`));
|
|
3908
|
+
} else {
|
|
3909
|
+
let r = new M({
|
|
3910
|
+
name: `__slack_${++m}_p`,
|
|
3911
|
+
type: "Continuous",
|
|
3912
|
+
lb: 0,
|
|
3913
|
+
ub: Infinity
|
|
3914
|
+
}), a = new M({
|
|
3915
|
+
name: `__slack_${++m}_n`,
|
|
3916
|
+
type: "Continuous",
|
|
3917
|
+
lb: 0,
|
|
3918
|
+
ub: Infinity
|
|
3919
|
+
});
|
|
3920
|
+
d.push(r, a), f.push([r, 1], [a, 1]), p.set(r, t), p.set(a, t);
|
|
3921
|
+
let o = n.clone().add(new C(/* @__PURE__ */ new Map([[r, -1], [a, 1]]), 0));
|
|
3922
|
+
u.push(new y(o, "==", i, `${e.name}_slack`));
|
|
3923
|
+
}
|
|
3924
|
+
}
|
|
3925
|
+
let h = {
|
|
3926
|
+
name: `${this.name}_elastic_check`,
|
|
2760
3927
|
sense: "Minimize",
|
|
2761
|
-
objective: new
|
|
2762
|
-
constraints:
|
|
2763
|
-
variables:
|
|
2764
|
-
|
|
2765
|
-
boolVars: this.boolVars
|
|
2766
|
-
}, u;
|
|
3928
|
+
objective: new C(new Map(f), 0),
|
|
3929
|
+
constraints: u,
|
|
3930
|
+
variables: [...l.variables, ...d]
|
|
3931
|
+
}, g;
|
|
2767
3932
|
try {
|
|
2768
|
-
|
|
3933
|
+
g = await i.solve(h, o);
|
|
2769
3934
|
} catch (e) {
|
|
2770
3935
|
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
2771
3936
|
}
|
|
2772
|
-
this.ensureExecutionValid(r, n, "check"), this.runTime =
|
|
2773
|
-
let
|
|
2774
|
-
this.status =
|
|
2775
|
-
let
|
|
2776
|
-
if (
|
|
2777
|
-
for (let
|
|
2778
|
-
let
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
3937
|
+
this.ensureExecutionValid(r, n, "check"), this.runTime = g.runTime ?? 0;
|
|
3938
|
+
let _ = g.status, v = g.terminationStatus ?? _, b = this.hasPrimalFromResult(g), x = typeof g.objectiveValue == "number" && Number.isFinite(g.objectiveValue) ? g.objectiveValue : Infinity, S = (_ === "Optimal" || _ === "Feasible" || b) && x <= 1e-5, w = typeof g.objectiveBound == "number" && Number.isFinite(g.objectiveBound) && g.objectiveBound > 1e-5, T = !S && (_ === "Infeasible" || _ === "Optimal" && x > 1e-5 || w), E = S ? "Sat" : T ? "Unsat" : "Unknown";
|
|
3939
|
+
this.status = E, this.terminationStatus = a.signal?.aborted || v === "Interrupted" ? "Interrupted" : v === "Optimal" || v === "Feasible" || v === "Infeasible" ? E : v, this.hasPrimalSolution = S, 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();
|
|
3940
|
+
let D = {};
|
|
3941
|
+
if (S && g.values) {
|
|
3942
|
+
for (let e of this.variables) {
|
|
3943
|
+
let t = g.values[e.name];
|
|
3944
|
+
if (typeof t == "number" && Number.isFinite(t)) {
|
|
3945
|
+
let n = this.normalizePrimalValue(e, t, i, a);
|
|
3946
|
+
e.value = n, this.values.set(e.name, n), s(D, e.name, n);
|
|
3947
|
+
}
|
|
3948
|
+
}
|
|
3949
|
+
for (let e of this.boolVars) {
|
|
3950
|
+
let t = l.boolVarToBinary.get(e), n = t ? g.values[t.name] : g.values[e.name];
|
|
3951
|
+
if (typeof n == "number" && Number.isFinite(n)) {
|
|
3952
|
+
let t = Math.round(n) === 1;
|
|
3953
|
+
e.value = t, this.values.set(e.name, t), s(D, e.name, t);
|
|
3954
|
+
}
|
|
2783
3955
|
}
|
|
2784
3956
|
}
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
let n =
|
|
2788
|
-
n
|
|
2789
|
-
}
|
|
2790
|
-
if (u.slacks) for (let [e, t] of Object.entries(u.slacks)) {
|
|
2791
|
-
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
2792
|
-
let n = this.getConstraintByName(e);
|
|
2793
|
-
n && (n.slack = t);
|
|
3957
|
+
let O = /* @__PURE__ */ new Set();
|
|
3958
|
+
if (T && g.values) for (let [e, t] of p.entries()) {
|
|
3959
|
+
let n = g.values[e.name];
|
|
3960
|
+
typeof n == "number" && n > 1e-5 && O.add(t);
|
|
2794
3961
|
}
|
|
2795
|
-
return this.hasSolutionState = !0, {
|
|
2796
|
-
status:
|
|
2797
|
-
values:
|
|
3962
|
+
return this.conflicts = T ? Object.freeze(Array.from(O)) : void 0, this.unsatCore = void 0, this.hasSolutionState = !0, {
|
|
3963
|
+
status: E,
|
|
3964
|
+
values: D,
|
|
3965
|
+
conflicts: this.conflicts,
|
|
3966
|
+
unsatCore: this.unsatCore,
|
|
2798
3967
|
runTime: this.runTime
|
|
2799
3968
|
};
|
|
2800
3969
|
}
|
|
2801
3970
|
validateSolution(e = {}) {
|
|
2802
|
-
return
|
|
3971
|
+
return Ze(this, e);
|
|
3972
|
+
}
|
|
3973
|
+
link(e) {
|
|
3974
|
+
if (e instanceof S || typeof e == "object" && e && "quadTerms" in e) throw Error("Linking constraint cannot be a quadratic expression.");
|
|
3975
|
+
if (!(e instanceof y) && (typeof e != "object" || !e || !("sense" in e) || !("lhs" in e) || !("rhs" in e))) throw Error("Linking constraint must contain a comparison operator (<=, >=, ==). Use expr`... <= ...` or .le(), .ge(), .eq().");
|
|
3976
|
+
this._linkingConstraints ||= [];
|
|
3977
|
+
let t = e;
|
|
3978
|
+
return this._linkingConstraints.push(t), t;
|
|
3979
|
+
}
|
|
3980
|
+
get linkingConstraints() {
|
|
3981
|
+
return this._linkingConstraints ?? [];
|
|
3982
|
+
}
|
|
3983
|
+
async solveBenders(e) {
|
|
3984
|
+
let t = await ut({
|
|
3985
|
+
master: this,
|
|
3986
|
+
...e
|
|
3987
|
+
});
|
|
3988
|
+
return this.decomposition = t, t;
|
|
2803
3989
|
}
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
if (typeof n == "string" && /(<=|>=|==|=<|=>|=)/.test(n)) throw Error(`Cannot use a comparison constraint as an objective in ${t}(). Use model.constraint(expr\`... <= ...\`) for constraints, or supply an unconstrained arithmetic expression to ${t}().`);
|
|
2811
|
-
if (typeof n == "number") {
|
|
2812
|
-
if (!Number.isFinite(n)) throw Error(`Invalid non-finite objective constant "${n}" passed to ${t}().`);
|
|
2813
|
-
return n;
|
|
3990
|
+
async solveColumnGeneration(e) {
|
|
3991
|
+
let t = await it({
|
|
3992
|
+
master: this,
|
|
3993
|
+
...e
|
|
3994
|
+
});
|
|
3995
|
+
return this.decomposition = t, t;
|
|
2814
3996
|
}
|
|
2815
|
-
|
|
2816
|
-
throw Error(`Invalid expression passed to ${t}(): expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.`);
|
|
2817
|
-
}
|
|
2818
|
-
function Ve(e) {
|
|
2819
|
-
return {
|
|
2820
|
-
expr: Be(e, "maximize"),
|
|
2821
|
-
sense: "Maximize"
|
|
2822
|
-
};
|
|
2823
|
-
}
|
|
2824
|
-
function He(e) {
|
|
2825
|
-
return {
|
|
2826
|
-
expr: Be(e, "minimize"),
|
|
2827
|
-
sense: "Minimize"
|
|
2828
|
-
};
|
|
2829
|
-
}
|
|
3997
|
+
};
|
|
2830
3998
|
//#endregion
|
|
2831
|
-
export {
|
|
3999
|
+
export { u as BoolExpr, f as BoolOp, d as BoolVar, y as Constraint, Ke as HiGHS, r as Highs, Ge as HighsSolver, C as LinExpr, Je as MockSolver, ft as Model, S as QuadExpr, M as Var, p as and, Y as buildIndicatorLinearization, Ae as buildLpSymbolMaps, tt as deriveBigMForGe, et as deriveBigMForLe, T as dot, Oe as expr, je as generateLpString, o as getHighs, n as getHighsWasmUrl, G as getSolver, g as implies, ke as isLpExportResult, nt as linearizeModelForMip, K as listAvailableSolvers, ot as maximize, st as minimize, s as normalizeSense, h as not, m as or, Ee as parseConstraint, Ce as parseExpr, Pe as registerSolver, H as sanitizeIdentifier, Fe as setDefaultSolver, t as setHighsWasmUrl, ut as solveBenders, it as solveColumnGeneration, e as solveLpWithHighs, w as sum, ce as validateModelIntegrity, Ze as validateModelSolution, Qe as validateUserBigM, _ as xor };
|