@ohtaman/washi 0.3.0 → 0.4.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 +11 -11
- package/README.md +11 -11
- package/README.zh-CN.md +11 -11
- package/dist/browser/washi.js +311 -208
- package/dist/browser/washi.min.js +4 -4
- package/dist/lib/washi.js +219 -116
- package/dist/types/modeler/expression.d.ts +7 -2
- package/dist/types/modeler/expression.d.ts.map +1 -1
- package/dist/types/modeler/model.d.ts +47 -43
- package/dist/types/modeler/model.d.ts.map +1 -1
- package/dist/types/modeler/parser.d.ts +9 -8
- package/dist/types/modeler/parser.d.ts.map +1 -1
- package/dist/types/modeler/quad-expr.d.ts +3 -1
- package/dist/types/modeler/quad-expr.d.ts.map +1 -1
- package/dist/types/modeler/types.d.ts +1 -1
- package/dist/types/modeler/types.d.ts.map +1 -1
- package/dist/types/modeler/variable.d.ts +6 -0
- package/dist/types/modeler/variable.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/browser/washi.js
CHANGED
|
@@ -61,7 +61,7 @@ function v(...e) {
|
|
|
61
61
|
}
|
|
62
62
|
//#endregion
|
|
63
63
|
//#region src/modeler/constraint.ts
|
|
64
|
-
var
|
|
64
|
+
var y = 0, b = class {
|
|
65
65
|
id;
|
|
66
66
|
lhs;
|
|
67
67
|
sense;
|
|
@@ -70,7 +70,7 @@ var ee = 0, y = class {
|
|
|
70
70
|
slack = null;
|
|
71
71
|
dual = null;
|
|
72
72
|
constructor(e, t, n, r) {
|
|
73
|
-
this.id = ++
|
|
73
|
+
this.id = ++y, this.lhs = e, this.sense = t, this.rhs = n, this.name = r || `c_${this.id}`;
|
|
74
74
|
}
|
|
75
75
|
and(e) {
|
|
76
76
|
return new p("and", [this, e]);
|
|
@@ -94,11 +94,11 @@ var ee = 0, y = class {
|
|
|
94
94
|
};
|
|
95
95
|
//#endregion
|
|
96
96
|
//#region src/modeler/quad-expr.ts
|
|
97
|
-
function
|
|
97
|
+
function x(e, t) {
|
|
98
98
|
let n = e.id, r = t.id;
|
|
99
99
|
return n <= r ? `${n}:${r}` : `${r}:${n}`;
|
|
100
100
|
}
|
|
101
|
-
var
|
|
101
|
+
var S = class e {
|
|
102
102
|
linearTerms;
|
|
103
103
|
quadTerms;
|
|
104
104
|
constant;
|
|
@@ -111,7 +111,7 @@ var x = class e {
|
|
|
111
111
|
return new e(this.linearTerms, this.quadTerms, this.constant);
|
|
112
112
|
}
|
|
113
113
|
getQuadCoeff(e, t) {
|
|
114
|
-
let n =
|
|
114
|
+
let n = x(e, t), r = this.quadTerms.get(n);
|
|
115
115
|
return r ? r.coeff : 0;
|
|
116
116
|
}
|
|
117
117
|
add(t) {
|
|
@@ -146,20 +146,45 @@ var x = class e {
|
|
|
146
146
|
return typeof t == "number" ? this.add(-t) : t instanceof e ? this.add(t.neg()) : ("terms" in t && t.terms instanceof Map, this.add(t.mul(-1)));
|
|
147
147
|
}
|
|
148
148
|
mul(t) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
let
|
|
152
|
-
|
|
149
|
+
if (typeof t == "number") {
|
|
150
|
+
let n = new e(/* @__PURE__ */ new Map(), /* @__PURE__ */ new Map(), this.constant * t);
|
|
151
|
+
for (let [e, r] of this.linearTerms) {
|
|
152
|
+
let i = r * t;
|
|
153
|
+
Math.abs(i) >= 1e-12 && n.linearTerms.set(e, i);
|
|
154
|
+
}
|
|
155
|
+
for (let [e, r] of this.quadTerms) {
|
|
156
|
+
let i = r.coeff * t;
|
|
157
|
+
Math.abs(i) >= 1e-12 && n.quadTerms.set(e, {
|
|
158
|
+
var1: r.var1,
|
|
159
|
+
var2: r.var2,
|
|
160
|
+
coeff: i
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
return n;
|
|
153
164
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
});
|
|
165
|
+
if ("id" in t && "name" in t && !("terms" in t) && !("quadTerms" in t)) {
|
|
166
|
+
if (this.quadTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
167
|
+
let n = new e();
|
|
168
|
+
Math.abs(this.constant) >= 1e-12 && n.linearTerms.set(t, this.constant);
|
|
169
|
+
for (let [r, i] of this.linearTerms) n = n.add(e.fromProduct(r, t, i));
|
|
170
|
+
return n;
|
|
161
171
|
}
|
|
162
|
-
|
|
172
|
+
let n = t, r = "quadTerms" in n ? n.quadTerms.size : 0, i = "quadTerms" in n ? n.linearTerms : n.terms;
|
|
173
|
+
if (this.quadTerms.size > 0 && (r > 0 || i.size > 0) || r > 0 && this.linearTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
174
|
+
if (r === 0 && i.size === 0) return this.mul(n.constant);
|
|
175
|
+
if (this.quadTerms.size === 0 && this.linearTerms.size === 0) {
|
|
176
|
+
let t = n.mul(this.constant);
|
|
177
|
+
if (t instanceof e) return t;
|
|
178
|
+
let r = new e();
|
|
179
|
+
r.constant = t.constant;
|
|
180
|
+
for (let [e, n] of t.terms) r.linearTerms.set(e, n);
|
|
181
|
+
return r;
|
|
182
|
+
}
|
|
183
|
+
let a = new e();
|
|
184
|
+
if (a.constant = this.constant * n.constant, Math.abs(n.constant) >= 1e-12) for (let [e, t] of this.linearTerms) a.linearTerms.set(e, (a.linearTerms.get(e) || 0) + t * n.constant);
|
|
185
|
+
if (Math.abs(this.constant) >= 1e-12) for (let [e, t] of i) a.linearTerms.set(e, (a.linearTerms.get(e) || 0) + t * this.constant);
|
|
186
|
+
for (let [t, n] of this.linearTerms) for (let [r, o] of i) a = a.add(e.fromProduct(t, r, n * o));
|
|
187
|
+
return a;
|
|
163
188
|
}
|
|
164
189
|
div(e) {
|
|
165
190
|
if (Math.abs(e) < 1e-12) throw Error("Division by zero in QuadExpr.div()");
|
|
@@ -183,15 +208,31 @@ var x = class e {
|
|
|
183
208
|
getValue() {
|
|
184
209
|
return this.value;
|
|
185
210
|
}
|
|
211
|
+
toString() {
|
|
212
|
+
let e = [], t = !0;
|
|
213
|
+
for (let n of this.quadTerms.values()) {
|
|
214
|
+
let r = n.coeff, i = r >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(r), o = a === 1 ? "" : `${a} `;
|
|
215
|
+
n.var1 === n.var2 ? e.push(`${i}${o}${n.var1.name}^2`) : e.push(`${i}${o}${n.var1.name} * ${n.var2.name}`), t = !1;
|
|
216
|
+
}
|
|
217
|
+
for (let [n, r] of this.linearTerms) {
|
|
218
|
+
let i = r >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(r), o = a === 1 ? "" : `${a} `;
|
|
219
|
+
e.push(`${i}${o}${n.name}`), t = !1;
|
|
220
|
+
}
|
|
221
|
+
if (this.constant !== 0 || e.length === 0) {
|
|
222
|
+
let n = this.constant >= 0 ? t ? "" : "+ " : "- ";
|
|
223
|
+
e.push(`${n}${Math.abs(this.constant)}`);
|
|
224
|
+
}
|
|
225
|
+
return e.join(" ") || "0";
|
|
226
|
+
}
|
|
186
227
|
static fromProduct(t, n, r = 1) {
|
|
187
|
-
let i = new e(), a =
|
|
228
|
+
let i = new e(), a = x(t, n);
|
|
188
229
|
return i.quadTerms.set(a, {
|
|
189
230
|
var1: t.id <= n.id ? t : n,
|
|
190
231
|
var2: t.id <= n.id ? n : t,
|
|
191
232
|
coeff: r
|
|
192
233
|
}), i;
|
|
193
234
|
}
|
|
194
|
-
},
|
|
235
|
+
}, C = class e {
|
|
195
236
|
terms;
|
|
196
237
|
constant;
|
|
197
238
|
constructor(e = /* @__PURE__ */ new Map(), t = 0) {
|
|
@@ -201,7 +242,7 @@ var x = class e {
|
|
|
201
242
|
return new e(this.terms, this.constant);
|
|
202
243
|
}
|
|
203
244
|
add(e) {
|
|
204
|
-
if (e instanceof
|
|
245
|
+
if (e instanceof S) return e.add(this);
|
|
205
246
|
let t = this.clone();
|
|
206
247
|
if (typeof e == "number") t.constant += e;
|
|
207
248
|
else if ("terms" in e) {
|
|
@@ -217,7 +258,7 @@ var x = class e {
|
|
|
217
258
|
return t;
|
|
218
259
|
}
|
|
219
260
|
sub(e) {
|
|
220
|
-
return e instanceof
|
|
261
|
+
return e instanceof S ? e.neg().add(this) : typeof e == "number" ? this.add(-e) : ("terms" in e, this.add(e.mul(-1)));
|
|
221
262
|
}
|
|
222
263
|
mul(t) {
|
|
223
264
|
if (typeof t == "number") {
|
|
@@ -228,9 +269,27 @@ var x = class e {
|
|
|
228
269
|
}
|
|
229
270
|
return n;
|
|
230
271
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
272
|
+
if (t instanceof D || typeof t == "object" && t && "id" in t && !("terms" in t) && !("quadTerms" in t)) {
|
|
273
|
+
let e = t, n = new S();
|
|
274
|
+
Math.abs(this.constant) >= 1e-12 && n.linearTerms.set(e, this.constant);
|
|
275
|
+
for (let [t, r] of this.terms) n = n.add(S.fromProduct(t, e, r));
|
|
276
|
+
return n;
|
|
277
|
+
}
|
|
278
|
+
if (t instanceof S) {
|
|
279
|
+
if (t.quadTerms.size > 0 && this.terms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
280
|
+
if (this.terms.size === 0) return t.mul(this.constant);
|
|
281
|
+
let e = new S();
|
|
282
|
+
if (e.constant = this.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [n, r] of this.terms) e.linearTerms.set(n, (e.linearTerms.get(n) || 0) + r * t.constant);
|
|
283
|
+
if (Math.abs(this.constant) >= 1e-12) for (let [n, r] of t.linearTerms) e.linearTerms.set(n, (e.linearTerms.get(n) || 0) + r * this.constant);
|
|
284
|
+
for (let [n, r] of this.terms) for (let [i, a] of t.linearTerms) e = e.add(S.fromProduct(n, i, r * a));
|
|
285
|
+
return e;
|
|
286
|
+
}
|
|
287
|
+
if (this.terms.size === 0) return t.mul(this.constant);
|
|
288
|
+
if (t.terms.size === 0) return this.mul(t.constant);
|
|
289
|
+
let n = new S();
|
|
290
|
+
if (n.constant = this.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [e, r] of this.terms) n.linearTerms.set(e, (n.linearTerms.get(e) || 0) + r * t.constant);
|
|
291
|
+
if (Math.abs(this.constant) >= 1e-12) for (let [e, r] of t.terms) n.linearTerms.set(e, (n.linearTerms.get(e) || 0) + r * this.constant);
|
|
292
|
+
for (let [e, r] of this.terms) for (let [i, a] of t.terms) n = n.add(S.fromProduct(e, i, r * a));
|
|
234
293
|
return n;
|
|
235
294
|
}
|
|
236
295
|
div(e) {
|
|
@@ -273,7 +332,7 @@ var x = class e {
|
|
|
273
332
|
let i = this.clone(), a = 0;
|
|
274
333
|
typeof n == "number" ? a = n : "terms" in n ? (i = i.sub(new e(n.terms, 0)), a = n.constant) : i = i.sub(n);
|
|
275
334
|
let o = a - i.constant;
|
|
276
|
-
return i.constant = 0, new
|
|
335
|
+
return i.constant = 0, new b(i, t, o, r);
|
|
277
336
|
}
|
|
278
337
|
toString() {
|
|
279
338
|
let e = [], t = !0;
|
|
@@ -288,7 +347,7 @@ var x = class e {
|
|
|
288
347
|
return e.join(" ") || "0";
|
|
289
348
|
}
|
|
290
349
|
};
|
|
291
|
-
function
|
|
350
|
+
function w(e, t) {
|
|
292
351
|
let n = /* @__PURE__ */ new Map(), r = 0;
|
|
293
352
|
function i(e) {
|
|
294
353
|
if (e != null) {
|
|
@@ -314,19 +373,19 @@ function C(e, t) {
|
|
|
314
373
|
for (let r of e) i(t ? t(r, n++) : r);
|
|
315
374
|
}
|
|
316
375
|
for (let [e, t] of n) Math.abs(t) < 1e-12 && n.delete(e);
|
|
317
|
-
return new
|
|
376
|
+
return new C(n, r);
|
|
318
377
|
}
|
|
319
|
-
function
|
|
378
|
+
function ee(e, t) {
|
|
320
379
|
let n = /* @__PURE__ */ new Map(), r = 0;
|
|
321
380
|
function i(e) {
|
|
322
381
|
return typeof e == "object" && !!e && typeof e.id == "number" && typeof e.name == "string" && typeof e.mul == "function" && typeof e.le == "function";
|
|
323
382
|
}
|
|
324
383
|
function a(e) {
|
|
325
|
-
return i(e) || e instanceof
|
|
384
|
+
return i(e) || e instanceof C || e instanceof S;
|
|
326
385
|
}
|
|
327
386
|
function o(e, t) {
|
|
328
387
|
if (typeof t == "number") r += e * t;
|
|
329
|
-
else if (t instanceof
|
|
388
|
+
else if (t instanceof C) {
|
|
330
389
|
for (let [r, i] of t.terms) {
|
|
331
390
|
let t = n.get(r) || 0;
|
|
332
391
|
n.set(r, t + e * i);
|
|
@@ -384,17 +443,17 @@ function w(e, t) {
|
|
|
384
443
|
}
|
|
385
444
|
c(e, t);
|
|
386
445
|
for (let [e, t] of n) Math.abs(t) < 1e-12 && n.delete(e);
|
|
387
|
-
return new
|
|
446
|
+
return new C(n, r);
|
|
388
447
|
}
|
|
389
448
|
//#endregion
|
|
390
449
|
//#region src/modeler/variable.ts
|
|
391
|
-
var
|
|
392
|
-
function
|
|
450
|
+
var T = 0;
|
|
451
|
+
function E(e) {
|
|
393
452
|
if (!e) return "Continuous";
|
|
394
453
|
let t = e.toLowerCase();
|
|
395
454
|
return t === "binary" || t === "bin" ? "Binary" : t === "integer" || t === "int" ? "Integer" : "Continuous";
|
|
396
455
|
}
|
|
397
|
-
var
|
|
456
|
+
var D = class e {
|
|
398
457
|
id;
|
|
399
458
|
name;
|
|
400
459
|
type;
|
|
@@ -403,42 +462,49 @@ var E = class e {
|
|
|
403
462
|
value = null;
|
|
404
463
|
reducedCost = null;
|
|
405
464
|
constructor(e = {}) {
|
|
406
|
-
this.id = ++
|
|
465
|
+
this.id = ++T, this.name = e.name || `x_${this.id}`, this.type = E(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);
|
|
407
466
|
}
|
|
408
467
|
mul(t) {
|
|
409
|
-
if (typeof t == "number") return new
|
|
410
|
-
if (t instanceof e) return
|
|
411
|
-
|
|
468
|
+
if (typeof t == "number") return new C(/* @__PURE__ */ new Map([[this, t]]), 0);
|
|
469
|
+
if (t instanceof e) return S.fromProduct(this, t, 1);
|
|
470
|
+
if (t instanceof S) {
|
|
471
|
+
if (t.quadTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
472
|
+
let e = new S();
|
|
473
|
+
Math.abs(t.constant) >= 1e-12 && e.linearTerms.set(this, t.constant);
|
|
474
|
+
for (let [n, r] of t.linearTerms) e = e.add(S.fromProduct(this, n, r));
|
|
475
|
+
return e;
|
|
476
|
+
}
|
|
477
|
+
let n = new S();
|
|
412
478
|
Math.abs(t.constant) >= 1e-12 && n.linearTerms.set(this, t.constant);
|
|
413
479
|
for (let [e, r] of t.terms) {
|
|
414
|
-
let t =
|
|
480
|
+
let t = S.fromProduct(this, e, r);
|
|
415
481
|
n = n.add(t);
|
|
416
482
|
}
|
|
417
483
|
return n;
|
|
418
484
|
}
|
|
419
485
|
add(e) {
|
|
420
|
-
return e instanceof
|
|
486
|
+
return e instanceof S ? e.add(this) : new C(/* @__PURE__ */ new Map([[this, 1]]), 0).add(e);
|
|
421
487
|
}
|
|
422
488
|
sub(e) {
|
|
423
|
-
return e instanceof
|
|
489
|
+
return e instanceof S ? e.neg().add(this) : new C(/* @__PURE__ */ new Map([[this, 1]]), 0).sub(e);
|
|
424
490
|
}
|
|
425
491
|
neg() {
|
|
426
492
|
return this.mul(-1);
|
|
427
493
|
}
|
|
428
494
|
le(e, t) {
|
|
429
|
-
return new
|
|
495
|
+
return new C(/* @__PURE__ */ new Map([[this, 1]]), 0).le(e, t);
|
|
430
496
|
}
|
|
431
497
|
lessThanOrEqual(e, t) {
|
|
432
498
|
return this.le(e, t);
|
|
433
499
|
}
|
|
434
500
|
ge(e, t) {
|
|
435
|
-
return new
|
|
501
|
+
return new C(/* @__PURE__ */ new Map([[this, 1]]), 0).ge(e, t);
|
|
436
502
|
}
|
|
437
503
|
greaterThanOrEqual(e, t) {
|
|
438
504
|
return this.ge(e, t);
|
|
439
505
|
}
|
|
440
506
|
eq(e, t) {
|
|
441
|
-
return new
|
|
507
|
+
return new C(/* @__PURE__ */ new Map([[this, 1]]), 0).eq(e, t);
|
|
442
508
|
}
|
|
443
509
|
equalTo(e, t) {
|
|
444
510
|
return this.eq(e, t);
|
|
@@ -449,7 +515,7 @@ var E = class e {
|
|
|
449
515
|
};
|
|
450
516
|
//#endregion
|
|
451
517
|
//#region src/modeler/parser.ts
|
|
452
|
-
function
|
|
518
|
+
function O(e) {
|
|
453
519
|
let t = [], n = 0, r = e.length;
|
|
454
520
|
for (; n < r;) {
|
|
455
521
|
let i = e[n];
|
|
@@ -465,9 +531,16 @@ function D(e) {
|
|
|
465
531
|
type: "MINUS",
|
|
466
532
|
value: "-"
|
|
467
533
|
}), n++;
|
|
468
|
-
else if (i === "*") t.push({
|
|
534
|
+
else if (i === "*") n + 1 < r && e[n + 1] === "*" ? (t.push({
|
|
535
|
+
type: "CARET",
|
|
536
|
+
value: "**"
|
|
537
|
+
}), n += 2) : (t.push({
|
|
469
538
|
type: "STAR",
|
|
470
539
|
value: "*"
|
|
540
|
+
}), n++);
|
|
541
|
+
else if (i === "^") t.push({
|
|
542
|
+
type: "CARET",
|
|
543
|
+
value: "^"
|
|
471
544
|
}), n++;
|
|
472
545
|
else if (i === "/") t.push({
|
|
473
546
|
type: "SLASH",
|
|
@@ -505,7 +578,24 @@ function D(e) {
|
|
|
505
578
|
}
|
|
506
579
|
return t;
|
|
507
580
|
}
|
|
508
|
-
|
|
581
|
+
function k(e, t) {
|
|
582
|
+
return e instanceof S ? e.add(t) : t instanceof S ? t.add(e) : e.add(t);
|
|
583
|
+
}
|
|
584
|
+
function te(e, t) {
|
|
585
|
+
return e instanceof S ? e.sub(t) : t instanceof S ? t.neg().add(e) : e.sub(t);
|
|
586
|
+
}
|
|
587
|
+
function A(e, t) {
|
|
588
|
+
let n = e instanceof S ? e.quadTerms : /* @__PURE__ */ new Map(), r = t instanceof S ? t.quadTerms : /* @__PURE__ */ new Map(), i = e instanceof S ? e.linearTerms : e.terms, a = t instanceof S ? t.linearTerms : t.terms;
|
|
589
|
+
if (n.size > 0 && (r.size > 0 || a.size > 0) || r.size > 0 && (n.size > 0 || i.size > 0)) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
590
|
+
if (n.size === 0 && i.size === 0) return t.mul(e.constant);
|
|
591
|
+
if (r.size === 0 && a.size === 0) return e.mul(t.constant);
|
|
592
|
+
let o = new S();
|
|
593
|
+
if (o.constant = e.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [e, n] of i) o.linearTerms.set(e, (o.linearTerms.get(e) || 0) + n * t.constant);
|
|
594
|
+
if (Math.abs(e.constant) >= 1e-12) for (let [t, n] of a) o.linearTerms.set(t, (o.linearTerms.get(t) || 0) + n * e.constant);
|
|
595
|
+
for (let [e, t] of i) for (let [n, r] of a) o = o.add(S.fromProduct(e, n, t * r));
|
|
596
|
+
return o;
|
|
597
|
+
}
|
|
598
|
+
var j = class {
|
|
509
599
|
tokens;
|
|
510
600
|
pos = 0;
|
|
511
601
|
resolver;
|
|
@@ -526,11 +616,11 @@ var O = class {
|
|
|
526
616
|
for (; this.pos < this.tokens.length;) {
|
|
527
617
|
let t = this.peek();
|
|
528
618
|
if (!t) break;
|
|
529
|
-
if (t.type === "PLUS") this.consume(), e = e
|
|
530
|
-
else if (t.type === "MINUS") this.consume(), e = e
|
|
619
|
+
if (t.type === "PLUS") this.consume(), e = k(e, this.parseTerm());
|
|
620
|
+
else if (t.type === "MINUS") this.consume(), e = te(e, this.parseTerm());
|
|
531
621
|
else break;
|
|
532
622
|
}
|
|
533
|
-
return e;
|
|
623
|
+
return e instanceof S && e.quadTerms.size === 0 ? new C(e.linearTerms, e.constant) : e;
|
|
534
624
|
}
|
|
535
625
|
parseTerm() {
|
|
536
626
|
let e = this.parseFactor();
|
|
@@ -540,57 +630,83 @@ var O = class {
|
|
|
540
630
|
if (t.type === "STAR") {
|
|
541
631
|
this.consume();
|
|
542
632
|
let t = this.parseFactor();
|
|
543
|
-
e =
|
|
633
|
+
e = A(e, t);
|
|
544
634
|
} else if (t.type === "SLASH") {
|
|
545
635
|
this.consume();
|
|
546
|
-
let t = this.parseFactor();
|
|
547
|
-
if (
|
|
636
|
+
let t = this.parseFactor(), n = t instanceof S ? t.linearTerms : t.terms, r = t instanceof S ? t.quadTerms.size : 0;
|
|
637
|
+
if (n.size > 0 || r > 0) throw Error("Cannot divide by variable in expression");
|
|
548
638
|
if (Math.abs(t.constant) < 1e-12) throw Error("Division by zero in expression");
|
|
549
639
|
e = e.div(t.constant);
|
|
550
640
|
} else break;
|
|
551
641
|
}
|
|
552
642
|
return e;
|
|
553
643
|
}
|
|
554
|
-
multiplyExpressions(e, t) {
|
|
555
|
-
if (e.terms.size > 0 && t.terms.size > 0) throw Error("Multiplication of two variables creates a non-linear term (not allowed in MILP/LP)");
|
|
556
|
-
return e.terms.size === 0 ? t.mul(e.constant) : e.mul(t.constant);
|
|
557
|
-
}
|
|
558
644
|
parseFactor() {
|
|
559
645
|
let e = this.peek();
|
|
560
646
|
if (!e) throw Error("Unexpected end of expression");
|
|
561
647
|
if (e.type === "PLUS") return this.consume(), this.parseFactor();
|
|
562
648
|
if (e.type === "MINUS") return this.consume(), this.parseFactor().neg();
|
|
649
|
+
let t;
|
|
563
650
|
if (e.type === "NUMBER") {
|
|
564
651
|
this.consume();
|
|
565
|
-
let
|
|
566
|
-
if (this.peek()?.type === "IDENT") {
|
|
567
|
-
let e
|
|
568
|
-
|
|
652
|
+
let n = parseFloat(e.value);
|
|
653
|
+
if (this.peek()?.type === "IDENT" || this.peek()?.type === "LPAREN") {
|
|
654
|
+
let e;
|
|
655
|
+
if (this.peek()?.type === "IDENT") {
|
|
656
|
+
let t = this.consume(), n = this.resolve(t.value);
|
|
657
|
+
e = n instanceof D || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new C(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
|
|
658
|
+
} else this.consume("LPAREN"), e = this.parseExpression(), this.consume("RPAREN");
|
|
659
|
+
return this.applyPower(e).mul(n);
|
|
569
660
|
}
|
|
570
|
-
|
|
571
|
-
}
|
|
572
|
-
|
|
661
|
+
t = new C(/* @__PURE__ */ new Map(), n);
|
|
662
|
+
} else if (e.type === "IDENT") {
|
|
663
|
+
this.consume();
|
|
664
|
+
let n = this.resolve(e.value);
|
|
665
|
+
t = n instanceof D || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new C(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
|
|
666
|
+
} else if (e.type === "LPAREN") this.consume("LPAREN"), t = this.parseExpression(), this.consume("RPAREN");
|
|
667
|
+
else throw Error(`Unexpected token '${e.value}' in expression`);
|
|
668
|
+
return this.applyPower(t);
|
|
669
|
+
}
|
|
670
|
+
applyPower(e) {
|
|
671
|
+
if (this.peek()?.type !== "CARET") return e;
|
|
672
|
+
let t = [];
|
|
673
|
+
for (; this.peek()?.type === "CARET";) {
|
|
674
|
+
this.consume();
|
|
675
|
+
let e = this.peek();
|
|
676
|
+
if (!e || e.type !== "NUMBER") throw Error("Exponent must be a non-negative integer number");
|
|
573
677
|
this.consume();
|
|
574
|
-
let
|
|
575
|
-
|
|
678
|
+
let n = parseFloat(e.value);
|
|
679
|
+
if (!Number.isInteger(n) || n < 0) throw Error("Exponent must be a non-negative integer");
|
|
680
|
+
t.push(n);
|
|
576
681
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
682
|
+
let n = t[t.length - 1];
|
|
683
|
+
for (let e = t.length - 2; e >= 0; e--) n = t[e] ** +n;
|
|
684
|
+
if (!Number.isFinite(n) || n < 0) throw Error("Exponent creates an invalid or out-of-range power");
|
|
685
|
+
let r = e instanceof S, i = r ? e.quadTerms.size : 0, a = r ? e.linearTerms.size : e.terms.size;
|
|
686
|
+
if (i === 0 && a === 0) {
|
|
687
|
+
let t = e.constant ** +n;
|
|
688
|
+
return new C(/* @__PURE__ */ new Map(), t);
|
|
581
689
|
}
|
|
582
|
-
|
|
690
|
+
if (n === 0) return new C(/* @__PURE__ */ new Map(), 1);
|
|
691
|
+
if (n === 1) return e;
|
|
692
|
+
if (n === 2) return A(e, e);
|
|
693
|
+
throw Error(`Exponent ${n} creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)`);
|
|
583
694
|
}
|
|
584
|
-
|
|
695
|
+
getRemainingToken() {
|
|
696
|
+
return this.peek();
|
|
697
|
+
}
|
|
698
|
+
resolve(e) {
|
|
585
699
|
let t = this.resolver(e);
|
|
586
700
|
if (!t) throw Error(`Unknown variable '${e}' in expression`);
|
|
587
701
|
return t;
|
|
588
702
|
}
|
|
589
703
|
};
|
|
590
|
-
function
|
|
591
|
-
|
|
704
|
+
function M(e, t) {
|
|
705
|
+
let n = new j(O(e), t), r = n.parseExpression(), i = n.getRemainingToken();
|
|
706
|
+
if (i) throw Error(`Unexpected token '${i.value}' after expression in "${e}"`);
|
|
707
|
+
return r;
|
|
592
708
|
}
|
|
593
|
-
function
|
|
709
|
+
function N(e, t, n) {
|
|
594
710
|
let r = e.match(/(<=|>=|==|=<|=>|=)/);
|
|
595
711
|
if (!r) throw Error(`Constraint must contain a comparison operator (<=, >=, ==, =): "${e}"`);
|
|
596
712
|
let i = r[0], a = r.index, o = e.substring(0, a).trim(), s = e.substring(a + i.length).trim(), c;
|
|
@@ -598,20 +714,19 @@ function A(e, t, n) {
|
|
|
598
714
|
else if (i === ">=" || i === "=>") c = ">=";
|
|
599
715
|
else if (i === "==" || i === "=") c = "==";
|
|
600
716
|
else throw Error(`Unsupported operator "${i}"`);
|
|
601
|
-
let l =
|
|
602
|
-
|
|
717
|
+
let l = M(o, t), u = M(s, t);
|
|
718
|
+
if (l instanceof S && l.quadTerms.size > 0 || u instanceof S && u.quadTerms.size > 0) throw Error("Quadratic constraints are not supported (only linear constraints are allowed in MILP/LP/QP)");
|
|
719
|
+
let d = l instanceof S ? new C(l.linearTerms, l.constant) : l, f = u instanceof S ? new C(u.linearTerms, u.constant) : u;
|
|
720
|
+
return c === "<=" ? d.le(f, n) : c === ">=" ? d.ge(f, n) : d.eq(f, n);
|
|
603
721
|
}
|
|
604
|
-
function
|
|
722
|
+
function P(e, t) {
|
|
605
723
|
let n = /* @__PURE__ */ new Map(), r = "";
|
|
606
724
|
for (let i = 0; i < e.length; i++) if (r += e[i], i < t.length) {
|
|
607
725
|
let e = t[i];
|
|
608
726
|
if (typeof e == "number") r += `(${e})`;
|
|
609
|
-
else if (e instanceof
|
|
610
|
-
let t = `
|
|
727
|
+
else if (e instanceof D || e instanceof C || e instanceof S || typeof e == "object" && e && ("id" in e || "terms" in e || "quadTerms" in e)) {
|
|
728
|
+
let t = `__ph_${i}__`;
|
|
611
729
|
n.set(t, e), r += t;
|
|
612
|
-
} else if (e instanceof S) {
|
|
613
|
-
`${i}`, r += `(${e.toString()})`;
|
|
614
|
-
for (let [t] of e.terms) n.set(t.name, t);
|
|
615
730
|
}
|
|
616
731
|
}
|
|
617
732
|
return {
|
|
@@ -619,42 +734,42 @@ function j(e, t) {
|
|
|
619
734
|
resolver: (e) => n.get(e)
|
|
620
735
|
};
|
|
621
736
|
}
|
|
622
|
-
function
|
|
623
|
-
let { fullText: n, resolver: r } =
|
|
624
|
-
return
|
|
737
|
+
function F(e, ...t) {
|
|
738
|
+
let { fullText: n, resolver: r } = P(e, t);
|
|
739
|
+
return N(n, r);
|
|
625
740
|
}
|
|
626
|
-
function
|
|
627
|
-
let { fullText: n, resolver: r } =
|
|
628
|
-
return /(<=|>=|==|=<|=>|=)/.test(n) ?
|
|
741
|
+
function I(e, ...t) {
|
|
742
|
+
let { fullText: n, resolver: r } = P(e, t);
|
|
743
|
+
return /(<=|>=|==|=<|=>|=)/.test(n) ? N(n, r) : M(n, r);
|
|
629
744
|
}
|
|
630
745
|
//#endregion
|
|
631
746
|
//#region src/modeler/lp-writer.ts
|
|
632
|
-
function
|
|
747
|
+
function L(e, t, n) {
|
|
633
748
|
let r = e.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
634
749
|
return /^[0-9]/.test(r) && (r = `${t}_${r}`), (!r || r.length === 0) && (r = `${t}_${n}`), r;
|
|
635
750
|
}
|
|
636
|
-
function
|
|
751
|
+
function R(e) {
|
|
637
752
|
let { sense: t, objective: n, constraints: r, variables: i } = e, a = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
|
|
638
753
|
for (let e of i) {
|
|
639
|
-
let t =
|
|
754
|
+
let t = L(e.name, "x", e.id), n = t, r = 1;
|
|
640
755
|
for (; c.has(n);) n = `${t}_${r++}`;
|
|
641
756
|
c.add(n), o.set(e, n), a.set(n, e);
|
|
642
757
|
}
|
|
643
758
|
let l = /* @__PURE__ */ new Set(), u = /* @__PURE__ */ new Map();
|
|
644
759
|
for (let e of r) {
|
|
645
|
-
let t =
|
|
760
|
+
let t = L(e.name, "c", e.id), n = t, r = 1;
|
|
646
761
|
for (; l.has(n);) n = `${t}_${r++}`;
|
|
647
762
|
l.add(n), u.set(e, n), s.set(n, e);
|
|
648
763
|
}
|
|
649
764
|
let d = [];
|
|
650
765
|
d.push(t && t.toLowerCase() === "maximize" ? "Maximize" : "Minimize");
|
|
651
|
-
let f = [], p = !0, m = n instanceof
|
|
766
|
+
let f = [], p = !0, m = n instanceof S ? n.linearTerms : n.terms;
|
|
652
767
|
if (m) for (let [e, t] of m) {
|
|
653
768
|
if (Math.abs(t) < 1e-12) continue;
|
|
654
769
|
let n = o.get(e), r = t >= 0 ? p ? "" : "+ " : "- ", i = Math.abs(t), a = i === 1 ? "" : `${i} `;
|
|
655
770
|
f.push(`${r}${a}${n}`), p = !1;
|
|
656
771
|
}
|
|
657
|
-
if (n instanceof
|
|
772
|
+
if (n instanceof S && n.quadTerms.size > 0) {
|
|
658
773
|
let e = [], t = !0;
|
|
659
774
|
for (let r of n.quadTerms.values()) {
|
|
660
775
|
if (Math.abs(r.coeff) < 1e-12) continue;
|
|
@@ -706,38 +821,38 @@ function F(e) {
|
|
|
706
821
|
}
|
|
707
822
|
//#endregion
|
|
708
823
|
//#region src/modeler/solvers/registry.ts
|
|
709
|
-
var
|
|
710
|
-
|
|
711
|
-
var
|
|
712
|
-
function
|
|
713
|
-
|
|
824
|
+
var z = Symbol.for("washi.solverRegistry"), B = Symbol.for("washi.defaultSolverFactory"), V = globalThis;
|
|
825
|
+
V[z] || (V[z] = /* @__PURE__ */ new Map());
|
|
826
|
+
var H = V[z];
|
|
827
|
+
function U(e, t) {
|
|
828
|
+
H.set(e.toLowerCase(), t);
|
|
714
829
|
}
|
|
715
|
-
function
|
|
830
|
+
function W(e) {
|
|
716
831
|
if (typeof e == "string") {
|
|
717
|
-
let t =
|
|
832
|
+
let t = H.get(e.toLowerCase());
|
|
718
833
|
if (!t) throw Error(`Solver '${e}' is not registered.`);
|
|
719
|
-
|
|
720
|
-
} else
|
|
834
|
+
V[B] = t;
|
|
835
|
+
} else V[B] = typeof e == "function" ? e : () => e;
|
|
721
836
|
}
|
|
722
|
-
function
|
|
837
|
+
function G(e, t) {
|
|
723
838
|
if (!e) {
|
|
724
|
-
let e =
|
|
725
|
-
if (!e) throw Error(`No default solver available. Available solvers: ${
|
|
839
|
+
let e = V[B] || H.get("highs");
|
|
840
|
+
if (!e) throw Error(`No default solver available. Available solvers: ${K().join(", ")}`);
|
|
726
841
|
return e(t);
|
|
727
842
|
}
|
|
728
843
|
if (typeof e == "string") {
|
|
729
|
-
let n = e.toLowerCase(), r =
|
|
730
|
-
if (!r) throw Error(n === "glpk" ? `Solver 'glpk' not found. Available solvers: ${
|
|
844
|
+
let n = e.toLowerCase(), r = H.get(n);
|
|
845
|
+
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(", ")}`);
|
|
731
846
|
return r(t);
|
|
732
847
|
}
|
|
733
848
|
return e;
|
|
734
849
|
}
|
|
735
|
-
function
|
|
736
|
-
return Array.from(
|
|
850
|
+
function K() {
|
|
851
|
+
return Array.from(H.keys());
|
|
737
852
|
}
|
|
738
853
|
//#endregion
|
|
739
854
|
//#region \0washi-browser-worker-factory
|
|
740
|
-
function
|
|
855
|
+
function q() {
|
|
741
856
|
let e = r("highs-worker.js");
|
|
742
857
|
if (new URL(e).origin === window.location.origin) return new Worker(e, { type: "module" });
|
|
743
858
|
let t = URL.createObjectURL(new Blob(["import " + JSON.stringify(e) + ";"], { type: "text/javascript" }));
|
|
@@ -750,41 +865,41 @@ function W() {
|
|
|
750
865
|
}
|
|
751
866
|
//#endregion
|
|
752
867
|
//#region src/modeler/solvers/highs/worker-client.ts
|
|
753
|
-
var
|
|
754
|
-
function
|
|
868
|
+
var J = null, Y = 0, X = /* @__PURE__ */ new Map();
|
|
869
|
+
function Z() {
|
|
755
870
|
if (typeof window > "u" || typeof Worker > "u") return null;
|
|
756
|
-
if (!
|
|
757
|
-
|
|
758
|
-
let e =
|
|
759
|
-
|
|
760
|
-
let { type: t, id: n, result: r, runTime: i, error: a } = e.data, o =
|
|
761
|
-
o && (
|
|
871
|
+
if (!J) try {
|
|
872
|
+
J = q();
|
|
873
|
+
let e = J;
|
|
874
|
+
J.onmessage = (e) => {
|
|
875
|
+
let { type: t, id: n, result: r, runTime: i, error: a } = e.data, o = X.get(n);
|
|
876
|
+
o && (X.delete(n), t === "SOLVE_SUCCESS" ? o.resolve({
|
|
762
877
|
result: r,
|
|
763
878
|
runTime: i
|
|
764
879
|
}) : o.reject(Error(a || "Worker solve failed")));
|
|
765
880
|
};
|
|
766
881
|
let t = (t) => {
|
|
767
|
-
if (
|
|
768
|
-
|
|
769
|
-
for (let e of
|
|
770
|
-
|
|
882
|
+
if (J === e) {
|
|
883
|
+
J = null, e.terminate();
|
|
884
|
+
for (let e of X.values()) e.reject(t);
|
|
885
|
+
X.clear();
|
|
771
886
|
}
|
|
772
887
|
};
|
|
773
|
-
|
|
888
|
+
J.onerror = (e) => t(/* @__PURE__ */ Error(`[WaSHI] HiGHS Worker failed to load or execute. Check Worker assets, CORS and CSP. ${e?.message || ""}`)), J.onmessageerror = () => t(/* @__PURE__ */ Error("[WaSHI] Could not deserialize the HiGHS Worker response."));
|
|
774
889
|
} catch {
|
|
775
|
-
|
|
890
|
+
J = null;
|
|
776
891
|
}
|
|
777
|
-
return
|
|
892
|
+
return J;
|
|
778
893
|
}
|
|
779
|
-
async function
|
|
780
|
-
let r = await a(n.wasmUrl), i = n.useWorker ?? typeof window < "u" ?
|
|
894
|
+
async function ne(e, n = {}) {
|
|
895
|
+
let r = await a(n.wasmUrl), i = n.useWorker ?? typeof window < "u" ? Z() : null;
|
|
781
896
|
if (!i) return t(e, n);
|
|
782
897
|
let o = {
|
|
783
898
|
...n,
|
|
784
899
|
wasmUrl: r
|
|
785
|
-
}, s = `req_${++
|
|
900
|
+
}, s = `req_${++Y}`;
|
|
786
901
|
return new Promise((t, n) => {
|
|
787
|
-
|
|
902
|
+
X.set(s, {
|
|
788
903
|
resolve: t,
|
|
789
904
|
reject: n
|
|
790
905
|
});
|
|
@@ -796,13 +911,13 @@ async function Y(e, n = {}) {
|
|
|
796
911
|
options: o
|
|
797
912
|
});
|
|
798
913
|
} catch (e) {
|
|
799
|
-
|
|
914
|
+
X.delete(s), n(e);
|
|
800
915
|
}
|
|
801
916
|
});
|
|
802
917
|
}
|
|
803
918
|
//#endregion
|
|
804
919
|
//#region src/modeler/solvers/highs/solver.ts
|
|
805
|
-
function
|
|
920
|
+
function re(e) {
|
|
806
921
|
if (typeof e != "string") return "Unknown";
|
|
807
922
|
let t = e.trim();
|
|
808
923
|
if (!t) return "Unknown";
|
|
@@ -831,7 +946,7 @@ function X(e) {
|
|
|
831
946
|
let n = t.toLowerCase();
|
|
832
947
|
return n.includes("infeasible") && n.includes("unbounded") ? "Unknown" : n.includes("infeasible") ? "Infeasible" : n.includes("unbounded") ? "Unbounded" : n.includes("time limit") || n.includes("timelimit") ? "TimeLimit" : n.includes("iteration limit") || n.includes("iterationlimit") ? "IterationLimit" : n.includes("error") ? "Error" : n === "optimal" ? "Optimal" : "Unknown";
|
|
833
948
|
}
|
|
834
|
-
var
|
|
949
|
+
var Q = class e {
|
|
835
950
|
static capabilities = {
|
|
836
951
|
supportsMIP: !0,
|
|
837
952
|
supportsQP: !0
|
|
@@ -847,7 +962,7 @@ var Z = class e {
|
|
|
847
962
|
let r = {
|
|
848
963
|
...this.options,
|
|
849
964
|
...n
|
|
850
|
-
}, { lpString: i, nameToVar: a, nameToConstraint: o } = t, { result: s, runTime: c } = await
|
|
965
|
+
}, { lpString: i, nameToVar: a, nameToConstraint: o } = t, { result: s, runTime: c } = await ne(i, r), l = re(s?.Status);
|
|
851
966
|
if (l === "Infeasible" || l === "Unbounded") return {
|
|
852
967
|
status: l,
|
|
853
968
|
objectiveValue: null,
|
|
@@ -887,11 +1002,11 @@ var Z = class e {
|
|
|
887
1002
|
raw: s
|
|
888
1003
|
};
|
|
889
1004
|
}
|
|
890
|
-
},
|
|
891
|
-
function
|
|
892
|
-
|
|
1005
|
+
}, ie = Q;
|
|
1006
|
+
function ae() {
|
|
1007
|
+
U("highs", (e) => new Q(e)), W((e) => new Q(e));
|
|
893
1008
|
}
|
|
894
|
-
|
|
1009
|
+
ae();
|
|
895
1010
|
//#endregion
|
|
896
1011
|
//#region src/modeler/solvers/mock.ts
|
|
897
1012
|
var $ = class {
|
|
@@ -921,13 +1036,13 @@ var $ = class {
|
|
|
921
1036
|
};
|
|
922
1037
|
}
|
|
923
1038
|
};
|
|
924
|
-
function
|
|
925
|
-
|
|
1039
|
+
function oe() {
|
|
1040
|
+
U("mock", (e) => new $(e));
|
|
926
1041
|
}
|
|
927
|
-
|
|
1042
|
+
oe();
|
|
928
1043
|
//#endregion
|
|
929
1044
|
//#region src/modeler/model.ts
|
|
930
|
-
var
|
|
1045
|
+
var se = class {
|
|
931
1046
|
name;
|
|
932
1047
|
sense;
|
|
933
1048
|
objective;
|
|
@@ -938,6 +1053,8 @@ var ie = class {
|
|
|
938
1053
|
unsatCore = [];
|
|
939
1054
|
values = /* @__PURE__ */ new Map();
|
|
940
1055
|
varMapByName = /* @__PURE__ */ new Map();
|
|
1056
|
+
boolVarMapByName = /* @__PURE__ */ new Map();
|
|
1057
|
+
boolVarPrefixCounters = /* @__PURE__ */ new Map();
|
|
941
1058
|
constrMapByName = /* @__PURE__ */ new Map();
|
|
942
1059
|
status = "NotSolved";
|
|
943
1060
|
objectiveValue = null;
|
|
@@ -949,7 +1066,7 @@ var ie = class {
|
|
|
949
1066
|
n = typeof e == "string" ? {
|
|
950
1067
|
...t,
|
|
951
1068
|
name: e
|
|
952
|
-
} : e, this.name = n.name || "OptimizationModel", this.sense = l(n.sense), this.objective = new
|
|
1069
|
+
} : e, this.name = n.name || "OptimizationModel", this.sense = l(n.sense), this.objective = new C(), n.solver && (this.solver = G(n.solver));
|
|
953
1070
|
}
|
|
954
1071
|
get vars() {
|
|
955
1072
|
return this.variables;
|
|
@@ -1017,71 +1134,66 @@ var ie = class {
|
|
|
1017
1134
|
continuous(e, t, n) {
|
|
1018
1135
|
return this.createDomainVars("Continuous", e, t, n);
|
|
1019
1136
|
}
|
|
1020
|
-
|
|
1021
|
-
let i;
|
|
1022
|
-
i = typeof e == "string" ? {
|
|
1023
|
-
name: e,
|
|
1024
|
-
type: t,
|
|
1025
|
-
lb: n,
|
|
1026
|
-
ub: r
|
|
1027
|
-
} : e || {};
|
|
1028
|
-
let a = new E(i);
|
|
1029
|
-
if (this.varMapByName.has(a.name)) throw Error(`Variable with name '${a.name}' already exists in model`);
|
|
1030
|
-
return this.variables.push(a), this.varMapByName.set(a.name, a), a;
|
|
1031
|
-
}
|
|
1032
|
-
addVars(e, t, n) {
|
|
1137
|
+
bool(e, t, n) {
|
|
1033
1138
|
if (typeof t == "number" || Array.isArray(t)) {
|
|
1034
|
-
let r = typeof e == "number" ? Array.from({ length: e }, (e, t) => t) : e, i = typeof t == "number" ? Array.from({ length: t }, (e, t) => t) : t, a = n || {}, o = a.prefix || a.name || "
|
|
1139
|
+
let r = typeof e == "number" ? Array.from({ length: e }, (e, t) => t) : e, i = typeof t == "number" ? Array.from({ length: t }, (e, t) => t) : t, a = n || {}, o = a.prefix || a.name || "p", s = {};
|
|
1035
1140
|
for (let e of r) {
|
|
1036
1141
|
s[e] = {};
|
|
1037
|
-
for (let t of i) s[e][t] = this.
|
|
1038
|
-
...a,
|
|
1039
|
-
name: `${o}_${e}_${t}`
|
|
1040
|
-
});
|
|
1142
|
+
for (let t of i) s[e][t] = this.createBoolVar(`${o}_${e}_${t}`);
|
|
1041
1143
|
}
|
|
1042
1144
|
return s;
|
|
1043
1145
|
}
|
|
1146
|
+
if (typeof e == "string" || e === void 0) return this.createBoolVar(e);
|
|
1044
1147
|
let r = t || {}, i = r.prefix || r.name;
|
|
1045
1148
|
if (typeof e == "number") {
|
|
1046
|
-
let t = [], n = i || "
|
|
1047
|
-
for (let
|
|
1048
|
-
...r,
|
|
1049
|
-
name: `${n}_${i}`
|
|
1050
|
-
}));
|
|
1149
|
+
let t = [], n = i || "p";
|
|
1150
|
+
for (let r = 0; r < e; r++) t.push(this.createBoolVar(this.getNextBoolVarName(n)));
|
|
1051
1151
|
return t;
|
|
1052
1152
|
}
|
|
1053
|
-
{
|
|
1153
|
+
if (Array.isArray(e) || e && typeof e[Symbol.iterator] == "function") {
|
|
1054
1154
|
let t = {};
|
|
1055
1155
|
for (let n of e) {
|
|
1056
1156
|
let e = i ? `${i}_${n}` : `${n}`;
|
|
1057
|
-
t[n] = this.
|
|
1058
|
-
...r,
|
|
1059
|
-
name: e
|
|
1060
|
-
});
|
|
1157
|
+
t[n] = this.createBoolVar(e);
|
|
1061
1158
|
}
|
|
1062
1159
|
return t;
|
|
1063
1160
|
}
|
|
1161
|
+
throw Error("Invalid arguments provided for boolean variable creation");
|
|
1064
1162
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1163
|
+
hasVarName(e) {
|
|
1164
|
+
return this.varMapByName.has(e) || this.boolVarMapByName.has(e);
|
|
1165
|
+
}
|
|
1166
|
+
getNextBoolVarName(e) {
|
|
1167
|
+
let t = this.boolVarPrefixCounters.get(e) ?? 0, n = `${e}_${t}`;
|
|
1168
|
+
for (; this.hasVarName(n);) t++, n = `${e}_${t}`;
|
|
1169
|
+
return this.boolVarPrefixCounters.set(e, t + 1), n;
|
|
1170
|
+
}
|
|
1171
|
+
createBoolVar(e) {
|
|
1172
|
+
let t = typeof e == "string" ? e.trim() : void 0, n = t && t.length > 0 ? t : this.getNextBoolVarName("p");
|
|
1173
|
+
if (this.hasVarName(n)) throw Error(`Variable with name '${n}' already exists in model`);
|
|
1174
|
+
let r = new f(n);
|
|
1175
|
+
return this.boolVars.push(r), this.boolVarMapByName.set(r.name, r), r;
|
|
1176
|
+
}
|
|
1177
|
+
addVar(e) {
|
|
1178
|
+
let t = e || {}, n = typeof t.name == "string" ? t.name.trim() : void 0, r = n && n.length > 0 ? n : void 0, i = new D({
|
|
1179
|
+
...t,
|
|
1180
|
+
name: r
|
|
1181
|
+
});
|
|
1182
|
+
if (this.hasVarName(i.name)) throw Error(`Variable with name '${i.name}' already exists in model`);
|
|
1183
|
+
return this.variables.push(i), this.varMapByName.set(i.name, i), i;
|
|
1075
1184
|
}
|
|
1076
1185
|
getVarByName(e) {
|
|
1077
1186
|
return this.varMapByName.get(e);
|
|
1078
1187
|
}
|
|
1188
|
+
getBoolVarByName(e) {
|
|
1189
|
+
return this.boolVarMapByName.get(e);
|
|
1190
|
+
}
|
|
1079
1191
|
getConstraintByName(e) {
|
|
1080
1192
|
return this.constrMapByName.get(e);
|
|
1081
1193
|
}
|
|
1082
1194
|
setObjective(e, t) {
|
|
1083
|
-
if (e instanceof
|
|
1084
|
-
t && (this.sense = l(t)), this.objective = typeof e == "string" ?
|
|
1195
|
+
if (e instanceof b) throw Error("Cannot set objective to a constraint comparison (<=, >=, ==). Did you mean to use m.constrain(expr`... <= ...`)? For objectives, supply an unconstrained expression like expr`45 * ${x} + 80 * ${y}`.");
|
|
1196
|
+
t && (this.sense = l(t)), this.objective = typeof e == "string" ? M(e, (e) => this.getVarByName(e)) : typeof e == "number" ? new C(/* @__PURE__ */ new Map(), e) : e instanceof S || "terms" in e ? e.clone() : new C(/* @__PURE__ */ new Map([[e, 1]]), 0);
|
|
1085
1197
|
}
|
|
1086
1198
|
maximize(e) {
|
|
1087
1199
|
this.setObjective(e, "Maximize");
|
|
@@ -1094,12 +1206,13 @@ var ie = class {
|
|
|
1094
1206
|
for (let t of e) this.constrain(t);
|
|
1095
1207
|
return this;
|
|
1096
1208
|
}
|
|
1097
|
-
if (e instanceof S) throw Error("Cannot add a
|
|
1209
|
+
if (e instanceof S) throw Error("Cannot add a quadratic expression without a comparison operator (<=, >=, ==) as a constraint. Quadratic constraints are not supported (only linear constraints are allowed in MILP/LP/QP).");
|
|
1210
|
+
if (e instanceof C) throw Error("Cannot add a linear expression without a comparison operator (<=, >=, ==) as a constraint. Use expr`... <= ...` or .le(), .ge(), .eq().");
|
|
1098
1211
|
return this.addConstraint(e, t), this;
|
|
1099
1212
|
}
|
|
1100
1213
|
getValues(e) {
|
|
1101
1214
|
if (e == null) return null;
|
|
1102
|
-
if (e instanceof
|
|
1215
|
+
if (e instanceof D || e instanceof f) return e.value;
|
|
1103
1216
|
if (Array.isArray(e)) return e.map((e) => this.getValues(e));
|
|
1104
1217
|
if (typeof e == "object") {
|
|
1105
1218
|
let t = {};
|
|
@@ -1108,12 +1221,9 @@ var ie = class {
|
|
|
1108
1221
|
}
|
|
1109
1222
|
return null;
|
|
1110
1223
|
}
|
|
1111
|
-
addBoolVar(e) {
|
|
1112
|
-
let t = new f(e);
|
|
1113
|
-
return this.boolVars.push(t), t;
|
|
1114
|
-
}
|
|
1115
1224
|
addConstraint(e, t) {
|
|
1116
|
-
if (e instanceof S) throw Error("Cannot add a
|
|
1225
|
+
if (e instanceof S) throw Error("Cannot add a quadratic expression without a comparison operator (<=, >=, ==) as a constraint. Quadratic constraints are not supported (only linear constraints are allowed in MILP/LP/QP).");
|
|
1226
|
+
if (e instanceof C) throw Error("Cannot add a linear expression without a comparison operator (<=, >=, ==) as a constraint. Use expr`... <= ...` or .le(), .ge(), .eq().");
|
|
1117
1227
|
if (e instanceof d) {
|
|
1118
1228
|
let n = t || `lc_${this.logicalConstraints.length + 1}`;
|
|
1119
1229
|
return this.logicalConstraints.push({
|
|
@@ -1122,23 +1232,18 @@ var ie = class {
|
|
|
1122
1232
|
}), e;
|
|
1123
1233
|
}
|
|
1124
1234
|
let n;
|
|
1125
|
-
if (typeof e == "string" ? n =
|
|
1235
|
+
if (typeof e == "string" ? n = N(e, (e) => this.getVarByName(e), t) : (n = e, t && (n.name = t)), this.constrMapByName.has(n.name)) throw Error(`Constraint with name '${n.name}' already exists in model`);
|
|
1126
1236
|
return this.constraints.push(n), this.constrMapByName.set(n.name, n), n;
|
|
1127
1237
|
}
|
|
1128
|
-
addConstr(e, t) {
|
|
1129
|
-
return this.addConstraint(e, t);
|
|
1130
|
-
}
|
|
1131
|
-
addConstrs(e) {
|
|
1132
|
-
return e.map((e) => this.addConstraint(e));
|
|
1133
|
-
}
|
|
1134
1238
|
add(e, t) {
|
|
1135
1239
|
if (Array.isArray(e)) {
|
|
1136
1240
|
for (let t of e) this.add(t);
|
|
1137
1241
|
return this;
|
|
1138
1242
|
}
|
|
1139
|
-
return e instanceof
|
|
1243
|
+
return e instanceof D ? (this.varMapByName.has(e.name) || (this.variables.push(e), this.varMapByName.set(e.name, e)), this) : (this.addConstraint(e, t), this);
|
|
1140
1244
|
}
|
|
1141
1245
|
indicator(e, t, n = {}) {
|
|
1246
|
+
if (t instanceof S) throw Error("Quadratic expressions or constraints are not supported in indicator constraints (only linear constraints are allowed).");
|
|
1142
1247
|
if (!("sense" in t) || !("lhs" in t)) throw Error("Invalid constraint expression passed to indicator(). Expression must include a comparison operator (<=, >=, ==).");
|
|
1143
1248
|
let r = t, i = n.activeValue === void 0 ? 1 : n.activeValue, a = n.M === void 0 ? 1e5 : n.M, o = n.name || `ind_${e.name}_${r.name}`, s = [], { lhs: c, sense: l, rhs: u } = r;
|
|
1144
1249
|
if (i === 1) {
|
|
@@ -1162,11 +1267,8 @@ var ie = class {
|
|
|
1162
1267
|
}
|
|
1163
1268
|
return s;
|
|
1164
1269
|
}
|
|
1165
|
-
addIndicator(e, t, n = {}) {
|
|
1166
|
-
return this.indicator(e, t, n);
|
|
1167
|
-
}
|
|
1168
1270
|
toLpString() {
|
|
1169
|
-
let { lpString: e } =
|
|
1271
|
+
let { lpString: e } = R({
|
|
1170
1272
|
name: this.name,
|
|
1171
1273
|
sense: this.sense,
|
|
1172
1274
|
objective: this.objective,
|
|
@@ -1177,7 +1279,8 @@ var ie = class {
|
|
|
1177
1279
|
}
|
|
1178
1280
|
async optimize(e, t) {
|
|
1179
1281
|
let n, r;
|
|
1180
|
-
if (e && typeof e == "object" && "solve" in e && typeof e.solve == "function" ? (n = e, r = t || {}) : typeof e == "function" ? (n = new e(t), r = t || {}) : typeof e == "string" ? (n =
|
|
1282
|
+
if (e && typeof e == "object" && "solve" in e && typeof e.solve == "function" ? (n = e, r = t || {}) : typeof e == "function" ? (n = new e(t), r = t || {}) : typeof e == "string" ? (n = G(e, t), r = t || {}) : (r = { ...e }, r.solver ? (n = G(r.solver, r), delete r.solver) : n = this.solver || G()), this.objective instanceof S && this.objective.quadTerms.size > 0 && n.capabilities?.supportsQP === !1) throw Error(`Solver "${n.name}" does not support quadratic objectives (QP). Please use a QP-capable solver such as HiGHS or Clarabel.`);
|
|
1283
|
+
if (this.logicalConstraints.length > 0 && n.capabilities?.supportsSMT !== !0) throw Error(`Solver "${n.name}" does not support SMT / logical constraints (or, implies, not, xor). Please use an SMT-capable solver such as Z3.`);
|
|
1181
1284
|
let i = {
|
|
1182
1285
|
name: this.name,
|
|
1183
1286
|
sense: this.sense,
|
|
@@ -1186,7 +1289,7 @@ var ie = class {
|
|
|
1186
1289
|
variables: this.variables,
|
|
1187
1290
|
logicalConstraints: this.logicalConstraints,
|
|
1188
1291
|
boolVars: this.boolVars
|
|
1189
|
-
}, a =
|
|
1292
|
+
}, a = R(i), o = await n.solve(i, a, r);
|
|
1190
1293
|
this.runTime = o.runTime ?? 0, this.status = o.status, this.objectiveValue = o.objectiveValue ?? null;
|
|
1191
1294
|
let s = {}, c = {}, l = {}, u = {};
|
|
1192
1295
|
this.values.clear();
|
|
@@ -1232,7 +1335,7 @@ var ie = class {
|
|
|
1232
1335
|
}
|
|
1233
1336
|
async check(e, t) {
|
|
1234
1337
|
let n, r;
|
|
1235
|
-
if (e && typeof e == "object" && "solve" in e && typeof e.solve == "function" ? (n = e, r = t || {}) : typeof e == "function" ? (n = new e(t), r = t || {}) : typeof e == "string" ? (n =
|
|
1338
|
+
if (e && typeof e == "object" && "solve" in e && typeof e.solve == "function" ? (n = e, r = t || {}) : typeof e == "function" ? (n = new e(t), r = t || {}) : typeof e == "string" ? (n = G(e, t), r = t || {}) : (r = { ...e }, r.solver ? (n = G(r.solver, r), delete r.solver) : n = this.solver || G()), this.logicalConstraints.length > 0 && n.capabilities?.supportsSMT !== !0) throw Error(`Solver "${n.name}" does not support SMT / logical constraints (or, implies, not, xor). Please use an SMT-capable solver such as Z3.`);
|
|
1236
1339
|
if (typeof n.check == "function") {
|
|
1237
1340
|
let e = await n.check({
|
|
1238
1341
|
name: this.name,
|
|
@@ -1255,7 +1358,7 @@ var ie = class {
|
|
|
1255
1358
|
}
|
|
1256
1359
|
let i = this.objective, a = this.sense;
|
|
1257
1360
|
try {
|
|
1258
|
-
this.objective = new
|
|
1361
|
+
this.objective = new C(), this.sense = "Minimize";
|
|
1259
1362
|
let e = await this.optimize(n, r), t = e === "Optimal" || e === "Feasible", i = e === "Infeasible", a = {};
|
|
1260
1363
|
if (t) {
|
|
1261
1364
|
for (let e of this.variables) e.value !== null && (a[e.name] = e.value);
|
|
@@ -1272,4 +1375,4 @@ var ie = class {
|
|
|
1272
1375
|
}
|
|
1273
1376
|
};
|
|
1274
1377
|
//#endregion
|
|
1275
|
-
export { d as BoolExpr, p as BoolOp, f as BoolVar,
|
|
1378
|
+
export { d as BoolExpr, p as BoolOp, f as BoolVar, b as Constraint, ie as HiGHS, Q as HighsSolver, C as LinExpr, $ as MockSolver, se as Model, c as OFFICIAL_HIGHS_CDN_WASM_URL, S as QuadExpr, D as Var, m as and, F as c, ee as dot, I as expr, R as generateLpString, i as getHighs, o as getHighsWasmUrl, G as getSolver, _ as implies, n as isValidWasmHeader, K as listAvailableSolvers, l as normalizeSense, g as not, h as or, N as parseConstraint, M as parseExpr, e as probeWasmUrl, U as registerSolver, a as resolveBrowserWasmUrl, W as setDefaultSolver, s as setHighsWasmUrl, t as solveLpWithHighs, w as sum, v as xor };
|