@ohtaman/washi 0.6.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 -421
- package/README.md +103 -421
- package/README.zh-CN.md +103 -421
- package/THIRD_PARTY_LICENSES.md +5 -3
- package/dist/browser/solvers/glpk.js +2 -2
- package/dist/browser/solvers/glpk.min.js +1 -1
- package/dist/browser/washi.js +777 -261
- package/dist/browser/washi.min.js +3 -3
- package/dist/lib/{registry-C20sxTwm.js → registry-D7TZ3Wh_.js} +88 -18
- package/dist/lib/solvers/glpk.js +3 -3
- package/dist/lib/solvers/z3.js +1 -1
- package/dist/lib/washi.js +864 -421
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/modeler/expression.d.ts +47 -26
- package/dist/types/modeler/expression.d.ts.map +1 -1
- package/dist/types/modeler/index.d.ts +2 -2
- package/dist/types/modeler/index.d.ts.map +1 -1
- package/dist/types/modeler/model.d.ts +12 -6
- 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/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 +2 -0
- package/dist/types/modeler/solvers/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 +14 -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 +28 -44
- package/docs/examples/unsat-core.md +15 -5
- package/docs/examples/vehicle-routing.md +10 -8
- package/docs/getting-started/ai-agents.md +25 -14
- 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 +46 -40
- package/docs/guide/decomposition.md +127 -259
- 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 +18 -6
- package/docs/guide/variables.md +33 -38
- package/docs/ja/getting-started/ai-agents.md +24 -14
- package/docs/solvers/highs.md +27 -6
- package/docs/solvers/index.md +1 -1
- package/docs/solvers/z3.md +3 -0
- package/docs/zh/getting-started/ai-agents.md +24 -14
- package/llms-full.txt +929 -687
- package/llms.txt +21 -19
- package/package.json +3 -3
- package/skills/washi/SKILL.md +14 -10
package/dist/browser/washi.js
CHANGED
|
@@ -491,37 +491,107 @@ var S = class e {
|
|
|
491
491
|
function w(e, t) {
|
|
492
492
|
let n = /* @__PURE__ */ new Map(), r = 0;
|
|
493
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) {
|
|
494
514
|
if (e != null) {
|
|
495
|
-
if (typeof e == "number")
|
|
496
|
-
|
|
497
|
-
|
|
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)) {
|
|
498
522
|
let t = e;
|
|
499
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().`);
|
|
500
525
|
for (let [e, r] of t.linearTerms) {
|
|
501
|
-
|
|
502
|
-
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);
|
|
503
530
|
}
|
|
504
|
-
r
|
|
505
|
-
|
|
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)) {
|
|
506
535
|
let t = e;
|
|
536
|
+
if (!Number.isFinite(t.constant)) throw Error(`Invalid non-finite constant "${t.constant}" in sum().`);
|
|
507
537
|
for (let [e, r] of t.terms) {
|
|
508
|
-
|
|
509
|
-
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);
|
|
510
542
|
}
|
|
511
|
-
r
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
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);
|
|
515
550
|
} else throw Error("Unsupported item in sum(): expected a number, Var, or LinExpr.");
|
|
516
551
|
}
|
|
517
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
|
+
}
|
|
518
579
|
if (typeof e == "number") {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
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") {
|
|
522
585
|
let n = 0;
|
|
523
|
-
for (let r of e)
|
|
524
|
-
}
|
|
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).");
|
|
525
595
|
for (let [e, t] of n) t === 0 && n.delete(e);
|
|
526
596
|
return new C(n, r);
|
|
527
597
|
}
|
|
@@ -830,7 +900,13 @@ var M = class {
|
|
|
830
900
|
toString() {
|
|
831
901
|
return this.name;
|
|
832
902
|
}
|
|
833
|
-
}
|
|
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]+)?$/;
|
|
834
910
|
function fe(e, t) {
|
|
835
911
|
let n = [], r = 0, i = e.length;
|
|
836
912
|
for (; r < i;) {
|
|
@@ -870,6 +946,10 @@ function fe(e, t) {
|
|
|
870
946
|
type: "RPAREN",
|
|
871
947
|
value: ")"
|
|
872
948
|
}), r++;
|
|
949
|
+
else if (a === ",") n.push({
|
|
950
|
+
type: "COMMA",
|
|
951
|
+
value: ","
|
|
952
|
+
}), r++;
|
|
873
953
|
else if (a === "<" || a === ">" || a === "=") {
|
|
874
954
|
let t = a;
|
|
875
955
|
r + 1 < i && (e[r + 1] === "=" || e[r + 1] === "<" || e[r + 1] === ">") ? (t += e[r + 1], r += 2) : r++, n.push({
|
|
@@ -914,12 +994,205 @@ function fe(e, t) {
|
|
|
914
994
|
}
|
|
915
995
|
return n;
|
|
916
996
|
}
|
|
917
|
-
|
|
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 {
|
|
918
1190
|
tokens;
|
|
919
1191
|
pos = 0;
|
|
920
1192
|
resolver;
|
|
921
|
-
|
|
922
|
-
|
|
1193
|
+
templateCtx;
|
|
1194
|
+
constructor(e, t, n) {
|
|
1195
|
+
this.tokens = e, this.resolver = t, this.templateCtx = n;
|
|
923
1196
|
}
|
|
924
1197
|
peek() {
|
|
925
1198
|
return this.tokens[this.pos];
|
|
@@ -931,54 +1204,240 @@ var pe = class {
|
|
|
931
1204
|
return t;
|
|
932
1205
|
}
|
|
933
1206
|
parseExpression() {
|
|
934
|
-
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();
|
|
935
1213
|
for (; this.pos < this.tokens.length;) {
|
|
936
1214
|
let t = this.peek();
|
|
937
1215
|
if (!t) break;
|
|
938
|
-
if (t.type === "PLUS") this.consume(), e = e
|
|
939
|
-
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(), "-");
|
|
940
1218
|
else break;
|
|
941
1219
|
}
|
|
942
|
-
return e
|
|
1220
|
+
return N(e) || typeof e == "number" ? e : pe(e);
|
|
943
1221
|
}
|
|
944
|
-
|
|
945
|
-
let e = this.
|
|
1222
|
+
parseTermNode() {
|
|
1223
|
+
let e = this.parseFactorNode();
|
|
946
1224
|
for (; this.pos < this.tokens.length;) {
|
|
947
1225
|
let t = this.peek();
|
|
948
1226
|
if (!t) break;
|
|
949
|
-
if (t.type === "STAR") this.consume(), e = e
|
|
950
|
-
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(), "/");
|
|
951
1229
|
else break;
|
|
952
1230
|
}
|
|
953
1231
|
return e;
|
|
954
1232
|
}
|
|
955
|
-
|
|
1233
|
+
parseFactorNode() {
|
|
956
1234
|
let e = this.peek();
|
|
957
1235
|
if (!e) throw Error("Unexpected end of expression");
|
|
958
|
-
if (e.type === "PLUS") return this.consume(), this.
|
|
959
|
-
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());
|
|
960
1238
|
let t;
|
|
961
1239
|
if (e.type === "NUMBER") {
|
|
962
1240
|
this.consume();
|
|
963
1241
|
let n = e.numericValue ?? Number(e.value);
|
|
964
1242
|
if (this.peek()?.type === "IDENT" || this.peek()?.type === "LPAREN") {
|
|
965
|
-
let e;
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
return this.applyPower(e).mul(n);
|
|
971
|
-
}
|
|
972
|
-
t = new C(/* @__PURE__ */ new Map(), n);
|
|
973
|
-
} else if (e.type === "IDENT") {
|
|
974
|
-
this.consume();
|
|
975
|
-
let n = this.resolve(e.value);
|
|
976
|
-
t = n instanceof M || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new C(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
|
|
977
|
-
} 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();
|
|
978
1248
|
else throw Error(`Unexpected token '${e.value}' in expression`);
|
|
979
|
-
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
|
+
});
|
|
980
1405
|
}
|
|
981
|
-
|
|
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;
|
|
1439
|
+
}
|
|
1440
|
+
applyPowerNode(e) {
|
|
982
1441
|
if (this.peek()?.type !== "CARET") return e;
|
|
983
1442
|
let t = [];
|
|
984
1443
|
for (; this.peek()?.type === "CARET";) {
|
|
@@ -995,55 +1454,87 @@ var pe = class {
|
|
|
995
1454
|
let n = t[t.length - 1];
|
|
996
1455
|
for (let e = t.length - 2; e >= 0; e--) n = t[e] ** +n;
|
|
997
1456
|
if (!Number.isFinite(n) || n < 0) throw Error("Exponent creates an invalid or out-of-range power");
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
if (
|
|
1002
|
-
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;
|
|
1003
1462
|
}
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
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);
|
|
1008
1477
|
}
|
|
1009
1478
|
getRemainingToken() {
|
|
1010
1479
|
return this.peek();
|
|
1011
1480
|
}
|
|
1012
|
-
|
|
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));
|
|
1013
1484
|
let t = this.resolver(e);
|
|
1014
1485
|
if (!t) throw Error(`Unknown variable '${e}' in expression`);
|
|
1015
|
-
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();
|
|
1016
1487
|
}
|
|
1017
1488
|
};
|
|
1018
|
-
function
|
|
1019
|
-
let
|
|
1020
|
-
if (
|
|
1021
|
-
return
|
|
1022
|
-
}
|
|
1023
|
-
function me(e, t) {
|
|
1024
|
-
return N(e, t);
|
|
1025
|
-
}
|
|
1026
|
-
function he(e, t, n, r) {
|
|
1027
|
-
let i = e.match(/(<=|>=|==|=<|=>|=)/);
|
|
1028
|
-
if (!i) throw Error(`Constraint must contain a comparison operator (<=, >=, ==, =): "${e}"`);
|
|
1029
|
-
let a = i[0], o = i.index, s = e.substring(0, o).trim(), c = e.substring(o + a.length).trim(), l;
|
|
1030
|
-
if (a === "<=" || a === "=<") l = "<=";
|
|
1031
|
-
else if (a === ">=" || a === "=>") l = ">=";
|
|
1032
|
-
else if (a === "==" || a === "=") l = "==";
|
|
1033
|
-
else throw Error(`Unsupported operator "${a}"`);
|
|
1034
|
-
let u = N(s, t, r), d = N(c, t, r);
|
|
1035
|
-
if (u instanceof S && u.quadTerms.size > 0 || d instanceof S && d.quadTerms.size > 0) throw Error("Quadratic constraints are not supported (only linear constraints are allowed in MILP/LP/QP)");
|
|
1036
|
-
let f = u instanceof S ? new C(u.linearTerms, u.constant) : u, p = d instanceof S ? new C(d.linearTerms, d.constant) : d, m;
|
|
1037
|
-
if (m = l === "<=" ? f.le(p, n) : l === ">=" ? f.ge(p, n) : f.eq(p, n), P(m.lhs), !Number.isFinite(m.rhs)) throw Error(`Invalid non-finite right-hand side "${m.rhs}" in constraint.`);
|
|
1038
|
-
return m;
|
|
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;
|
|
1039
1493
|
}
|
|
1040
|
-
function
|
|
1041
|
-
return
|
|
1494
|
+
function Ce(e, t) {
|
|
1495
|
+
return Se(e, t);
|
|
1042
1496
|
}
|
|
1043
|
-
function
|
|
1044
|
-
|
|
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;
|
|
1516
|
+
}
|
|
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;
|
|
1530
|
+
}
|
|
1531
|
+
function Ee(e, t, n) {
|
|
1532
|
+
return Te(e, t, n);
|
|
1045
1533
|
}
|
|
1046
|
-
function
|
|
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";
|
|
1536
|
+
}
|
|
1537
|
+
function B(e) {
|
|
1047
1538
|
if ("constant" in e && !Number.isFinite(e.constant)) throw Error(`Invalid non-finite constant "${e.constant}" in expression.`);
|
|
1048
1539
|
if ("terms" in e && e.terms instanceof Map) {
|
|
1049
1540
|
for (let [, t] of e.terms) if (!Number.isFinite(t)) throw Error(`Invalid non-finite coefficient "${t}" in expression.`);
|
|
@@ -1055,57 +1546,67 @@ function P(e) {
|
|
|
1055
1546
|
for (let [, t] of e.quadTerms) if (!Number.isFinite(t.coeff)) throw Error(`Invalid non-finite quadratic coefficient "${t.coeff}" in expression.`);
|
|
1056
1547
|
}
|
|
1057
1548
|
}
|
|
1058
|
-
function
|
|
1059
|
-
return e instanceof y
|
|
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;
|
|
1060
1551
|
}
|
|
1061
|
-
function
|
|
1062
|
-
let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), i = e.join(""),
|
|
1063
|
-
for (;
|
|
1064
|
-
let
|
|
1065
|
-
for (let
|
|
1066
|
-
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];
|
|
1067
1558
|
if (typeof e == "number") {
|
|
1068
1559
|
if (!Number.isFinite(e)) throw Error(`Invalid numeric value "${e}" in template expression: interpolated numbers must be finite.`);
|
|
1069
|
-
let t = `${
|
|
1070
|
-
r.set(t, e),
|
|
1071
|
-
} else if (
|
|
1072
|
-
else if (
|
|
1073
|
-
|
|
1074
|
-
let t = `${
|
|
1075
|
-
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} `;
|
|
1076
1573
|
} else throw Error("Unsupported interpolation value in template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
1077
1574
|
}
|
|
1078
1575
|
return {
|
|
1079
|
-
fullText:
|
|
1576
|
+
fullText: c,
|
|
1080
1577
|
resolver: (e) => n.get(e),
|
|
1081
|
-
numberMap: r
|
|
1578
|
+
numberMap: r,
|
|
1579
|
+
templateCtx: {
|
|
1580
|
+
rawContainerMap: i,
|
|
1581
|
+
functionMap: a
|
|
1582
|
+
}
|
|
1082
1583
|
};
|
|
1083
1584
|
}
|
|
1084
|
-
function
|
|
1085
|
-
let { fullText: n, resolver: r, numberMap: i } =
|
|
1086
|
-
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);
|
|
1087
1588
|
}
|
|
1088
1589
|
//#endregion
|
|
1089
1590
|
//#region src/modeler/lp-writer.ts
|
|
1090
|
-
function
|
|
1591
|
+
function ke(e) {
|
|
1091
1592
|
return typeof e == "object" && !!e && typeof e.lpString == "string" && e.nameToVar instanceof Map && e.nameToConstraint instanceof Map;
|
|
1092
1593
|
}
|
|
1093
|
-
function
|
|
1594
|
+
function H(e, t = "x", n = 0) {
|
|
1094
1595
|
let r = e.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
1095
1596
|
return /^[0-9]/.test(r) && (r = `${t}_${r}`), (!r || r.length === 0) && (r = `${t}_${n}`), r;
|
|
1096
1597
|
}
|
|
1097
|
-
function
|
|
1598
|
+
function Ae(e) {
|
|
1098
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();
|
|
1099
1600
|
for (let e = 0; e < t.length; e++) {
|
|
1100
1601
|
let n = t[e];
|
|
1101
1602
|
s.set(n, e);
|
|
1102
|
-
let a =
|
|
1603
|
+
let a = H(n.name, "x", e), o = a, l = 1;
|
|
1103
1604
|
for (; c.has(o);) o = `${a}_${l++}`;
|
|
1104
1605
|
c.add(o), i.set(n, o), r.set(o, n);
|
|
1105
1606
|
}
|
|
1106
1607
|
let l = /* @__PURE__ */ new Set();
|
|
1107
1608
|
for (let e = 0; e < n.length; e++) {
|
|
1108
|
-
let t = n[e], r =
|
|
1609
|
+
let t = n[e], r = H(t.name, "c", e + 1), i = r, s = 1;
|
|
1109
1610
|
for (; l.has(i);) i = `${r}_${s++}`;
|
|
1110
1611
|
l.add(i), o.set(t, i), a.set(i, t);
|
|
1111
1612
|
}
|
|
@@ -1118,8 +1619,8 @@ function xe(e) {
|
|
|
1118
1619
|
varOrder: s
|
|
1119
1620
|
};
|
|
1120
1621
|
}
|
|
1121
|
-
function
|
|
1122
|
-
let { sense: n, objective: r, constraints: i, variables: a } = e, o = t?.relax === !0, { nameToVar: s, varToName: c, nameToConstraint: l, constrToName: u, varOrder: d } =
|
|
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 = [];
|
|
1123
1624
|
f.push(n && n.toLowerCase() === "maximize" ? "Maximize" : "Minimize");
|
|
1124
1625
|
let p = [], m = !0, h = r instanceof S ? r.linearTerms : r.terms;
|
|
1125
1626
|
if (h) for (let [e, t] of h) {
|
|
@@ -1197,52 +1698,52 @@ function L(e, t) {
|
|
|
1197
1698
|
}
|
|
1198
1699
|
//#endregion
|
|
1199
1700
|
//#region src/modeler/solvers/registry.ts
|
|
1200
|
-
var
|
|
1201
|
-
|
|
1202
|
-
var
|
|
1203
|
-
function
|
|
1204
|
-
|
|
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);
|
|
1205
1706
|
}
|
|
1206
|
-
function
|
|
1707
|
+
function Fe(e) {
|
|
1207
1708
|
if (typeof e == "string") {
|
|
1208
|
-
let t =
|
|
1709
|
+
let t = W.get(e.toLowerCase());
|
|
1209
1710
|
if (!t) throw Error(`Solver '${e}' is not registered.`);
|
|
1210
|
-
|
|
1211
|
-
} else
|
|
1711
|
+
U[Ne] = t;
|
|
1712
|
+
} else U[Ne] = typeof e == "function" ? e : () => e;
|
|
1212
1713
|
}
|
|
1213
|
-
function
|
|
1714
|
+
function G(e, t) {
|
|
1214
1715
|
if (!e) {
|
|
1215
|
-
let e =
|
|
1216
|
-
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(", ")}`);
|
|
1217
1718
|
return e(t);
|
|
1218
1719
|
}
|
|
1219
1720
|
if (typeof e == "string") {
|
|
1220
|
-
let n = e.toLowerCase(), r =
|
|
1221
|
-
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(", ")}`);
|
|
1222
1723
|
return r(t);
|
|
1223
1724
|
}
|
|
1224
1725
|
return e;
|
|
1225
1726
|
}
|
|
1226
|
-
function
|
|
1227
|
-
return Array.from(
|
|
1727
|
+
function K() {
|
|
1728
|
+
return Array.from(W.keys());
|
|
1228
1729
|
}
|
|
1229
1730
|
//#endregion
|
|
1230
1731
|
//#region \0washi-browser-worker-factory
|
|
1231
|
-
function
|
|
1232
|
-
let e = a("highs-worker.js");
|
|
1233
|
-
if (new URL(e).origin ===
|
|
1234
|
-
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" }));
|
|
1235
1736
|
try {
|
|
1236
|
-
let e = new Worker(
|
|
1237
|
-
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;
|
|
1238
1739
|
} catch (e) {
|
|
1239
|
-
throw URL.revokeObjectURL(
|
|
1740
|
+
throw URL.revokeObjectURL(n), e;
|
|
1240
1741
|
}
|
|
1241
1742
|
}
|
|
1242
1743
|
//#endregion
|
|
1243
1744
|
//#region src/modeler/solvers/highs/worker-client.ts
|
|
1244
|
-
var
|
|
1245
|
-
function
|
|
1745
|
+
var q = null, Le = 0, J = /* @__PURE__ */ new Map();
|
|
1746
|
+
function Re(e, t) {
|
|
1246
1747
|
return e ? {
|
|
1247
1748
|
Status: "Interrupted",
|
|
1248
1749
|
StatusCode: 17,
|
|
@@ -1266,8 +1767,8 @@ function De(e, t) {
|
|
|
1266
1767
|
Rows: []
|
|
1267
1768
|
};
|
|
1268
1769
|
}
|
|
1269
|
-
function
|
|
1270
|
-
let t =
|
|
1770
|
+
function ze(e) {
|
|
1771
|
+
let t = J.values().next().value;
|
|
1271
1772
|
if (t && !t.dispatched) {
|
|
1272
1773
|
t.dispatched = !0;
|
|
1273
1774
|
try {
|
|
@@ -1279,30 +1780,30 @@ function G(e) {
|
|
|
1279
1780
|
...t.reportProgress ? { reportProgress: !0 } : {}
|
|
1280
1781
|
});
|
|
1281
1782
|
} catch (n) {
|
|
1282
|
-
|
|
1783
|
+
J.delete(t.id), t.cleanupAbort?.(), t.reject(n), ze(e);
|
|
1283
1784
|
}
|
|
1284
1785
|
}
|
|
1285
1786
|
}
|
|
1286
|
-
function
|
|
1287
|
-
let e =
|
|
1288
|
-
e && (
|
|
1289
|
-
for (let e of
|
|
1290
|
-
if (
|
|
1291
|
-
let e =
|
|
1292
|
-
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);
|
|
1293
1794
|
else {
|
|
1294
1795
|
let e = /* @__PURE__ */ Error("[WaSHI] Failed to recreate HiGHS Worker after interruption.");
|
|
1295
|
-
for (let t of Array.from(
|
|
1796
|
+
for (let t of Array.from(J.values())) J.delete(t.id), t.cleanupAbort?.(), t.reject(e);
|
|
1296
1797
|
}
|
|
1297
1798
|
}
|
|
1298
1799
|
}
|
|
1299
|
-
function
|
|
1800
|
+
function Ve() {
|
|
1300
1801
|
if (typeof window > "u" || typeof Worker > "u") return null;
|
|
1301
|
-
if (!
|
|
1302
|
-
|
|
1303
|
-
let e =
|
|
1304
|
-
|
|
1305
|
-
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);
|
|
1306
1807
|
if (l) {
|
|
1307
1808
|
if (n === "SOLVE_PROGRESS") {
|
|
1308
1809
|
if (s) {
|
|
@@ -1310,10 +1811,10 @@ function ke() {
|
|
|
1310
1811
|
try {
|
|
1311
1812
|
l.onProgress?.(s);
|
|
1312
1813
|
} catch (e) {
|
|
1313
|
-
let t =
|
|
1814
|
+
let t = J.get(r);
|
|
1314
1815
|
if (t) {
|
|
1315
|
-
let n =
|
|
1316
|
-
|
|
1816
|
+
let n = J.keys().next().value;
|
|
1817
|
+
J.delete(r), t.cleanupAbort?.(), n === r && Be(), t.reject(e);
|
|
1317
1818
|
}
|
|
1318
1819
|
}
|
|
1319
1820
|
}
|
|
@@ -1323,72 +1824,72 @@ function ke() {
|
|
|
1323
1824
|
c && (l.lastIncumbent = c);
|
|
1324
1825
|
return;
|
|
1325
1826
|
}
|
|
1326
|
-
|
|
1827
|
+
J.delete(r), l.cleanupAbort?.(), n === "SOLVE_SUCCESS" ? l.resolve({
|
|
1327
1828
|
result: i,
|
|
1328
1829
|
runTime: a
|
|
1329
|
-
}) : l.reject(Error(o || "Worker solve failed")),
|
|
1830
|
+
}) : l.reject(Error(o || "Worker solve failed")), q === e && ze(e);
|
|
1330
1831
|
}
|
|
1331
1832
|
};
|
|
1332
1833
|
let t = (t) => {
|
|
1333
|
-
if (
|
|
1334
|
-
|
|
1335
|
-
for (let e of
|
|
1336
|
-
|
|
1834
|
+
if (q === e) {
|
|
1835
|
+
q = null, e.terminate();
|
|
1836
|
+
for (let e of J.values()) e.cleanupAbort?.(), e.reject(t);
|
|
1837
|
+
J.clear();
|
|
1337
1838
|
}
|
|
1338
1839
|
};
|
|
1339
|
-
|
|
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."));
|
|
1340
1841
|
} catch {
|
|
1341
|
-
|
|
1842
|
+
q = null;
|
|
1342
1843
|
}
|
|
1343
|
-
return
|
|
1844
|
+
return q;
|
|
1344
1845
|
}
|
|
1345
|
-
async function
|
|
1846
|
+
async function He(t, n = {}) {
|
|
1346
1847
|
if (n.signal?.aborted) return {
|
|
1347
|
-
result:
|
|
1848
|
+
result: Re(),
|
|
1348
1849
|
runTime: 0
|
|
1349
1850
|
};
|
|
1350
1851
|
let r = await i(n.wasmUrl);
|
|
1351
1852
|
if (n.signal?.aborted) return {
|
|
1352
|
-
result:
|
|
1853
|
+
result: Re(),
|
|
1353
1854
|
runTime: 0
|
|
1354
1855
|
};
|
|
1355
|
-
let a = n.useWorker ?? typeof window < "u" ?
|
|
1356
|
-
if (!
|
|
1357
|
-
let { signal:
|
|
1358
|
-
for (let [e, t] of Object.entries(
|
|
1359
|
-
|
|
1360
|
-
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();
|
|
1361
1862
|
return new Promise((e, n) => {
|
|
1362
1863
|
let r = {
|
|
1363
|
-
id:
|
|
1864
|
+
id: f,
|
|
1364
1865
|
lpString: t,
|
|
1365
|
-
workerOptions:
|
|
1366
|
-
reportProgress:
|
|
1367
|
-
startTime:
|
|
1368
|
-
onProgress:
|
|
1866
|
+
workerOptions: u,
|
|
1867
|
+
reportProgress: d,
|
|
1868
|
+
startTime: p,
|
|
1869
|
+
onProgress: c,
|
|
1369
1870
|
resolve: e,
|
|
1370
1871
|
reject: n
|
|
1371
1872
|
};
|
|
1372
|
-
if (
|
|
1873
|
+
if (s) {
|
|
1373
1874
|
let e = () => {
|
|
1374
|
-
let e =
|
|
1875
|
+
let e = J.get(f);
|
|
1375
1876
|
if (!e) return;
|
|
1376
|
-
let t =
|
|
1377
|
-
|
|
1877
|
+
let t = J.keys().next().value;
|
|
1878
|
+
J.delete(f), e.cleanupAbort?.(), t === f && Be();
|
|
1378
1879
|
let n = (performance.now() - e.startTime) / 1e3;
|
|
1379
1880
|
e.resolve({
|
|
1380
|
-
result:
|
|
1881
|
+
result: Re(e.lastIncumbent, e.lastProgress),
|
|
1381
1882
|
runTime: n
|
|
1382
1883
|
});
|
|
1383
1884
|
};
|
|
1384
|
-
|
|
1885
|
+
s.addEventListener("abort", e, { once: !0 }), r.cleanupAbort = () => s.removeEventListener("abort", e);
|
|
1385
1886
|
}
|
|
1386
|
-
|
|
1887
|
+
J.set(f, r), ze(o);
|
|
1387
1888
|
});
|
|
1388
1889
|
}
|
|
1389
1890
|
//#endregion
|
|
1390
1891
|
//#region src/modeler/solvers/highs/solver.ts
|
|
1391
|
-
function
|
|
1892
|
+
function Ue(e, t) {
|
|
1392
1893
|
if (typeof t == "number") switch (t) {
|
|
1393
1894
|
case 0: return "NotSolved";
|
|
1394
1895
|
case 1:
|
|
@@ -1447,8 +1948,8 @@ function je(e, t) {
|
|
|
1447
1948
|
let r = n.toLowerCase();
|
|
1448
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";
|
|
1449
1950
|
}
|
|
1450
|
-
function
|
|
1451
|
-
switch (
|
|
1951
|
+
function We(e, t, n) {
|
|
1952
|
+
switch (Ue(e, t)) {
|
|
1452
1953
|
case "Optimal": return "Optimal";
|
|
1453
1954
|
case "Infeasible": return "Infeasible";
|
|
1454
1955
|
case "Unbounded": return "Unbounded";
|
|
@@ -1465,7 +1966,7 @@ function Me(e, t, n) {
|
|
|
1465
1966
|
default: return "Unknown";
|
|
1466
1967
|
}
|
|
1467
1968
|
}
|
|
1468
|
-
var
|
|
1969
|
+
var Ge = class e {
|
|
1469
1970
|
static capabilities = {
|
|
1470
1971
|
supportsMIP: !0,
|
|
1471
1972
|
supportsQP: !0,
|
|
@@ -1479,12 +1980,12 @@ var K = class e {
|
|
|
1479
1980
|
this.options = e;
|
|
1480
1981
|
}
|
|
1481
1982
|
async solve(e, t = {}, n = {}) {
|
|
1482
|
-
let r =
|
|
1983
|
+
let r = ke(t), i = r ? n : t, a = {
|
|
1483
1984
|
...this.options,
|
|
1484
1985
|
...i
|
|
1485
1986
|
}, o = e.objective.constant || 0;
|
|
1486
1987
|
for (let t of e.variables) A(t);
|
|
1487
|
-
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();
|
|
1488
1989
|
for (let [e, t] of c.entries()) {
|
|
1489
1990
|
f.add(t);
|
|
1490
1991
|
let n = ae(t);
|
|
@@ -1495,7 +1996,7 @@ var K = class e {
|
|
|
1495
1996
|
if (!f.has(n)) {
|
|
1496
1997
|
let e = ae(n);
|
|
1497
1998
|
if (e !== void 0) {
|
|
1498
|
-
let r =
|
|
1999
|
+
let r = H(n.name, "x", t);
|
|
1499
2000
|
Object.prototype.hasOwnProperty.call(u, r) || (u[r] = e, d = !0);
|
|
1500
2001
|
}
|
|
1501
2002
|
}
|
|
@@ -1506,13 +2007,13 @@ var K = class e {
|
|
|
1506
2007
|
...o === 0 ? {} : { objectiveOffset: o },
|
|
1507
2008
|
initialValues: d ? u : void 0
|
|
1508
2009
|
});
|
|
1509
|
-
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;
|
|
1510
2011
|
if (typeof m?.HasPrimalSolution == "boolean") y = m.HasPrimalSolution;
|
|
1511
2012
|
else {
|
|
1512
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);
|
|
1513
2014
|
y = _ === "Infeasible" || _ === "Unbounded" || _ === "InfeasibleOrUnbounded" || _ === "Error" || _ === "NotSolved" ? !1 : _ === "Optimal" || _ === "Feasible" ? n || t : n && (e.length === 0 || t);
|
|
1514
2015
|
}
|
|
1515
|
-
let b =
|
|
2016
|
+
let b = We(m?.Status, m?.StatusCode, y), x = null;
|
|
1516
2017
|
y && typeof m?.ObjectiveValue == "number" && Number.isFinite(m.ObjectiveValue) && (x = m.ObjectiveValue + g);
|
|
1517
2018
|
let S, C, w;
|
|
1518
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) {
|
|
@@ -1553,7 +2054,7 @@ var K = class e {
|
|
|
1553
2054
|
if (n) {
|
|
1554
2055
|
if (typeof t.Primal == "number" && Number.isFinite(t.Primal)) {
|
|
1555
2056
|
let e = Math.abs(t.Primal) < 1e-9 ? 0 : t.Primal;
|
|
1556
|
-
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);
|
|
1557
2058
|
}
|
|
1558
2059
|
typeof t.Dual == "number" && Number.isFinite(t.Dual) && T(O, n.name, Math.abs(t.Dual) < 1e-9 ? 0 : t.Dual);
|
|
1559
2060
|
}
|
|
@@ -1587,14 +2088,14 @@ var K = class e {
|
|
|
1587
2088
|
raw: m
|
|
1588
2089
|
};
|
|
1589
2090
|
}
|
|
1590
|
-
},
|
|
1591
|
-
function
|
|
1592
|
-
|
|
2091
|
+
}, Ke = Ge;
|
|
2092
|
+
function qe() {
|
|
2093
|
+
Pe("highs", (e) => new Ge(e)), Fe((e) => new Ge(e));
|
|
1593
2094
|
}
|
|
1594
|
-
|
|
2095
|
+
qe();
|
|
1595
2096
|
//#endregion
|
|
1596
2097
|
//#region src/modeler/solvers/mock.ts
|
|
1597
|
-
var
|
|
2098
|
+
var Je = class {
|
|
1598
2099
|
name;
|
|
1599
2100
|
capabilities;
|
|
1600
2101
|
options;
|
|
@@ -1606,7 +2107,7 @@ var Fe = class {
|
|
|
1606
2107
|
}, this.options = e;
|
|
1607
2108
|
}
|
|
1608
2109
|
async solve(e, t = {}, n = {}) {
|
|
1609
|
-
let r =
|
|
2110
|
+
let r = ke(t) ? n : t, i = {
|
|
1610
2111
|
...this.options,
|
|
1611
2112
|
...r
|
|
1612
2113
|
}, a = !!(i.values && Object.keys(i.values).length > 0 || i.boolValues && Object.keys(i.boolValues).length > 0);
|
|
@@ -1694,19 +2195,19 @@ var Fe = class {
|
|
|
1694
2195
|
};
|
|
1695
2196
|
}
|
|
1696
2197
|
};
|
|
1697
|
-
function
|
|
1698
|
-
|
|
2198
|
+
function Ye() {
|
|
2199
|
+
Pe("mock", (e) => new Je(e));
|
|
1699
2200
|
}
|
|
1700
|
-
|
|
2201
|
+
Ye();
|
|
1701
2202
|
//#endregion
|
|
1702
2203
|
//#region src/modeler/solution-validator.ts
|
|
1703
|
-
function
|
|
2204
|
+
function Xe(e, t) {
|
|
1704
2205
|
if (e === void 0) return 1e-6;
|
|
1705
2206
|
if (typeof e != "number" || !Number.isFinite(e) || e < 0) throw Error(`Invalid ${t}: expected a finite non-negative number, received ${String(e)}.`);
|
|
1706
2207
|
return e;
|
|
1707
2208
|
}
|
|
1708
|
-
function
|
|
1709
|
-
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;
|
|
1710
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.");
|
|
1711
2212
|
let o = t.values, s = [], c = Object.create(null), l = [], u = [], p = 0, m = (e) => {
|
|
1712
2213
|
typeof e == "number" && !Number.isNaN(e) && e > p && (p = e);
|
|
@@ -2080,10 +2581,10 @@ function Re(e, t = {}) {
|
|
|
2080
2581
|
}
|
|
2081
2582
|
//#endregion
|
|
2082
2583
|
//#region src/modeler/big-m.ts
|
|
2083
|
-
function
|
|
2584
|
+
function Qe(e, t) {
|
|
2084
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}.`);
|
|
2085
2586
|
}
|
|
2086
|
-
function
|
|
2587
|
+
function $e(e, t, n) {
|
|
2087
2588
|
let r = e.constant === void 0 ? 0 : e.constant;
|
|
2088
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}).`);
|
|
2089
2590
|
let i = t - r;
|
|
@@ -2094,8 +2595,8 @@ function Be(e, t, n) {
|
|
|
2094
2595
|
}
|
|
2095
2596
|
return i;
|
|
2096
2597
|
}
|
|
2097
|
-
function
|
|
2098
|
-
let r =
|
|
2598
|
+
function et(e, t, n) {
|
|
2599
|
+
let r = $e(e, t, n), i = 0;
|
|
2099
2600
|
for (let [t, r] of e.terms) {
|
|
2100
2601
|
if (r === 0) continue;
|
|
2101
2602
|
let e;
|
|
@@ -2115,8 +2616,8 @@ function q(e, t, n) {
|
|
|
2115
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.`);
|
|
2116
2617
|
return o;
|
|
2117
2618
|
}
|
|
2118
|
-
function
|
|
2119
|
-
let r =
|
|
2619
|
+
function tt(e, t, n) {
|
|
2620
|
+
let r = $e(e, t, n), i = 0;
|
|
2120
2621
|
for (let [t, r] of e.terms) {
|
|
2121
2622
|
if (r === 0) continue;
|
|
2122
2623
|
let e;
|
|
@@ -2139,7 +2640,7 @@ function J(e, t, n) {
|
|
|
2139
2640
|
function Y(e, t, n, r, i, a, o) {
|
|
2140
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}].`);
|
|
2141
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.`);
|
|
2142
|
-
let s =
|
|
2643
|
+
let s = $e(t, r, o);
|
|
2143
2644
|
if (i !== 0 && i !== 1) throw Error(`Invalid activeValue: ${i}. Indicator activation value must be 0 or 1.`);
|
|
2144
2645
|
if (n !== "<=" && n !== ">=") throw Error(`Invalid indicator sense for "${o}": expected "<=" or ">=", received "${String(n)}".`);
|
|
2145
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}.`);
|
|
@@ -2159,7 +2660,7 @@ function Y(e, t, n, r, i, a, o) {
|
|
|
2159
2660
|
function X(e, t = 0) {
|
|
2160
2661
|
return new C(new Map(e), t);
|
|
2161
2662
|
}
|
|
2162
|
-
function
|
|
2663
|
+
function nt(e, t, n, r) {
|
|
2163
2664
|
let i = [...e], a = [...n], o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map();
|
|
2164
2665
|
for (let e of n) s.set(e, e.name);
|
|
2165
2666
|
let c = new Set(e.map((e) => e.name)), l = 0;
|
|
@@ -2182,7 +2683,7 @@ function Ve(e, t, n, r) {
|
|
|
2182
2683
|
o.set(e, n), i.push(n);
|
|
2183
2684
|
}
|
|
2184
2685
|
function p(e, t) {
|
|
2185
|
-
if (e instanceof
|
|
2686
|
+
if (e instanceof rt) return e.wrappedVar;
|
|
2186
2687
|
if (e instanceof d) {
|
|
2187
2688
|
let n = o.get(e);
|
|
2188
2689
|
if (!n) throw Error(`Unregistered BoolVar "${e.name}" in logical constraint "${t}".`);
|
|
@@ -2404,7 +2905,7 @@ function Ve(e, t, n, r) {
|
|
|
2404
2905
|
}
|
|
2405
2906
|
if (r instanceof f) {
|
|
2406
2907
|
if (r.op === "and") {
|
|
2407
|
-
for (let e = 0; e < r.children.length; e++) g(new f("implies", [c instanceof M ? new
|
|
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}`);
|
|
2408
2909
|
return;
|
|
2409
2910
|
}
|
|
2410
2911
|
if (r.op === "not") {
|
|
@@ -2423,10 +2924,10 @@ function Ve(e, t, n, r) {
|
|
|
2423
2924
|
function _(e, t, n, r, i) {
|
|
2424
2925
|
let { lhs: o, sense: c, rhs: l } = t;
|
|
2425
2926
|
if (c === "<=" || c === ">=") {
|
|
2426
|
-
let t = Y(e, o, c, l, n, 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);
|
|
2427
2928
|
a.push(u), s.set(u, i);
|
|
2428
2929
|
} else {
|
|
2429
|
-
let t =
|
|
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`);
|
|
2430
2931
|
a.push(f, p), s.set(f, i), s.set(p, i);
|
|
2431
2932
|
}
|
|
2432
2933
|
}
|
|
@@ -2437,7 +2938,7 @@ function Ve(e, t, n, r) {
|
|
|
2437
2938
|
constraintToOriginalName: s
|
|
2438
2939
|
};
|
|
2439
2940
|
}
|
|
2440
|
-
var
|
|
2941
|
+
var rt = class extends d {
|
|
2441
2942
|
wrappedVar;
|
|
2442
2943
|
constructor(e) {
|
|
2443
2944
|
super(e.name), this.wrappedVar = e;
|
|
@@ -2445,7 +2946,7 @@ var He = class extends d {
|
|
|
2445
2946
|
};
|
|
2446
2947
|
//#endregion
|
|
2447
2948
|
//#region src/decomposition/column-generation.ts
|
|
2448
|
-
async function
|
|
2949
|
+
async function it(e) {
|
|
2449
2950
|
let t = e.master;
|
|
2450
2951
|
if (!t) throw Error("A master Model must be provided for solveColumnGeneration.");
|
|
2451
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;
|
|
@@ -2516,7 +3017,7 @@ async function Ue(e) {
|
|
|
2516
3017
|
}
|
|
2517
3018
|
//#endregion
|
|
2518
3019
|
//#region src/modeler/objective.ts
|
|
2519
|
-
function
|
|
3020
|
+
function at(e, t) {
|
|
2520
3021
|
let n = e;
|
|
2521
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}\`)).`);
|
|
2522
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}\`)).`);
|
|
@@ -2527,24 +3028,24 @@ function We(e, t) {
|
|
|
2527
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;
|
|
2528
3029
|
throw Error(`Invalid expression passed to ${t}(): expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.`);
|
|
2529
3030
|
}
|
|
2530
|
-
function
|
|
3031
|
+
function ot(e) {
|
|
2531
3032
|
return {
|
|
2532
|
-
expr:
|
|
3033
|
+
expr: at(e, "maximize"),
|
|
2533
3034
|
sense: "Maximize"
|
|
2534
3035
|
};
|
|
2535
3036
|
}
|
|
2536
|
-
function
|
|
3037
|
+
function st(e) {
|
|
2537
3038
|
return {
|
|
2538
|
-
expr:
|
|
3039
|
+
expr: at(e, "minimize"),
|
|
2539
3040
|
sense: "Minimize"
|
|
2540
3041
|
};
|
|
2541
3042
|
}
|
|
2542
3043
|
//#endregion
|
|
2543
3044
|
//#region src/decomposition/benders.ts
|
|
2544
|
-
function
|
|
3045
|
+
function ct(e) {
|
|
2545
3046
|
return !!(e && typeof e == "object" && "constraints" in e && "variables" in e && typeof e.solve == "function");
|
|
2546
3047
|
}
|
|
2547
|
-
async function
|
|
3048
|
+
async function lt(e, t, n, r, i, a, o, s, c = 1) {
|
|
2548
3049
|
let l = [];
|
|
2549
3050
|
for (let r = 0; r < t.length; r++) {
|
|
2550
3051
|
let a = t[r], o = a.lhs, s = a.sense, u = a.rhs - (o.constant || 0), d = [], f = [], p = 0;
|
|
@@ -2600,7 +3101,7 @@ async function Je(e, t, n, r, i, a, o, s, c = 1) {
|
|
|
2600
3101
|
subproblemObjective: b
|
|
2601
3102
|
};
|
|
2602
3103
|
}
|
|
2603
|
-
async function
|
|
3104
|
+
async function ut(e) {
|
|
2604
3105
|
let t = e.master;
|
|
2605
3106
|
if (!t) throw Error("A master Model must be provided for solveBenders.");
|
|
2606
3107
|
let { subproblem: n, maxIterations: r = 100, gapTolerance: i = 1e-4, solver: a, solverOptions: o, onIteration: s } = e, c;
|
|
@@ -2624,10 +3125,10 @@ async function Ye(e) {
|
|
|
2624
3125
|
master: t
|
|
2625
3126
|
}), x = [];
|
|
2626
3127
|
if (b) {
|
|
2627
|
-
if (
|
|
3128
|
+
if (ct(b)) {
|
|
2628
3129
|
let n = b, r = n.linkingConstraints;
|
|
2629
|
-
c || (c = t.continuous("__benders_theta", { lb: 0 }), v ? t.objective(
|
|
2630
|
-
let i = await
|
|
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);
|
|
2631
3132
|
i && x.push(i);
|
|
2632
3133
|
} else Array.isArray(b) ? x.push(...b) : x.push(b);
|
|
2633
3134
|
}
|
|
@@ -2683,13 +3184,13 @@ function Z(e) {
|
|
|
2683
3184
|
function Q(e) {
|
|
2684
3185
|
return typeof e == "object" && !!e && !Array.isArray(e) && !(e instanceof String) && typeof e[Symbol.iterator] != "function";
|
|
2685
3186
|
}
|
|
2686
|
-
function
|
|
3187
|
+
function dt(e) {
|
|
2687
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);
|
|
2688
3189
|
}
|
|
2689
3190
|
function $(e, t) {
|
|
2690
3191
|
if (!Number.isInteger(e) || e < 0) throw Error(`Invalid count (${e}) for ${t} variable creation: count must be a non-negative integer.`);
|
|
2691
3192
|
}
|
|
2692
|
-
var
|
|
3193
|
+
var ft = class {
|
|
2693
3194
|
name;
|
|
2694
3195
|
_sense;
|
|
2695
3196
|
_objectiveExpr;
|
|
@@ -2732,7 +3233,7 @@ var Ze = class {
|
|
|
2732
3233
|
n = typeof e == "string" ? {
|
|
2733
3234
|
...t,
|
|
2734
3235
|
name: e
|
|
2735
|
-
} : e, this.name = n.name || "OptimizationModel", this._sense = s(n.sense), this._objectiveExpr = new C(), n.solver && (this.solver =
|
|
3236
|
+
} : e, this.name = n.name || "OptimizationModel", this._sense = s(n.sense), this._objectiveExpr = new C(), n.solver && (this.solver = G(n.solver));
|
|
2736
3237
|
}
|
|
2737
3238
|
get sense() {
|
|
2738
3239
|
return this._sense;
|
|
@@ -3031,7 +3532,7 @@ var Ze = class {
|
|
|
3031
3532
|
applyObjective(e, t) {
|
|
3032
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}`)).");
|
|
3033
3534
|
let n = t === void 0 ? this.sense : s(t), r;
|
|
3034
|
-
if (typeof e == "string") r =
|
|
3535
|
+
if (typeof e == "string") r = Ce(e, (e) => this.getVarByName(e));
|
|
3035
3536
|
else if (typeof e == "number") r = new C(/* @__PURE__ */ new Map(), e);
|
|
3036
3537
|
else if (e instanceof S) r = e.clone();
|
|
3037
3538
|
else if (e instanceof C) r = e.clone();
|
|
@@ -3047,13 +3548,14 @@ var Ze = class {
|
|
|
3047
3548
|
}
|
|
3048
3549
|
constraint(e, t) {
|
|
3049
3550
|
if (Array.isArray(e)) return this.runTransactionalBatch(() => {
|
|
3050
|
-
|
|
3051
|
-
|
|
3551
|
+
let t = [];
|
|
3552
|
+
for (let n of e) t.push(this.constraint(n));
|
|
3553
|
+
return t;
|
|
3052
3554
|
});
|
|
3053
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.");
|
|
3054
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().");
|
|
3055
|
-
if (
|
|
3056
|
-
return this.addConstraint(e, t)
|
|
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);
|
|
3057
3559
|
}
|
|
3058
3560
|
getValues(e) {
|
|
3059
3561
|
if (e == null) return null;
|
|
@@ -3069,7 +3571,7 @@ var Ze = class {
|
|
|
3069
3571
|
addConstraint(e, t) {
|
|
3070
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.");
|
|
3071
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().");
|
|
3072
|
-
if (
|
|
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().`);
|
|
3073
3575
|
if (e instanceof u) {
|
|
3074
3576
|
let n = typeof t == "string" && t.trim().length > 0 ? t.trim() : void 0;
|
|
3075
3577
|
if (n !== void 0) {
|
|
@@ -3089,7 +3591,7 @@ var Ze = class {
|
|
|
3089
3591
|
};
|
|
3090
3592
|
return this.logicalConstraints.push(a), this.logicalConstrMapByName.set(i, a), this.recordModelMutation(), e;
|
|
3091
3593
|
}
|
|
3092
|
-
let n = typeof e == "string" ?
|
|
3594
|
+
let n = typeof e == "string" ? Ee(e, (e) => this.getVarByName(e), t) : e;
|
|
3093
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.");
|
|
3094
3596
|
n.ownerModel && n.ownerModel !== this && (j(n, this.name, (e) => this.varMapByName.get(e.name) === e, n.name), te(n, this));
|
|
3095
3597
|
let r = typeof t == "string" && t.trim().length > 0 ? t.trim() : n.hasExplicitName ? n.name.trim() : void 0;
|
|
@@ -3128,15 +3630,15 @@ var Ze = class {
|
|
|
3128
3630
|
try {
|
|
3129
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`);
|
|
3130
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`);
|
|
3131
|
-
n.M !== void 0 &&
|
|
3633
|
+
n.M !== void 0 && Qe(n.M, d);
|
|
3132
3634
|
let t = (e) => this.varMapByName.get(e.name) === e;
|
|
3133
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.`);
|
|
3134
3636
|
if (c === "<=" || c === "==") {
|
|
3135
|
-
let t = Y(e, s, "<=", l, i, n.M === void 0 ?
|
|
3637
|
+
let t = Y(e, s, "<=", l, i, n.M === void 0 ? et(s, l, f) : n.M, f);
|
|
3136
3638
|
m.push([new y(t.lhs, "<=", t.rhs, f), f]);
|
|
3137
3639
|
}
|
|
3138
3640
|
if (c === ">=" || c === "==") {
|
|
3139
|
-
let t = Y(e, s, ">=", l, i, n.M === void 0 ?
|
|
3641
|
+
let t = Y(e, s, ">=", l, i, n.M === void 0 ? tt(s, l, p) : n.M, p);
|
|
3140
3642
|
m.push([new y(t.lhs, ">=", t.rhs, p), p]);
|
|
3141
3643
|
}
|
|
3142
3644
|
for (let [e, n] of m) j(e, this.name, t, n);
|
|
@@ -3147,7 +3649,7 @@ var Ze = class {
|
|
|
3147
3649
|
}
|
|
3148
3650
|
toLpString() {
|
|
3149
3651
|
this.validateIntegrity();
|
|
3150
|
-
let { lpString: e } =
|
|
3652
|
+
let { lpString: e } = je({
|
|
3151
3653
|
name: this.name,
|
|
3152
3654
|
sense: this.sense,
|
|
3153
3655
|
objective: this.objectiveExpr,
|
|
@@ -3177,6 +3679,9 @@ var Ze = class {
|
|
|
3177
3679
|
let t = e.status, n = e.terminationStatus ?? t, r = e.values || {}, i = e.boolValues || {};
|
|
3178
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"));
|
|
3179
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
|
+
}
|
|
3180
3685
|
resolveSolverAndOptions(e, t) {
|
|
3181
3686
|
if (e && typeof e == "object" && "solve" in e && typeof e.solve == "function") {
|
|
3182
3687
|
let { solver: n, ...r } = t || {};
|
|
@@ -3195,16 +3700,16 @@ var Ze = class {
|
|
|
3195
3700
|
if (typeof e == "string") {
|
|
3196
3701
|
let { solver: n, ...r } = t || {};
|
|
3197
3702
|
return {
|
|
3198
|
-
activeSolver:
|
|
3703
|
+
activeSolver: G(e, r),
|
|
3199
3704
|
activeOptions: r
|
|
3200
3705
|
};
|
|
3201
3706
|
}
|
|
3202
3707
|
let { solver: n, ...r } = e || {};
|
|
3203
3708
|
return n ? {
|
|
3204
|
-
activeSolver:
|
|
3709
|
+
activeSolver: G(n, r),
|
|
3205
3710
|
activeOptions: r
|
|
3206
3711
|
} : {
|
|
3207
|
-
activeSolver: this.solver ||
|
|
3712
|
+
activeSolver: this.solver || G(),
|
|
3208
3713
|
activeOptions: r
|
|
3209
3714
|
};
|
|
3210
3715
|
}
|
|
@@ -3224,7 +3729,7 @@ var Ze = class {
|
|
|
3224
3729
|
let { activeSolver: i, activeOptions: a } = this.resolveSolverAndOptions(e, t);
|
|
3225
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.`);
|
|
3226
3731
|
let o, s = null;
|
|
3227
|
-
if (this.logicalConstraints.length > 0 && i.capabilities?.supportsSMT !== !0 ? (s =
|
|
3732
|
+
if (this.logicalConstraints.length > 0 && i.capabilities?.supportsSMT !== !0 ? (s = nt(this.variables, this.boolVars, this.constraints, this.logicalConstraints), o = {
|
|
3228
3733
|
name: this.name,
|
|
3229
3734
|
sense: this.sense,
|
|
3230
3735
|
objective: this._objectiveExpr,
|
|
@@ -3263,7 +3768,11 @@ var Ze = class {
|
|
|
3263
3768
|
if (this.values.clear(), u && l.values) {
|
|
3264
3769
|
for (let [e, t] of Object.entries(l.values)) if (typeof t == "number" && Number.isFinite(t)) {
|
|
3265
3770
|
let n = this.getVarByName(e), r = this.getBoolVarByName(e);
|
|
3266
|
-
|
|
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);
|
|
3267
3776
|
} else if (typeof t == "boolean") {
|
|
3268
3777
|
let n = t, r = this.getBoolVarByName(e);
|
|
3269
3778
|
r ? (r.value = n, f(p, r.name, +!!n), this.values.set(r.name, n)) : this.values.set(e, n);
|
|
@@ -3349,8 +3858,12 @@ var Ze = class {
|
|
|
3349
3858
|
if (e.values && e.status === "Sat") {
|
|
3350
3859
|
for (let [n, r] of Object.entries(e.values)) if (typeof r == "number") {
|
|
3351
3860
|
if (!Number.isFinite(r)) continue;
|
|
3352
|
-
let e = this.getVarByName(n),
|
|
3353
|
-
|
|
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));
|
|
3354
3867
|
} else if (typeof r == "boolean") {
|
|
3355
3868
|
let e = this.getBoolVarByName(n);
|
|
3356
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));
|
|
@@ -3364,7 +3877,7 @@ var Ze = class {
|
|
|
3364
3877
|
runTime: this.runTime
|
|
3365
3878
|
};
|
|
3366
3879
|
}
|
|
3367
|
-
let l = this.logicalConstraints.length > 0 || this.boolVars.length > 0 ?
|
|
3880
|
+
let l = this.logicalConstraints.length > 0 || this.boolVars.length > 0 ? nt(this.variables, this.boolVars, this.constraints, this.logicalConstraints) : {
|
|
3368
3881
|
variables: [...this.variables],
|
|
3369
3882
|
constraints: [...this.constraints],
|
|
3370
3883
|
boolVarToBinary: /* @__PURE__ */ new Map(),
|
|
@@ -3428,7 +3941,10 @@ var Ze = class {
|
|
|
3428
3941
|
if (S && g.values) {
|
|
3429
3942
|
for (let e of this.variables) {
|
|
3430
3943
|
let t = g.values[e.name];
|
|
3431
|
-
typeof t == "number" && Number.isFinite(t)
|
|
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
|
+
}
|
|
3432
3948
|
}
|
|
3433
3949
|
for (let e of this.boolVars) {
|
|
3434
3950
|
let t = l.boolVarToBinary.get(e), n = t ? g.values[t.name] : g.values[e.name];
|
|
@@ -3452,7 +3968,7 @@ var Ze = class {
|
|
|
3452
3968
|
};
|
|
3453
3969
|
}
|
|
3454
3970
|
validateSolution(e = {}) {
|
|
3455
|
-
return
|
|
3971
|
+
return Ze(this, e);
|
|
3456
3972
|
}
|
|
3457
3973
|
link(e) {
|
|
3458
3974
|
if (e instanceof S || typeof e == "object" && e && "quadTerms" in e) throw Error("Linking constraint cannot be a quadratic expression.");
|
|
@@ -3465,14 +3981,14 @@ var Ze = class {
|
|
|
3465
3981
|
return this._linkingConstraints ?? [];
|
|
3466
3982
|
}
|
|
3467
3983
|
async solveBenders(e) {
|
|
3468
|
-
let t = await
|
|
3984
|
+
let t = await ut({
|
|
3469
3985
|
master: this,
|
|
3470
3986
|
...e
|
|
3471
3987
|
});
|
|
3472
3988
|
return this.decomposition = t, t;
|
|
3473
3989
|
}
|
|
3474
3990
|
async solveColumnGeneration(e) {
|
|
3475
|
-
let t = await
|
|
3991
|
+
let t = await it({
|
|
3476
3992
|
master: this,
|
|
3477
3993
|
...e
|
|
3478
3994
|
});
|
|
@@ -3480,4 +3996,4 @@ var Ze = class {
|
|
|
3480
3996
|
}
|
|
3481
3997
|
};
|
|
3482
3998
|
//#endregion
|
|
3483
|
-
export { u as BoolExpr, f as BoolOp, d as BoolVar, y as Constraint,
|
|
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 };
|