@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/lib/washi.js
CHANGED
|
@@ -76,20 +76,45 @@ var D = class e {
|
|
|
76
76
|
return typeof t == "number" ? this.add(-t) : t instanceof e ? this.add(t.neg()) : ("terms" in t && t.terms instanceof Map, this.add(t.mul(-1)));
|
|
77
77
|
}
|
|
78
78
|
mul(t) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
let
|
|
82
|
-
|
|
79
|
+
if (typeof t == "number") {
|
|
80
|
+
let n = new e(/* @__PURE__ */ new Map(), /* @__PURE__ */ new Map(), this.constant * t);
|
|
81
|
+
for (let [e, r] of this.linearTerms) {
|
|
82
|
+
let i = r * t;
|
|
83
|
+
Math.abs(i) >= 1e-12 && n.linearTerms.set(e, i);
|
|
84
|
+
}
|
|
85
|
+
for (let [e, r] of this.quadTerms) {
|
|
86
|
+
let i = r.coeff * t;
|
|
87
|
+
Math.abs(i) >= 1e-12 && n.quadTerms.set(e, {
|
|
88
|
+
var1: r.var1,
|
|
89
|
+
var2: r.var2,
|
|
90
|
+
coeff: i
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return n;
|
|
83
94
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
});
|
|
95
|
+
if ("id" in t && "name" in t && !("terms" in t) && !("quadTerms" in t)) {
|
|
96
|
+
if (this.quadTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
97
|
+
let n = new e();
|
|
98
|
+
Math.abs(this.constant) >= 1e-12 && n.linearTerms.set(t, this.constant);
|
|
99
|
+
for (let [r, i] of this.linearTerms) n = n.add(e.fromProduct(r, t, i));
|
|
100
|
+
return n;
|
|
91
101
|
}
|
|
92
|
-
|
|
102
|
+
let n = t, r = "quadTerms" in n ? n.quadTerms.size : 0, i = "quadTerms" in n ? n.linearTerms : n.terms;
|
|
103
|
+
if (this.quadTerms.size > 0 && (r > 0 || i.size > 0) || r > 0 && this.linearTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
104
|
+
if (r === 0 && i.size === 0) return this.mul(n.constant);
|
|
105
|
+
if (this.quadTerms.size === 0 && this.linearTerms.size === 0) {
|
|
106
|
+
let t = n.mul(this.constant);
|
|
107
|
+
if (t instanceof e) return t;
|
|
108
|
+
let r = new e();
|
|
109
|
+
r.constant = t.constant;
|
|
110
|
+
for (let [e, n] of t.terms) r.linearTerms.set(e, n);
|
|
111
|
+
return r;
|
|
112
|
+
}
|
|
113
|
+
let a = new e();
|
|
114
|
+
if (a.constant = this.constant * n.constant, Math.abs(n.constant) >= 1e-12) for (let [e, t] of this.linearTerms) a.linearTerms.set(e, (a.linearTerms.get(e) || 0) + t * n.constant);
|
|
115
|
+
if (Math.abs(this.constant) >= 1e-12) for (let [e, t] of i) a.linearTerms.set(e, (a.linearTerms.get(e) || 0) + t * this.constant);
|
|
116
|
+
for (let [t, n] of this.linearTerms) for (let [r, o] of i) a = a.add(e.fromProduct(t, r, n * o));
|
|
117
|
+
return a;
|
|
93
118
|
}
|
|
94
119
|
div(e) {
|
|
95
120
|
if (Math.abs(e) < 1e-12) throw Error("Division by zero in QuadExpr.div()");
|
|
@@ -113,6 +138,22 @@ var D = class e {
|
|
|
113
138
|
getValue() {
|
|
114
139
|
return this.value;
|
|
115
140
|
}
|
|
141
|
+
toString() {
|
|
142
|
+
let e = [], t = !0;
|
|
143
|
+
for (let n of this.quadTerms.values()) {
|
|
144
|
+
let r = n.coeff, i = r >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(r), o = a === 1 ? "" : `${a} `;
|
|
145
|
+
n.var1 === n.var2 ? e.push(`${i}${o}${n.var1.name}^2`) : e.push(`${i}${o}${n.var1.name} * ${n.var2.name}`), t = !1;
|
|
146
|
+
}
|
|
147
|
+
for (let [n, r] of this.linearTerms) {
|
|
148
|
+
let i = r >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(r), o = a === 1 ? "" : `${a} `;
|
|
149
|
+
e.push(`${i}${o}${n.name}`), t = !1;
|
|
150
|
+
}
|
|
151
|
+
if (this.constant !== 0 || e.length === 0) {
|
|
152
|
+
let n = this.constant >= 0 ? t ? "" : "+ " : "- ";
|
|
153
|
+
e.push(`${n}${Math.abs(this.constant)}`);
|
|
154
|
+
}
|
|
155
|
+
return e.join(" ") || "0";
|
|
156
|
+
}
|
|
116
157
|
static fromProduct(t, n, r = 1) {
|
|
117
158
|
let i = new e(), a = E(t, n);
|
|
118
159
|
return i.quadTerms.set(a, {
|
|
@@ -158,9 +199,27 @@ var D = class e {
|
|
|
158
199
|
}
|
|
159
200
|
return n;
|
|
160
201
|
}
|
|
202
|
+
if (t instanceof M || typeof t == "object" && t && "id" in t && !("terms" in t) && !("quadTerms" in t)) {
|
|
203
|
+
let e = t, n = new D();
|
|
204
|
+
Math.abs(this.constant) >= 1e-12 && n.linearTerms.set(e, this.constant);
|
|
205
|
+
for (let [t, r] of this.terms) n = n.add(D.fromProduct(t, e, r));
|
|
206
|
+
return n;
|
|
207
|
+
}
|
|
208
|
+
if (t instanceof D) {
|
|
209
|
+
if (t.quadTerms.size > 0 && this.terms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
210
|
+
if (this.terms.size === 0) return t.mul(this.constant);
|
|
211
|
+
let e = new D();
|
|
212
|
+
if (e.constant = this.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [n, r] of this.terms) e.linearTerms.set(n, (e.linearTerms.get(n) || 0) + r * t.constant);
|
|
213
|
+
if (Math.abs(this.constant) >= 1e-12) for (let [n, r] of t.linearTerms) e.linearTerms.set(n, (e.linearTerms.get(n) || 0) + r * this.constant);
|
|
214
|
+
for (let [n, r] of this.terms) for (let [i, a] of t.linearTerms) e = e.add(D.fromProduct(n, i, r * a));
|
|
215
|
+
return e;
|
|
216
|
+
}
|
|
217
|
+
if (this.terms.size === 0) return t.mul(this.constant);
|
|
218
|
+
if (t.terms.size === 0) return this.mul(t.constant);
|
|
161
219
|
let n = new D();
|
|
162
|
-
Math.abs(
|
|
163
|
-
for (let [e, r] of
|
|
220
|
+
if (n.constant = this.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [e, r] of this.terms) n.linearTerms.set(e, (n.linearTerms.get(e) || 0) + r * t.constant);
|
|
221
|
+
if (Math.abs(this.constant) >= 1e-12) for (let [e, r] of t.terms) n.linearTerms.set(e, (n.linearTerms.get(e) || 0) + r * this.constant);
|
|
222
|
+
for (let [e, r] of this.terms) for (let [i, a] of t.terms) n = n.add(D.fromProduct(e, i, r * a));
|
|
164
223
|
return n;
|
|
165
224
|
}
|
|
166
225
|
div(e) {
|
|
@@ -318,13 +377,13 @@ function A(e, t) {
|
|
|
318
377
|
}
|
|
319
378
|
//#endregion
|
|
320
379
|
//#region src/modeler/variable.ts
|
|
321
|
-
var
|
|
322
|
-
function
|
|
380
|
+
var j = 0;
|
|
381
|
+
function ie(e) {
|
|
323
382
|
if (!e) return "Continuous";
|
|
324
383
|
let t = e.toLowerCase();
|
|
325
384
|
return t === "binary" || t === "bin" ? "Binary" : t === "integer" || t === "int" ? "Integer" : "Continuous";
|
|
326
385
|
}
|
|
327
|
-
var
|
|
386
|
+
var M = class e {
|
|
328
387
|
id;
|
|
329
388
|
name;
|
|
330
389
|
type;
|
|
@@ -333,11 +392,18 @@ var j = class e {
|
|
|
333
392
|
value = null;
|
|
334
393
|
reducedCost = null;
|
|
335
394
|
constructor(e = {}) {
|
|
336
|
-
this.id = ++
|
|
395
|
+
this.id = ++j, this.name = e.name || `x_${this.id}`, this.type = ie(e.type), this.type === "Binary" ? (this.lb = 0, this.ub = 1) : (this.lb = e.lb === void 0 ? 0 : e.lb, this.ub = e.ub === void 0 ? Infinity : e.ub);
|
|
337
396
|
}
|
|
338
397
|
mul(t) {
|
|
339
398
|
if (typeof t == "number") return new O(/* @__PURE__ */ new Map([[this, t]]), 0);
|
|
340
399
|
if (t instanceof e) return D.fromProduct(this, t, 1);
|
|
400
|
+
if (t instanceof D) {
|
|
401
|
+
if (t.quadTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
402
|
+
let e = new D();
|
|
403
|
+
Math.abs(t.constant) >= 1e-12 && e.linearTerms.set(this, t.constant);
|
|
404
|
+
for (let [n, r] of t.linearTerms) e = e.add(D.fromProduct(this, n, r));
|
|
405
|
+
return e;
|
|
406
|
+
}
|
|
341
407
|
let n = new D();
|
|
342
408
|
Math.abs(t.constant) >= 1e-12 && n.linearTerms.set(this, t.constant);
|
|
343
409
|
for (let [e, r] of t.terms) {
|
|
@@ -379,7 +445,7 @@ var j = class e {
|
|
|
379
445
|
};
|
|
380
446
|
//#endregion
|
|
381
447
|
//#region src/modeler/parser.ts
|
|
382
|
-
function
|
|
448
|
+
function ae(e) {
|
|
383
449
|
let t = [], n = 0, r = e.length;
|
|
384
450
|
for (; n < r;) {
|
|
385
451
|
let i = e[n];
|
|
@@ -395,9 +461,16 @@ function M(e) {
|
|
|
395
461
|
type: "MINUS",
|
|
396
462
|
value: "-"
|
|
397
463
|
}), n++;
|
|
398
|
-
else if (i === "*") t.push({
|
|
464
|
+
else if (i === "*") n + 1 < r && e[n + 1] === "*" ? (t.push({
|
|
465
|
+
type: "CARET",
|
|
466
|
+
value: "**"
|
|
467
|
+
}), n += 2) : (t.push({
|
|
399
468
|
type: "STAR",
|
|
400
469
|
value: "*"
|
|
470
|
+
}), n++);
|
|
471
|
+
else if (i === "^") t.push({
|
|
472
|
+
type: "CARET",
|
|
473
|
+
value: "^"
|
|
401
474
|
}), n++;
|
|
402
475
|
else if (i === "/") t.push({
|
|
403
476
|
type: "SLASH",
|
|
@@ -435,7 +508,24 @@ function M(e) {
|
|
|
435
508
|
}
|
|
436
509
|
return t;
|
|
437
510
|
}
|
|
438
|
-
|
|
511
|
+
function oe(e, t) {
|
|
512
|
+
return e instanceof D ? e.add(t) : t instanceof D ? t.add(e) : e.add(t);
|
|
513
|
+
}
|
|
514
|
+
function se(e, t) {
|
|
515
|
+
return e instanceof D ? e.sub(t) : t instanceof D ? t.neg().add(e) : e.sub(t);
|
|
516
|
+
}
|
|
517
|
+
function N(e, t) {
|
|
518
|
+
let n = e instanceof D ? e.quadTerms : /* @__PURE__ */ new Map(), r = t instanceof D ? t.quadTerms : /* @__PURE__ */ new Map(), i = e instanceof D ? e.linearTerms : e.terms, a = t instanceof D ? t.linearTerms : t.terms;
|
|
519
|
+
if (n.size > 0 && (r.size > 0 || a.size > 0) || r.size > 0 && (n.size > 0 || i.size > 0)) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
520
|
+
if (n.size === 0 && i.size === 0) return t.mul(e.constant);
|
|
521
|
+
if (r.size === 0 && a.size === 0) return e.mul(t.constant);
|
|
522
|
+
let o = new D();
|
|
523
|
+
if (o.constant = e.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [e, n] of i) o.linearTerms.set(e, (o.linearTerms.get(e) || 0) + n * t.constant);
|
|
524
|
+
if (Math.abs(e.constant) >= 1e-12) for (let [t, n] of a) o.linearTerms.set(t, (o.linearTerms.get(t) || 0) + n * e.constant);
|
|
525
|
+
for (let [e, t] of i) for (let [n, r] of a) o = o.add(D.fromProduct(e, n, t * r));
|
|
526
|
+
return o;
|
|
527
|
+
}
|
|
528
|
+
var ce = class {
|
|
439
529
|
tokens;
|
|
440
530
|
pos = 0;
|
|
441
531
|
resolver;
|
|
@@ -456,11 +546,11 @@ var N = class {
|
|
|
456
546
|
for (; this.pos < this.tokens.length;) {
|
|
457
547
|
let t = this.peek();
|
|
458
548
|
if (!t) break;
|
|
459
|
-
if (t.type === "PLUS") this.consume(), e = e
|
|
460
|
-
else if (t.type === "MINUS") this.consume(), e = e
|
|
549
|
+
if (t.type === "PLUS") this.consume(), e = oe(e, this.parseTerm());
|
|
550
|
+
else if (t.type === "MINUS") this.consume(), e = se(e, this.parseTerm());
|
|
461
551
|
else break;
|
|
462
552
|
}
|
|
463
|
-
return e;
|
|
553
|
+
return e instanceof D && e.quadTerms.size === 0 ? new O(e.linearTerms, e.constant) : e;
|
|
464
554
|
}
|
|
465
555
|
parseTerm() {
|
|
466
556
|
let e = this.parseFactor();
|
|
@@ -470,55 +560,81 @@ var N = class {
|
|
|
470
560
|
if (t.type === "STAR") {
|
|
471
561
|
this.consume();
|
|
472
562
|
let t = this.parseFactor();
|
|
473
|
-
e =
|
|
563
|
+
e = N(e, t);
|
|
474
564
|
} else if (t.type === "SLASH") {
|
|
475
565
|
this.consume();
|
|
476
|
-
let t = this.parseFactor();
|
|
477
|
-
if (
|
|
566
|
+
let t = this.parseFactor(), n = t instanceof D ? t.linearTerms : t.terms, r = t instanceof D ? t.quadTerms.size : 0;
|
|
567
|
+
if (n.size > 0 || r > 0) throw Error("Cannot divide by variable in expression");
|
|
478
568
|
if (Math.abs(t.constant) < 1e-12) throw Error("Division by zero in expression");
|
|
479
569
|
e = e.div(t.constant);
|
|
480
570
|
} else break;
|
|
481
571
|
}
|
|
482
572
|
return e;
|
|
483
573
|
}
|
|
484
|
-
multiplyExpressions(e, t) {
|
|
485
|
-
if (e.terms.size > 0 && t.terms.size > 0) throw Error("Multiplication of two variables creates a non-linear term (not allowed in MILP/LP)");
|
|
486
|
-
return e.terms.size === 0 ? t.mul(e.constant) : e.mul(t.constant);
|
|
487
|
-
}
|
|
488
574
|
parseFactor() {
|
|
489
575
|
let e = this.peek();
|
|
490
576
|
if (!e) throw Error("Unexpected end of expression");
|
|
491
577
|
if (e.type === "PLUS") return this.consume(), this.parseFactor();
|
|
492
578
|
if (e.type === "MINUS") return this.consume(), this.parseFactor().neg();
|
|
579
|
+
let t;
|
|
493
580
|
if (e.type === "NUMBER") {
|
|
494
581
|
this.consume();
|
|
495
|
-
let
|
|
496
|
-
if (this.peek()?.type === "IDENT") {
|
|
497
|
-
let e
|
|
498
|
-
|
|
582
|
+
let n = parseFloat(e.value);
|
|
583
|
+
if (this.peek()?.type === "IDENT" || this.peek()?.type === "LPAREN") {
|
|
584
|
+
let e;
|
|
585
|
+
if (this.peek()?.type === "IDENT") {
|
|
586
|
+
let t = this.consume(), n = this.resolve(t.value);
|
|
587
|
+
e = n instanceof M || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new O(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
|
|
588
|
+
} else this.consume("LPAREN"), e = this.parseExpression(), this.consume("RPAREN");
|
|
589
|
+
return this.applyPower(e).mul(n);
|
|
499
590
|
}
|
|
500
|
-
|
|
501
|
-
}
|
|
502
|
-
|
|
591
|
+
t = new O(/* @__PURE__ */ new Map(), n);
|
|
592
|
+
} else if (e.type === "IDENT") {
|
|
593
|
+
this.consume();
|
|
594
|
+
let n = this.resolve(e.value);
|
|
595
|
+
t = n instanceof M || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new O(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
|
|
596
|
+
} else if (e.type === "LPAREN") this.consume("LPAREN"), t = this.parseExpression(), this.consume("RPAREN");
|
|
597
|
+
else throw Error(`Unexpected token '${e.value}' in expression`);
|
|
598
|
+
return this.applyPower(t);
|
|
599
|
+
}
|
|
600
|
+
applyPower(e) {
|
|
601
|
+
if (this.peek()?.type !== "CARET") return e;
|
|
602
|
+
let t = [];
|
|
603
|
+
for (; this.peek()?.type === "CARET";) {
|
|
604
|
+
this.consume();
|
|
605
|
+
let e = this.peek();
|
|
606
|
+
if (!e || e.type !== "NUMBER") throw Error("Exponent must be a non-negative integer number");
|
|
503
607
|
this.consume();
|
|
504
|
-
let
|
|
505
|
-
|
|
608
|
+
let n = parseFloat(e.value);
|
|
609
|
+
if (!Number.isInteger(n) || n < 0) throw Error("Exponent must be a non-negative integer");
|
|
610
|
+
t.push(n);
|
|
506
611
|
}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
612
|
+
let n = t[t.length - 1];
|
|
613
|
+
for (let e = t.length - 2; e >= 0; e--) n = t[e] ** +n;
|
|
614
|
+
if (!Number.isFinite(n) || n < 0) throw Error("Exponent creates an invalid or out-of-range power");
|
|
615
|
+
let r = e instanceof D, i = r ? e.quadTerms.size : 0, a = r ? e.linearTerms.size : e.terms.size;
|
|
616
|
+
if (i === 0 && a === 0) {
|
|
617
|
+
let t = e.constant ** +n;
|
|
618
|
+
return new O(/* @__PURE__ */ new Map(), t);
|
|
511
619
|
}
|
|
512
|
-
|
|
620
|
+
if (n === 0) return new O(/* @__PURE__ */ new Map(), 1);
|
|
621
|
+
if (n === 1) return e;
|
|
622
|
+
if (n === 2) return N(e, e);
|
|
623
|
+
throw Error(`Exponent ${n} creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)`);
|
|
624
|
+
}
|
|
625
|
+
getRemainingToken() {
|
|
626
|
+
return this.peek();
|
|
513
627
|
}
|
|
514
|
-
|
|
628
|
+
resolve(e) {
|
|
515
629
|
let t = this.resolver(e);
|
|
516
630
|
if (!t) throw Error(`Unknown variable '${e}' in expression`);
|
|
517
631
|
return t;
|
|
518
632
|
}
|
|
519
633
|
};
|
|
520
634
|
function P(e, t) {
|
|
521
|
-
|
|
635
|
+
let n = new ce(ae(e), t), r = n.parseExpression(), i = n.getRemainingToken();
|
|
636
|
+
if (i) throw Error(`Unexpected token '${i.value}' after expression in "${e}"`);
|
|
637
|
+
return r;
|
|
522
638
|
}
|
|
523
639
|
function F(e, t, n) {
|
|
524
640
|
let r = e.match(/(<=|>=|==|=<|=>|=)/);
|
|
@@ -529,19 +645,18 @@ function F(e, t, n) {
|
|
|
529
645
|
else if (i === "==" || i === "=") c = "==";
|
|
530
646
|
else throw Error(`Unsupported operator "${i}"`);
|
|
531
647
|
let l = P(o, t), u = P(s, t);
|
|
532
|
-
|
|
648
|
+
if (l instanceof D && l.quadTerms.size > 0 || u instanceof D && u.quadTerms.size > 0) throw Error("Quadratic constraints are not supported (only linear constraints are allowed in MILP/LP/QP)");
|
|
649
|
+
let d = l instanceof D ? new O(l.linearTerms, l.constant) : l, f = u instanceof D ? new O(u.linearTerms, u.constant) : u;
|
|
650
|
+
return c === "<=" ? d.le(f, n) : c === ">=" ? d.ge(f, n) : d.eq(f, n);
|
|
533
651
|
}
|
|
534
652
|
function I(e, t) {
|
|
535
653
|
let n = /* @__PURE__ */ new Map(), r = "";
|
|
536
654
|
for (let i = 0; i < e.length; i++) if (r += e[i], i < t.length) {
|
|
537
655
|
let e = t[i];
|
|
538
656
|
if (typeof e == "number") r += `(${e})`;
|
|
539
|
-
else if (e instanceof
|
|
540
|
-
let t = `
|
|
657
|
+
else if (e instanceof M || e instanceof O || e instanceof D || typeof e == "object" && e && ("id" in e || "terms" in e || "quadTerms" in e)) {
|
|
658
|
+
let t = `__ph_${i}__`;
|
|
541
659
|
n.set(t, e), r += t;
|
|
542
|
-
} else if (e instanceof O) {
|
|
543
|
-
`${i}`, r += `(${e.toString()})`;
|
|
544
|
-
for (let [t] of e.terms) n.set(t.name, t);
|
|
545
660
|
}
|
|
546
661
|
}
|
|
547
662
|
return {
|
|
@@ -636,8 +751,8 @@ function B(e) {
|
|
|
636
751
|
}
|
|
637
752
|
//#endregion
|
|
638
753
|
//#region src/modeler/solvers/highs/worker-client.ts
|
|
639
|
-
var V = null,
|
|
640
|
-
function
|
|
754
|
+
var V = null, le = 0, H = /* @__PURE__ */ new Map();
|
|
755
|
+
function ue() {
|
|
641
756
|
if (typeof window > "u" || typeof Worker > "u") return null;
|
|
642
757
|
if (!V) try {
|
|
643
758
|
V = ee();
|
|
@@ -663,12 +778,12 @@ function se() {
|
|
|
663
778
|
return V;
|
|
664
779
|
}
|
|
665
780
|
async function U(e, t = {}) {
|
|
666
|
-
let n = await _(t.wasmUrl), r = t.useWorker ?? typeof window < "u" ?
|
|
781
|
+
let n = await _(t.wasmUrl), r = t.useWorker ?? typeof window < "u" ? ue() : null;
|
|
667
782
|
if (!r) return m(e, t);
|
|
668
783
|
let i = {
|
|
669
784
|
...t,
|
|
670
785
|
wasmUrl: n
|
|
671
|
-
}, a = `req_${++
|
|
786
|
+
}, a = `req_${++le}`;
|
|
672
787
|
return new Promise((t, n) => {
|
|
673
788
|
H.set(a, {
|
|
674
789
|
resolve: t,
|
|
@@ -795,10 +910,10 @@ var J = /* @__PURE__ */ S({
|
|
|
795
910
|
solveLp: () => U,
|
|
796
911
|
solveLpWithHighs: () => m
|
|
797
912
|
});
|
|
798
|
-
import * as
|
|
799
|
-
w(J,
|
|
800
|
-
import * as
|
|
801
|
-
w(J,
|
|
913
|
+
import * as de from "./highs-worker-factory.js";
|
|
914
|
+
w(J, de);
|
|
915
|
+
import * as fe from "./highs-assets.js";
|
|
916
|
+
w(J, fe);
|
|
802
917
|
//#endregion
|
|
803
918
|
//#region src/modeler/solvers/highs.ts
|
|
804
919
|
var Y = /* @__PURE__ */ S({
|
|
@@ -887,6 +1002,8 @@ var $ = class {
|
|
|
887
1002
|
unsatCore = [];
|
|
888
1003
|
values = /* @__PURE__ */ new Map();
|
|
889
1004
|
varMapByName = /* @__PURE__ */ new Map();
|
|
1005
|
+
boolVarMapByName = /* @__PURE__ */ new Map();
|
|
1006
|
+
boolVarPrefixCounters = /* @__PURE__ */ new Map();
|
|
890
1007
|
constrMapByName = /* @__PURE__ */ new Map();
|
|
891
1008
|
status = "NotSolved";
|
|
892
1009
|
objectiveValue = null;
|
|
@@ -966,65 +1083,60 @@ var $ = class {
|
|
|
966
1083
|
continuous(e, t, n) {
|
|
967
1084
|
return this.createDomainVars("Continuous", e, t, n);
|
|
968
1085
|
}
|
|
969
|
-
|
|
970
|
-
let i;
|
|
971
|
-
i = typeof e == "string" ? {
|
|
972
|
-
name: e,
|
|
973
|
-
type: t,
|
|
974
|
-
lb: n,
|
|
975
|
-
ub: r
|
|
976
|
-
} : e || {};
|
|
977
|
-
let a = new j(i);
|
|
978
|
-
if (this.varMapByName.has(a.name)) throw Error(`Variable with name '${a.name}' already exists in model`);
|
|
979
|
-
return this.variables.push(a), this.varMapByName.set(a.name, a), a;
|
|
980
|
-
}
|
|
981
|
-
addVars(e, t, n) {
|
|
1086
|
+
bool(e, t, n) {
|
|
982
1087
|
if (typeof t == "number" || Array.isArray(t)) {
|
|
983
|
-
let r = typeof e == "number" ? Array.from({ length: e }, (e, t) => t) : e, i = typeof t == "number" ? Array.from({ length: t }, (e, t) => t) : t, a = n || {}, o = a.prefix || a.name || "
|
|
1088
|
+
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 = {};
|
|
984
1089
|
for (let e of r) {
|
|
985
1090
|
s[e] = {};
|
|
986
|
-
for (let t of i) s[e][t] = this.
|
|
987
|
-
...a,
|
|
988
|
-
name: `${o}_${e}_${t}`
|
|
989
|
-
});
|
|
1091
|
+
for (let t of i) s[e][t] = this.createBoolVar(`${o}_${e}_${t}`);
|
|
990
1092
|
}
|
|
991
1093
|
return s;
|
|
992
1094
|
}
|
|
1095
|
+
if (typeof e == "string" || e === void 0) return this.createBoolVar(e);
|
|
993
1096
|
let r = t || {}, i = r.prefix || r.name;
|
|
994
1097
|
if (typeof e == "number") {
|
|
995
|
-
let t = [], n = i || "
|
|
996
|
-
for (let
|
|
997
|
-
...r,
|
|
998
|
-
name: `${n}_${i}`
|
|
999
|
-
}));
|
|
1098
|
+
let t = [], n = i || "p";
|
|
1099
|
+
for (let r = 0; r < e; r++) t.push(this.createBoolVar(this.getNextBoolVarName(n)));
|
|
1000
1100
|
return t;
|
|
1001
1101
|
}
|
|
1002
|
-
{
|
|
1102
|
+
if (Array.isArray(e) || e && typeof e[Symbol.iterator] == "function") {
|
|
1003
1103
|
let t = {};
|
|
1004
1104
|
for (let n of e) {
|
|
1005
1105
|
let e = i ? `${i}_${n}` : `${n}`;
|
|
1006
|
-
t[n] = this.
|
|
1007
|
-
...r,
|
|
1008
|
-
name: e
|
|
1009
|
-
});
|
|
1106
|
+
t[n] = this.createBoolVar(e);
|
|
1010
1107
|
}
|
|
1011
1108
|
return t;
|
|
1012
1109
|
}
|
|
1110
|
+
throw Error("Invalid arguments provided for boolean variable creation");
|
|
1013
1111
|
}
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1112
|
+
hasVarName(e) {
|
|
1113
|
+
return this.varMapByName.has(e) || this.boolVarMapByName.has(e);
|
|
1114
|
+
}
|
|
1115
|
+
getNextBoolVarName(e) {
|
|
1116
|
+
let t = this.boolVarPrefixCounters.get(e) ?? 0, n = `${e}_${t}`;
|
|
1117
|
+
for (; this.hasVarName(n);) t++, n = `${e}_${t}`;
|
|
1118
|
+
return this.boolVarPrefixCounters.set(e, t + 1), n;
|
|
1119
|
+
}
|
|
1120
|
+
createBoolVar(e) {
|
|
1121
|
+
let t = typeof e == "string" ? e.trim() : void 0, r = t && t.length > 0 ? t : this.getNextBoolVarName("p");
|
|
1122
|
+
if (this.hasVarName(r)) throw Error(`Variable with name '${r}' already exists in model`);
|
|
1123
|
+
let i = new n(r);
|
|
1124
|
+
return this.boolVars.push(i), this.boolVarMapByName.set(i.name, i), i;
|
|
1125
|
+
}
|
|
1126
|
+
addVar(e) {
|
|
1127
|
+
let t = e || {}, n = typeof t.name == "string" ? t.name.trim() : void 0, r = n && n.length > 0 ? n : void 0, i = new M({
|
|
1128
|
+
...t,
|
|
1129
|
+
name: r
|
|
1130
|
+
});
|
|
1131
|
+
if (this.hasVarName(i.name)) throw Error(`Variable with name '${i.name}' already exists in model`);
|
|
1132
|
+
return this.variables.push(i), this.varMapByName.set(i.name, i), i;
|
|
1024
1133
|
}
|
|
1025
1134
|
getVarByName(e) {
|
|
1026
1135
|
return this.varMapByName.get(e);
|
|
1027
1136
|
}
|
|
1137
|
+
getBoolVarByName(e) {
|
|
1138
|
+
return this.boolVarMapByName.get(e);
|
|
1139
|
+
}
|
|
1028
1140
|
getConstraintByName(e) {
|
|
1029
1141
|
return this.constrMapByName.get(e);
|
|
1030
1142
|
}
|
|
@@ -1043,12 +1155,13 @@ var $ = class {
|
|
|
1043
1155
|
for (let t of e) this.constrain(t);
|
|
1044
1156
|
return this;
|
|
1045
1157
|
}
|
|
1158
|
+
if (e instanceof D) 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).");
|
|
1046
1159
|
if (e instanceof O) throw Error("Cannot add a linear expression without a comparison operator (<=, >=, ==) as a constraint. Use expr`... <= ...` or .le(), .ge(), .eq().");
|
|
1047
1160
|
return this.addConstraint(e, t), this;
|
|
1048
1161
|
}
|
|
1049
1162
|
getValues(e) {
|
|
1050
1163
|
if (e == null) return null;
|
|
1051
|
-
if (e instanceof
|
|
1164
|
+
if (e instanceof M || e instanceof n) return e.value;
|
|
1052
1165
|
if (Array.isArray(e)) return e.map((e) => this.getValues(e));
|
|
1053
1166
|
if (typeof e == "object") {
|
|
1054
1167
|
let t = {};
|
|
@@ -1057,11 +1170,8 @@ var $ = class {
|
|
|
1057
1170
|
}
|
|
1058
1171
|
return null;
|
|
1059
1172
|
}
|
|
1060
|
-
addBoolVar(e) {
|
|
1061
|
-
let t = new n(e);
|
|
1062
|
-
return this.boolVars.push(t), t;
|
|
1063
|
-
}
|
|
1064
1173
|
addConstraint(e, t) {
|
|
1174
|
+
if (e instanceof D) 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).");
|
|
1065
1175
|
if (e instanceof O) throw Error("Cannot add a linear expression without a comparison operator (<=, >=, ==) as a constraint. Use expr`... <= ...` or .le(), .ge(), .eq().");
|
|
1066
1176
|
if (e instanceof i) {
|
|
1067
1177
|
let n = t || `lc_${this.logicalConstraints.length + 1}`;
|
|
@@ -1074,20 +1184,15 @@ var $ = class {
|
|
|
1074
1184
|
if (typeof e == "string" ? n = F(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`);
|
|
1075
1185
|
return this.constraints.push(n), this.constrMapByName.set(n.name, n), n;
|
|
1076
1186
|
}
|
|
1077
|
-
addConstr(e, t) {
|
|
1078
|
-
return this.addConstraint(e, t);
|
|
1079
|
-
}
|
|
1080
|
-
addConstrs(e) {
|
|
1081
|
-
return e.map((e) => this.addConstraint(e));
|
|
1082
|
-
}
|
|
1083
1187
|
add(e, t) {
|
|
1084
1188
|
if (Array.isArray(e)) {
|
|
1085
1189
|
for (let t of e) this.add(t);
|
|
1086
1190
|
return this;
|
|
1087
1191
|
}
|
|
1088
|
-
return e instanceof
|
|
1192
|
+
return e instanceof M ? (this.varMapByName.has(e.name) || (this.variables.push(e), this.varMapByName.set(e.name, e)), this) : (this.addConstraint(e, t), this);
|
|
1089
1193
|
}
|
|
1090
1194
|
indicator(e, t, n = {}) {
|
|
1195
|
+
if (t instanceof D) throw Error("Quadratic expressions or constraints are not supported in indicator constraints (only linear constraints are allowed).");
|
|
1091
1196
|
if (!("sense" in t) || !("lhs" in t)) throw Error("Invalid constraint expression passed to indicator(). Expression must include a comparison operator (<=, >=, ==).");
|
|
1092
1197
|
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;
|
|
1093
1198
|
if (i === 1) {
|
|
@@ -1111,9 +1216,6 @@ var $ = class {
|
|
|
1111
1216
|
}
|
|
1112
1217
|
return s;
|
|
1113
1218
|
}
|
|
1114
|
-
addIndicator(e, t, n = {}) {
|
|
1115
|
-
return this.indicator(e, t, n);
|
|
1116
|
-
}
|
|
1117
1219
|
toLpString() {
|
|
1118
1220
|
let { lpString: e } = B({
|
|
1119
1221
|
name: this.name,
|
|
@@ -1127,6 +1229,7 @@ var $ = class {
|
|
|
1127
1229
|
async optimize(e, t) {
|
|
1128
1230
|
let n, r;
|
|
1129
1231
|
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 = f(e, t), r = t || {}) : (r = { ...e }, r.solver ? (n = f(r.solver, r), delete r.solver) : n = this.solver || f()), this.objective instanceof D && 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.`);
|
|
1232
|
+
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.`);
|
|
1130
1233
|
let i = {
|
|
1131
1234
|
name: this.name,
|
|
1132
1235
|
sense: this.sense,
|
|
@@ -1232,7 +1335,7 @@ w(/* @__PURE__ */ S({
|
|
|
1232
1335
|
Model: () => $,
|
|
1233
1336
|
OFFICIAL_HIGHS_CDN_WASM_URL: () => b,
|
|
1234
1337
|
QuadExpr: () => D,
|
|
1235
|
-
Var: () =>
|
|
1338
|
+
Var: () => M,
|
|
1236
1339
|
and: () => e,
|
|
1237
1340
|
c: () => L,
|
|
1238
1341
|
dot: () => A,
|
|
@@ -1262,4 +1365,4 @@ w(/* @__PURE__ */ S({
|
|
|
1262
1365
|
xor: () => r
|
|
1263
1366
|
}), Q);
|
|
1264
1367
|
//#endregion
|
|
1265
|
-
export { i as BoolExpr, o as BoolOp, n as BoolVar, c as Constraint, K as HiGHS, G as HighsSolver, O as LinExpr, X as MockSolver, $ as Model, b as OFFICIAL_HIGHS_CDN_WASM_URL, D as QuadExpr,
|
|
1368
|
+
export { i as BoolExpr, o as BoolOp, n as BoolVar, c as Constraint, K as HiGHS, G as HighsSolver, O as LinExpr, X as MockSolver, $ as Model, b as OFFICIAL_HIGHS_CDN_WASM_URL, D as QuadExpr, M as Var, e as and, L as c, A as dot, R as expr, B as generateLpString, g as getHighs, v as getHighsWasmUrl, f as getSolver, a as implies, h as isValidWasmHeader, u as listAvailableSolvers, T as normalizeSense, s as not, t as or, F as parseConstraint, P as parseExpr, p as probeWasmUrl, d as registerSolver, _ as resolveBrowserWasmUrl, l as setDefaultSolver, y as setHighsWasmUrl, m as solveLpWithHighs, k as sum, r as xor };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Var } from "./variable.js";
|
|
2
2
|
import { Constraint } from "./constraint.js";
|
|
3
3
|
import { QuadExpr } from "./quad-expr.js";
|
|
4
4
|
/**
|
|
@@ -17,16 +17,21 @@ export declare class LinExpr {
|
|
|
17
17
|
*/
|
|
18
18
|
add(other: QuadExpr): QuadExpr;
|
|
19
19
|
add(other: LinExpr | Var | number): LinExpr;
|
|
20
|
+
add(other: QuadExpr | LinExpr | Var | number): LinExpr | QuadExpr;
|
|
20
21
|
/**
|
|
21
22
|
* Subtract another expression, variable, or number
|
|
22
23
|
*/
|
|
23
24
|
sub(other: QuadExpr): QuadExpr;
|
|
24
25
|
sub(other: LinExpr | Var | number): LinExpr;
|
|
26
|
+
sub(other: QuadExpr | LinExpr | Var | number): LinExpr | QuadExpr;
|
|
25
27
|
/**
|
|
26
|
-
* Multiply this expression by a scalar coefficient or
|
|
28
|
+
* Multiply this expression by a scalar coefficient, variable, or expression
|
|
27
29
|
*/
|
|
28
30
|
mul(scalar: number): LinExpr;
|
|
29
31
|
mul(v: Var): QuadExpr;
|
|
32
|
+
mul(other: LinExpr): LinExpr | QuadExpr;
|
|
33
|
+
mul(other: QuadExpr): QuadExpr;
|
|
34
|
+
mul(operand: number | Var | LinExpr | QuadExpr): LinExpr | QuadExpr;
|
|
30
35
|
/**
|
|
31
36
|
* Divide this expression by a non-zero scalar
|
|
32
37
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../../src/modeler/expression.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../../src/modeler/expression.ts"],"names":[],"mappings":"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"}
|