@ohtaman/washi 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/README.ja.md +100 -107
  2. package/README.md +98 -105
  3. package/README.zh-CN.md +101 -108
  4. package/dist/browser/highs-worker.js +21 -3
  5. package/dist/browser/loader-CtaDHef_.js +273 -0
  6. package/dist/browser/solvers/glpk.js +433 -286
  7. package/dist/browser/solvers/glpk.min.js +1 -1
  8. package/dist/browser/solvers/z3.js +1002 -981
  9. package/dist/browser/solvers/z3.min.js +2 -2
  10. package/dist/browser/washi.js +2129 -676
  11. package/dist/browser/washi.min.js +4 -4
  12. package/dist/lib/highs-worker.js +21 -3
  13. package/dist/lib/loader-DmNC_UNk.js +279 -0
  14. package/dist/lib/registry-BEfvpZW3.js +951 -0
  15. package/dist/lib/solvers/glpk.js +201 -90
  16. package/dist/lib/solvers/z3.js +399 -259
  17. package/dist/lib/washi.js +1627 -988
  18. package/dist/types/index.d.ts +4 -4
  19. package/dist/types/index.d.ts.map +1 -1
  20. package/dist/types/modeler/big-m.d.ts +75 -0
  21. package/dist/types/modeler/big-m.d.ts.map +1 -0
  22. package/dist/types/modeler/boolean-expr.d.ts +103 -14
  23. package/dist/types/modeler/boolean-expr.d.ts.map +1 -1
  24. package/dist/types/modeler/constraint.d.ts +36 -9
  25. package/dist/types/modeler/constraint.d.ts.map +1 -1
  26. package/dist/types/modeler/expression.d.ts +113 -28
  27. package/dist/types/modeler/expression.d.ts.map +1 -1
  28. package/dist/types/modeler/index.d.ts +10 -6
  29. package/dist/types/modeler/index.d.ts.map +1 -1
  30. package/dist/types/modeler/lp-writer.d.ts +27 -2
  31. package/dist/types/modeler/lp-writer.d.ts.map +1 -1
  32. package/dist/types/modeler/model.d.ts +478 -131
  33. package/dist/types/modeler/model.d.ts.map +1 -1
  34. package/dist/types/modeler/objective.d.ts +59 -0
  35. package/dist/types/modeler/objective.d.ts.map +1 -0
  36. package/dist/types/modeler/parser.d.ts +34 -10
  37. package/dist/types/modeler/parser.d.ts.map +1 -1
  38. package/dist/types/modeler/quad-expr.d.ts +26 -7
  39. package/dist/types/modeler/quad-expr.d.ts.map +1 -1
  40. package/dist/types/modeler/solution-validator.d.ts +93 -0
  41. package/dist/types/modeler/solution-validator.d.ts.map +1 -0
  42. package/dist/types/modeler/solvers/glpk/solver.d.ts +26 -2
  43. package/dist/types/modeler/solvers/glpk/solver.d.ts.map +1 -1
  44. package/dist/types/modeler/solvers/highs/loader.d.ts +36 -11
  45. package/dist/types/modeler/solvers/highs/loader.d.ts.map +1 -1
  46. package/dist/types/modeler/solvers/highs/solver.d.ts +11 -4
  47. package/dist/types/modeler/solvers/highs/solver.d.ts.map +1 -1
  48. package/dist/types/modeler/solvers/highs/worker-client.d.ts.map +1 -1
  49. package/dist/types/modeler/solvers/mock.d.ts +14 -5
  50. package/dist/types/modeler/solvers/mock.d.ts.map +1 -1
  51. package/dist/types/modeler/solvers/types.d.ts +71 -11
  52. package/dist/types/modeler/solvers/types.d.ts.map +1 -1
  53. package/dist/types/modeler/solvers/z3/loader.d.ts +2 -3
  54. package/dist/types/modeler/solvers/z3/loader.d.ts.map +1 -1
  55. package/dist/types/modeler/solvers/z3/solver.d.ts +15 -5
  56. package/dist/types/modeler/solvers/z3/solver.d.ts.map +1 -1
  57. package/dist/types/modeler/types.d.ts +59 -1
  58. package/dist/types/modeler/types.d.ts.map +1 -1
  59. package/dist/types/modeler/validation.d.ts +56 -0
  60. package/dist/types/modeler/validation.d.ts.map +1 -0
  61. package/dist/types/modeler/variable.d.ts +48 -14
  62. package/dist/types/modeler/variable.d.ts.map +1 -1
  63. package/docs/examples/diet-sensitivity.md +90 -0
  64. package/docs/examples/ecommerce-coupons.md +106 -0
  65. package/docs/examples/index.md +53 -0
  66. package/docs/examples/knapsack.md +60 -0
  67. package/docs/examples/portfolio-qp.md +83 -0
  68. package/docs/examples/production.md +51 -0
  69. package/docs/examples/shift-scheduling.md +175 -0
  70. package/docs/examples/smt-security.md +74 -0
  71. package/docs/examples/transportation.md +90 -0
  72. package/docs/examples/unsat-core.md +64 -0
  73. package/docs/getting-started/ai-agents.md +267 -0
  74. package/docs/getting-started/cross-origin.md +87 -0
  75. package/docs/getting-started/index.md +116 -0
  76. package/docs/getting-started/runtimes.md +227 -0
  77. package/docs/guide/constraints.md +177 -0
  78. package/docs/guide/expressions.md +204 -0
  79. package/docs/guide/objectives.md +170 -0
  80. package/docs/guide/unsat-core.md +147 -0
  81. package/docs/guide/variables.md +188 -0
  82. package/docs/ja/getting-started/ai-agents.md +266 -0
  83. package/docs/solvers/custom-solver.md +525 -0
  84. package/docs/solvers/glpk.md +66 -0
  85. package/docs/solvers/highs.md +93 -0
  86. package/docs/solvers/index.md +42 -0
  87. package/docs/solvers/z3.md +78 -0
  88. package/docs/zh/getting-started/ai-agents.md +266 -0
  89. package/llms-full.txt +3249 -0
  90. package/llms.txt +197 -0
  91. package/package.json +18 -5
  92. package/skills/washi/SKILL.md +197 -0
  93. package/dist/browser/loader-CVt4CloI.js +0 -58
  94. package/dist/lib/async-mutex-Duo4jwzn.js +0 -195
  95. package/dist/lib/constraint-BRuB3ooC.js +0 -90
  96. package/dist/lib/loader-Dti0v9yC.js +0 -50
  97. package/dist/lib/registry-DksqCSjI.js +0 -32
package/dist/lib/washi.js CHANGED
@@ -1,531 +1,119 @@
1
- import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s, t as c } from "./constraint-BRuB3ooC.js";
2
- import { i as l, n as u, r as d, t as f } from "./registry-DksqCSjI.js";
3
- import { a as p, c as m, i as h, n as g, o as _, r as v, s as y, t as b } from "./loader-Dti0v9yC.js";
4
- import { createHighsWorker as ee } from "./highs-worker-factory.js";
1
+ import { A as e, C as t, D as n, E as r, M as i, N as a, O as o, S as s, T as c, _ as l, a as u, b as d, c as f, d as p, f as m, g as h, h as g, i as _, j as v, k as y, l as b, m as x, n as S, o as C, p as w, r as T, s as E, t as D, u as O, v as k, w as A, x as j, y as ee } from "./registry-BEfvpZW3.js";
2
+ import { a as M, c as N, i as P, n as F, o as I, r as L, s as R, t as te } from "./loader-DmNC_UNk.js";
3
+ import { createHighsWorker as ne } from "./highs-worker-factory.js";
5
4
  //#region \0rolldown/runtime.js
6
- var x = Object.defineProperty, te = Object.getOwnPropertyDescriptor, ne = Object.getOwnPropertyNames, re = Object.prototype.hasOwnProperty, S = (e, t) => {
5
+ var re = Object.defineProperty, ie = Object.getOwnPropertyDescriptor, ae = Object.getOwnPropertyNames, oe = Object.prototype.hasOwnProperty, se = (e, t) => {
7
6
  let n = {};
8
- for (var r in e) x(n, r, {
7
+ for (var r in e) re(n, r, {
9
8
  get: e[r],
10
9
  enumerable: !0
11
10
  });
12
- return t || x(n, Symbol.toStringTag, { value: "Module" }), n;
13
- }, C = (e, t, n, r) => {
14
- if (t && typeof t == "object" || typeof t == "function") for (var i = ne(t), a = 0, o = i.length, s; a < o; a++) s = i[a], !re.call(e, s) && s !== n && x(e, s, {
11
+ return t || re(n, Symbol.toStringTag, { value: "Module" }), n;
12
+ }, ce = (e, t, n, r) => {
13
+ if (t && typeof t == "object" || typeof t == "function") for (var i = ae(t), a = 0, o = i.length, s; a < o; a++) s = i[a], !oe.call(e, s) && s !== n && re(e, s, {
15
14
  get: ((e) => t[e]).bind(null, s),
16
- enumerable: !(r = te(t, s)) || r.enumerable
15
+ enumerable: !(r = ie(t, s)) || r.enumerable
17
16
  });
18
17
  return e;
19
- }, w = (e, t, n) => (C(e, t, "default"), n && C(n, t, "default"));
18
+ }, z = (e, t, n) => (ce(e, t, "default"), n && ce(n, t, "default"));
20
19
  //#endregion
21
20
  //#region src/modeler/types.ts
22
- function T(e) {
23
- return e && e.toLowerCase() === "maximize" ? "Maximize" : "Minimize";
21
+ function le(e) {
22
+ if (e === void 0) return "Minimize";
23
+ if (typeof e == "string") {
24
+ let t = e.toLowerCase();
25
+ if (t === "maximize") return "Maximize";
26
+ if (t === "minimize") return "Minimize";
27
+ }
28
+ throw Error(`Invalid optimization sense "${String(e)}": expected "Maximize", "Minimize", "maximize", or "minimize".`);
24
29
  }
25
30
  //#endregion
26
- //#region src/modeler/quad-expr.ts
27
- function E(e, t) {
28
- let n = e.id, r = t.id;
29
- return n <= r ? `${n}:${r}` : `${r}:${n}`;
30
- }
31
- var D = class e {
32
- linearTerms;
33
- quadTerms;
34
- constant;
35
- constructor(e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map(), n = 0) {
36
- this.linearTerms = new Map(e), this.quadTerms = /* @__PURE__ */ new Map();
37
- for (let [e, n] of t) this.quadTerms.set(e, { ...n });
38
- this.constant = n;
39
- }
40
- clone() {
41
- return new e(this.linearTerms, this.quadTerms, this.constant);
42
- }
43
- getQuadCoeff(e, t) {
44
- let n = E(e, t), r = this.quadTerms.get(n);
45
- return r ? r.coeff : 0;
46
- }
47
- add(t) {
48
- let n = this.clone();
49
- if (typeof t == "number") return n.constant += t, n;
50
- if (t instanceof e) {
51
- for (let [e, r] of t.quadTerms) {
52
- let t = n.quadTerms.get(e), i = (t ? t.coeff : 0) + r.coeff;
53
- Math.abs(i) < 1e-12 ? n.quadTerms.delete(e) : n.quadTerms.set(e, {
54
- var1: r.var1,
55
- var2: r.var2,
56
- coeff: i
57
- });
58
- }
59
- for (let [e, r] of t.linearTerms) {
60
- let t = (n.linearTerms.get(e) || 0) + r;
61
- Math.abs(t) < 1e-12 ? n.linearTerms.delete(e) : n.linearTerms.set(e, t);
62
- }
63
- return n.constant += t.constant, n;
64
- }
65
- if ("terms" in t && t.terms instanceof Map) {
66
- for (let [e, r] of t.terms) {
67
- let t = (n.linearTerms.get(e) || 0) + r;
68
- Math.abs(t) < 1e-12 ? n.linearTerms.delete(e) : n.linearTerms.set(e, t);
69
- }
70
- return n.constant += t.constant, n;
71
- }
72
- let r = t, i = (n.linearTerms.get(r) || 0) + 1;
73
- return Math.abs(i) < 1e-12 ? n.linearTerms.delete(r) : n.linearTerms.set(r, i), n;
74
- }
75
- sub(t) {
76
- return typeof t == "number" ? this.add(-t) : t instanceof e ? this.add(t.neg()) : ("terms" in t && t.terms instanceof Map, this.add(t.mul(-1)));
77
- }
78
- mul(t) {
79
- if (typeof t == "number") {
80
- let n = new e(/* @__PURE__ */ new Map(), /* @__PURE__ */ new Map(), this.constant * t);
81
- for (let [e, r] of this.linearTerms) {
82
- let i = r * t;
83
- Math.abs(i) >= 1e-12 && n.linearTerms.set(e, i);
84
- }
85
- for (let [e, r] of this.quadTerms) {
86
- let i = r.coeff * t;
87
- Math.abs(i) >= 1e-12 && n.quadTerms.set(e, {
88
- var1: r.var1,
89
- var2: r.var2,
90
- coeff: i
91
- });
92
- }
93
- return n;
94
- }
95
- if ("id" in t && "name" in t && !("terms" in t) && !("quadTerms" in t)) {
96
- if (this.quadTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
97
- let n = new e();
98
- Math.abs(this.constant) >= 1e-12 && n.linearTerms.set(t, this.constant);
99
- for (let [r, i] of this.linearTerms) n = n.add(e.fromProduct(r, t, i));
100
- return n;
101
- }
102
- let n = t, r = "quadTerms" in n ? n.quadTerms.size : 0, i = "quadTerms" in n ? n.linearTerms : n.terms;
103
- if (this.quadTerms.size > 0 && (r > 0 || i.size > 0) || r > 0 && this.linearTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
104
- if (r === 0 && i.size === 0) return this.mul(n.constant);
105
- if (this.quadTerms.size === 0 && this.linearTerms.size === 0) {
106
- let t = n.mul(this.constant);
107
- if (t instanceof e) return t;
108
- let r = new e();
109
- r.constant = t.constant;
110
- for (let [e, n] of t.terms) r.linearTerms.set(e, n);
111
- return r;
112
- }
113
- let a = new e();
114
- if (a.constant = this.constant * n.constant, Math.abs(n.constant) >= 1e-12) for (let [e, t] of this.linearTerms) a.linearTerms.set(e, (a.linearTerms.get(e) || 0) + t * n.constant);
115
- if (Math.abs(this.constant) >= 1e-12) for (let [e, t] of i) a.linearTerms.set(e, (a.linearTerms.get(e) || 0) + t * this.constant);
116
- for (let [t, n] of this.linearTerms) for (let [r, o] of i) a = a.add(e.fromProduct(t, r, n * o));
117
- return a;
118
- }
119
- div(e) {
120
- if (Math.abs(e) < 1e-12) throw Error("Division by zero in QuadExpr.div()");
121
- return this.mul(1 / e);
122
- }
123
- neg() {
124
- return this.mul(-1);
125
- }
126
- get value() {
127
- let e = this.constant;
128
- for (let [t, n] of this.linearTerms) {
129
- if (t.value === null) return null;
130
- e += n * t.value;
131
- }
132
- for (let t of this.quadTerms.values()) {
133
- if (t.var1.value === null || t.var2.value === null) return null;
134
- e += t.coeff * t.var1.value * t.var2.value;
135
- }
136
- return e;
137
- }
138
- getValue() {
139
- return this.value;
140
- }
141
- toString() {
142
- let e = [], t = !0;
143
- for (let n of this.quadTerms.values()) {
144
- let r = n.coeff, i = r >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(r), o = a === 1 ? "" : `${a} `;
145
- n.var1 === n.var2 ? e.push(`${i}${o}${n.var1.name}^2`) : e.push(`${i}${o}${n.var1.name} * ${n.var2.name}`), t = !1;
146
- }
147
- for (let [n, r] of this.linearTerms) {
148
- let i = r >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(r), o = a === 1 ? "" : `${a} `;
149
- e.push(`${i}${o}${n.name}`), t = !1;
150
- }
151
- if (this.constant !== 0 || e.length === 0) {
152
- let n = this.constant >= 0 ? t ? "" : "+ " : "- ";
153
- e.push(`${n}${Math.abs(this.constant)}`);
154
- }
155
- return e.join(" ") || "0";
156
- }
157
- static fromProduct(t, n, r = 1) {
158
- let i = new e(), a = E(t, n);
159
- return i.quadTerms.set(a, {
160
- var1: t.id <= n.id ? t : n,
161
- var2: t.id <= n.id ? n : t,
162
- coeff: r
163
- }), i;
164
- }
165
- }, O = class e {
166
- terms;
167
- constant;
168
- constructor(e = /* @__PURE__ */ new Map(), t = 0) {
169
- this.terms = new Map(e), this.constant = t;
170
- }
171
- clone() {
172
- return new e(this.terms, this.constant);
173
- }
174
- add(e) {
175
- if (e instanceof D) return e.add(this);
176
- let t = this.clone();
177
- if (typeof e == "number") t.constant += e;
178
- else if ("terms" in e) {
179
- for (let [n, r] of e.terms) {
180
- let e = (t.terms.get(n) || 0) + r;
181
- Math.abs(e) < 1e-12 ? t.terms.delete(n) : t.terms.set(n, e);
182
- }
183
- t.constant += e.constant;
184
- } else {
185
- let n = (t.terms.get(e) || 0) + 1;
186
- Math.abs(n) < 1e-12 ? t.terms.delete(e) : t.terms.set(e, n);
187
- }
188
- return t;
189
- }
190
- sub(e) {
191
- return e instanceof D ? e.neg().add(this) : typeof e == "number" ? this.add(-e) : ("terms" in e, this.add(e.mul(-1)));
192
- }
193
- mul(t) {
194
- if (typeof t == "number") {
195
- let n = new e(/* @__PURE__ */ new Map(), this.constant * t);
196
- for (let [e, r] of this.terms) {
197
- let i = r * t;
198
- Math.abs(i) >= 1e-12 && n.terms.set(e, i);
199
- }
200
- return n;
201
- }
202
- if (t instanceof M || typeof t == "object" && t && "id" in t && !("terms" in t) && !("quadTerms" in t)) {
203
- let e = t, n = new D();
204
- Math.abs(this.constant) >= 1e-12 && n.linearTerms.set(e, this.constant);
205
- for (let [t, r] of this.terms) n = n.add(D.fromProduct(t, e, r));
206
- return n;
207
- }
208
- if (t instanceof D) {
209
- if (t.quadTerms.size > 0 && this.terms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
210
- if (this.terms.size === 0) return t.mul(this.constant);
211
- let e = new D();
212
- if (e.constant = this.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [n, r] of this.terms) e.linearTerms.set(n, (e.linearTerms.get(n) || 0) + r * t.constant);
213
- if (Math.abs(this.constant) >= 1e-12) for (let [n, r] of t.linearTerms) e.linearTerms.set(n, (e.linearTerms.get(n) || 0) + r * this.constant);
214
- for (let [n, r] of this.terms) for (let [i, a] of t.linearTerms) e = e.add(D.fromProduct(n, i, r * a));
215
- return e;
216
- }
217
- if (this.terms.size === 0) return t.mul(this.constant);
218
- if (t.terms.size === 0) return this.mul(t.constant);
219
- let n = new D();
220
- if (n.constant = this.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [e, r] of this.terms) n.linearTerms.set(e, (n.linearTerms.get(e) || 0) + r * t.constant);
221
- if (Math.abs(this.constant) >= 1e-12) for (let [e, r] of t.terms) n.linearTerms.set(e, (n.linearTerms.get(e) || 0) + r * this.constant);
222
- for (let [e, r] of this.terms) for (let [i, a] of t.terms) n = n.add(D.fromProduct(e, i, r * a));
223
- return n;
224
- }
225
- div(e) {
226
- if (Math.abs(e) < 1e-12) throw Error("Division by zero in LinExpr.div()");
227
- return this.mul(1 / e);
228
- }
229
- neg() {
230
- return this.mul(-1);
231
- }
232
- get value() {
233
- let e = this.constant;
234
- for (let [t, n] of this.terms) {
235
- if (t.value === null) return null;
236
- e += n * t.value;
237
- }
238
- return e;
239
- }
240
- getValue() {
241
- return this.value;
242
- }
243
- le(e, t) {
244
- return this.toConstraint("<=", e, t);
245
- }
246
- lessThanOrEqual(e, t) {
247
- return this.le(e, t);
248
- }
249
- ge(e, t) {
250
- return this.toConstraint(">=", e, t);
251
- }
252
- greaterThanOrEqual(e, t) {
253
- return this.ge(e, t);
254
- }
255
- eq(e, t) {
256
- return this.toConstraint("==", e, t);
257
- }
258
- equalTo(e, t) {
259
- return this.eq(e, t);
260
- }
261
- toConstraint(t, n, r) {
262
- let i = this.clone(), a = 0;
263
- typeof n == "number" ? a = n : "terms" in n ? (i = i.sub(new e(n.terms, 0)), a = n.constant) : i = i.sub(n);
264
- let o = a - i.constant;
265
- return i.constant = 0, new c(i, t, o, r);
266
- }
267
- toString() {
268
- let e = [], t = !0;
269
- for (let [n, r] of this.terms) {
270
- let i = r >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(r), o = a === 1 ? "" : `${a} `;
271
- e.push(`${i}${o}${n.name}`), t = !1;
272
- }
273
- if (this.constant !== 0 || e.length === 0) {
274
- let n = this.constant >= 0 ? t ? "" : "+ " : "- ";
275
- e.push(`${n}${Math.abs(this.constant)}`);
276
- }
277
- return e.join(" ") || "0";
278
- }
279
- };
280
- function k(e, t) {
281
- let n = /* @__PURE__ */ new Map(), r = 0;
282
- function i(e) {
283
- if (e != null) {
284
- if (typeof e == "number") r += e;
285
- else if (typeof e == "object" && "terms" in e) {
286
- let t = e;
287
- for (let [e, r] of t.terms) {
288
- let t = n.get(e) || 0;
289
- n.set(e, t + r);
290
- }
291
- r += t.constant;
292
- } else {
293
- let t = e, r = n.get(t) || 0;
294
- n.set(t, r + 1);
295
- }
296
- }
297
- }
298
- if (typeof e == "number") {
299
- let n = e, r = t;
300
- for (let e = 0; e < n; e++) i(r(e, e));
301
- } else {
302
- let n = 0;
303
- for (let r of e) i(t ? t(r, n++) : r);
304
- }
305
- for (let [e, t] of n) Math.abs(t) < 1e-12 && n.delete(e);
306
- return new O(n, r);
307
- }
308
- function A(e, t) {
309
- let n = /* @__PURE__ */ new Map(), r = 0;
310
- function i(e) {
311
- return typeof e == "object" && !!e && typeof e.id == "number" && typeof e.name == "string" && typeof e.mul == "function" && typeof e.le == "function";
312
- }
313
- function a(e) {
314
- return i(e) || e instanceof O || e instanceof D;
315
- }
316
- function o(e, t) {
317
- if (typeof t == "number") r += e * t;
318
- else if (t instanceof O) {
319
- for (let [r, i] of t.terms) {
320
- let t = n.get(r) || 0;
321
- n.set(r, t + e * i);
322
- }
323
- r += e * t.constant;
324
- } else if (i(t)) {
325
- let r = t, i = n.get(r) || 0;
326
- n.set(r, i + e);
327
- } else throw Error("Cannot multiply number by non-variable/expression operand in dot().");
328
- }
329
- function s(e) {
330
- return typeof e == "object" && !!e && !Array.isArray(e) && !a(e);
331
- }
332
- function c(e, t, n = "") {
333
- if (e === void 0 || t === void 0 || e === null || t === null) throw Error(`Nullish or undefined operand encountered in dot() at '${n || "root"}'.`);
334
- if (typeof e == "number") {
335
- o(e, t);
336
- return;
337
- }
338
- if (typeof t == "number") {
339
- o(t, e);
340
- return;
341
- }
342
- if (Array.isArray(e) || Array.isArray(t)) {
343
- if (Array.isArray(e) && Array.isArray(t)) {
344
- if (e.length !== t.length) throw Error(`Array length mismatch in dot() at '${n || "root"}': received lengths ${e.length} and ${t.length}.`);
345
- for (let r = 0; r < e.length; r++) c(e[r], t[r], n ? `${n}[${r}]` : `[${r}]`);
346
- return;
347
- }
348
- let r = Array.isArray(e) ? e : t, i = Array.isArray(e) ? t : e;
349
- if (s(i)) {
350
- let a = Object.keys(i);
351
- if (a.length > 0 && a.every((e) => /^\d+$/.test(e))) {
352
- if (a.length !== r.length) throw Error(`Array length mismatch in dot() at '${n || "root"}': array has length ${r.length}, but object has ${a.length} indices.`);
353
- let o = [];
354
- for (let e = 0; e < r.length; e++) !(e in i) && !(String(e) in i) && o.push(e);
355
- if (o.length > 0) throw Error(`Key mismatch in dot() at '${n || "root"}': missing indices [${o.join(", ")}] in numeric record.`);
356
- for (let i = 0; i < r.length; i++) c(e[i], t[i], n ? `${n}[${i}]` : `[${i}]`);
357
- return;
358
- }
359
- throw Error(`Type mismatch in dot() at '${n || "root"}': one operand is an Array while the other is an Object with keys [${a.slice(0, 5).join(", ")}].`);
360
- }
361
- throw Error(`Type mismatch in dot() at '${n || "root"}': one operand is an Array while the other is not.`);
362
- }
363
- if (s(e) && s(t)) {
364
- let r = Object.keys(e), i = Object.keys(t), a = r.filter((e) => !(e in t)), o = i.filter((t) => !(t in e));
365
- if (a.length > 0 || o.length > 0) {
366
- let e = [];
367
- throw a.length > 0 && e.push(`missing in second operand: [${a.join(", ")}]`), o.length > 0 && e.push(`missing in first operand: [${o.join(", ")}]`), Error(`Key mismatch in dot() at '${n || "root"}': ${e.join("; ")}.`);
368
- }
369
- for (let i of r) c(e[i], t[i], n ? `${n}.${i}` : i);
370
- return;
371
- }
372
- throw Error(`Unsupported operand types in dot() at '${n || "root"}'.`);
373
- }
374
- c(e, t);
375
- for (let [e, t] of n) Math.abs(t) < 1e-12 && n.delete(e);
376
- return new O(n, r);
377
- }
378
- //#endregion
379
- //#region src/modeler/variable.ts
380
- var j = 0;
381
- function ie(e) {
382
- if (!e) return "Continuous";
383
- let t = e.toLowerCase();
384
- return t === "binary" || t === "bin" ? "Binary" : t === "integer" || t === "int" ? "Integer" : "Continuous";
385
- }
386
- var M = class e {
387
- id;
388
- name;
389
- type;
390
- lb;
391
- ub;
392
- value = null;
393
- reducedCost = null;
394
- constructor(e = {}) {
395
- this.id = ++j, this.name = e.name || `x_${this.id}`, this.type = ie(e.type), this.type === "Binary" ? (this.lb = 0, this.ub = 1) : (this.lb = e.lb === void 0 ? 0 : e.lb, this.ub = e.ub === void 0 ? Infinity : e.ub);
396
- }
397
- mul(t) {
398
- if (typeof t == "number") return new O(/* @__PURE__ */ new Map([[this, t]]), 0);
399
- if (t instanceof e) return D.fromProduct(this, t, 1);
400
- if (t instanceof D) {
401
- if (t.quadTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
402
- let e = new D();
403
- Math.abs(t.constant) >= 1e-12 && e.linearTerms.set(this, t.constant);
404
- for (let [n, r] of t.linearTerms) e = e.add(D.fromProduct(this, n, r));
405
- return e;
406
- }
407
- let n = new D();
408
- Math.abs(t.constant) >= 1e-12 && n.linearTerms.set(this, t.constant);
409
- for (let [e, r] of t.terms) {
410
- let t = D.fromProduct(this, e, r);
411
- n = n.add(t);
412
- }
413
- return n;
414
- }
415
- add(e) {
416
- return e instanceof D ? e.add(this) : new O(/* @__PURE__ */ new Map([[this, 1]]), 0).add(e);
417
- }
418
- sub(e) {
419
- return e instanceof D ? e.neg().add(this) : new O(/* @__PURE__ */ new Map([[this, 1]]), 0).sub(e);
420
- }
421
- neg() {
422
- return this.mul(-1);
423
- }
424
- le(e, t) {
425
- return new O(/* @__PURE__ */ new Map([[this, 1]]), 0).le(e, t);
426
- }
427
- lessThanOrEqual(e, t) {
428
- return this.le(e, t);
429
- }
430
- ge(e, t) {
431
- return new O(/* @__PURE__ */ new Map([[this, 1]]), 0).ge(e, t);
432
- }
433
- greaterThanOrEqual(e, t) {
434
- return this.ge(e, t);
435
- }
436
- eq(e, t) {
437
- return new O(/* @__PURE__ */ new Map([[this, 1]]), 0).eq(e, t);
438
- }
439
- equalTo(e, t) {
440
- return this.eq(e, t);
441
- }
442
- toString() {
443
- return this.name;
444
- }
445
- };
446
- //#endregion
447
31
  //#region src/modeler/parser.ts
448
- function ae(e) {
449
- let t = [], n = 0, r = e.length;
450
- for (; n < r;) {
451
- let i = e[n];
452
- if (/\s/.test(i)) {
453
- n++;
32
+ var ue = /^(?:[0-9]+(?:\.[0-9]+)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;
33
+ function de(e, t) {
34
+ let n = [], r = 0, i = e.length;
35
+ for (; r < i;) {
36
+ let a = e[r];
37
+ if (/\s/.test(a)) {
38
+ r++;
454
39
  continue;
455
40
  }
456
- if (i === "+") t.push({
41
+ if (a === "+") n.push({
457
42
  type: "PLUS",
458
43
  value: "+"
459
- }), n++;
460
- else if (i === "-") t.push({
44
+ }), r++;
45
+ else if (a === "-") n.push({
461
46
  type: "MINUS",
462
47
  value: "-"
463
- }), n++;
464
- else if (i === "*") n + 1 < r && e[n + 1] === "*" ? (t.push({
48
+ }), r++;
49
+ else if (a === "*") r + 1 < i && e[r + 1] === "*" ? (n.push({
465
50
  type: "CARET",
466
51
  value: "**"
467
- }), n += 2) : (t.push({
52
+ }), r += 2) : (n.push({
468
53
  type: "STAR",
469
54
  value: "*"
470
- }), n++);
471
- else if (i === "^") t.push({
55
+ }), r++);
56
+ else if (a === "^") n.push({
472
57
  type: "CARET",
473
58
  value: "^"
474
- }), n++;
475
- else if (i === "/") t.push({
59
+ }), r++;
60
+ else if (a === "/") n.push({
476
61
  type: "SLASH",
477
62
  value: "/"
478
- }), n++;
479
- else if (i === "(") t.push({
63
+ }), r++;
64
+ else if (a === "(") n.push({
480
65
  type: "LPAREN",
481
66
  value: "("
482
- }), n++;
483
- else if (i === ")") t.push({
67
+ }), r++;
68
+ else if (a === ")") n.push({
484
69
  type: "RPAREN",
485
70
  value: ")"
486
- }), n++;
487
- else if (i === "<" || i === ">" || i === "=") {
488
- let a = i;
489
- n + 1 < r && (e[n + 1] === "=" || e[n + 1] === "<" || e[n + 1] === ">") ? (a += e[n + 1], n += 2) : n++, t.push({
71
+ }), r++;
72
+ else if (a === "<" || a === ">" || a === "=") {
73
+ let t = a;
74
+ r + 1 < i && (e[r + 1] === "=" || e[r + 1] === "<" || e[r + 1] === ">") ? (t += e[r + 1], r += 2) : r++, n.push({
490
75
  type: "COMP",
491
- value: a
76
+ value: t
492
77
  });
493
- } else if (/[0-9.]/.test(i)) {
494
- let i = "";
495
- for (; n < r && /[0-9.]/.test(e[n]);) i += e[n], n++;
496
- t.push({
78
+ } else if (/[0-9.]/.test(a)) {
79
+ let t = r, a = "";
80
+ for (; r < i && /[0-9]/.test(e[r]);) a += e[r++];
81
+ if (r < i && e[r] === ".") for (a += e[r++]; r < i && /[0-9]/.test(e[r]);) a += e[r++];
82
+ if (r < i && (e[r] === "e" || e[r] === "E")) {
83
+ let t = r + 1 < i ? e[r + 1] : "";
84
+ if (!/[a-zA-Z_]/.test(t)) {
85
+ for (a += e[r++], r < i && (e[r] === "+" || e[r] === "-") && (a += e[r++]); r < i && /[0-9]/.test(e[r]);) a += e[r++];
86
+ for (; r < i && (e[r] === "." || e[r] === "e" || e[r] === "E" || /[0-9]/.test(e[r]));) a += e[r++];
87
+ }
88
+ } else for (; r < i && (e[r] === "." || /[0-9]/.test(e[r]));) a += e[r++];
89
+ if (!ue.test(a)) throw Error(`Invalid numeric literal '${a}' at position ${t} in: "${e}"`);
90
+ let o = Number(a);
91
+ if (!Number.isFinite(o)) throw Error(`Numeric literal '${a}' overflows finite floating-point range in: "${e}"`);
92
+ if (o === 0 && !/^[0.]+(?:[eE][+-]?\d+)?$/.test(a)) throw Error(`Numeric literal '${a}' underflows to zero at position ${t} in: "${e}"`);
93
+ n.push({
497
94
  type: "NUMBER",
498
- value: i
95
+ value: a,
96
+ numericValue: o
499
97
  });
500
- } else if (/[a-zA-Z_]/.test(i)) {
501
- let i = "";
502
- for (; n < r && /[a-zA-Z0-9_]/.test(e[n]);) i += e[n], n++;
503
- t.push({
98
+ } else if (/[a-zA-Z_]/.test(a)) {
99
+ let a = "";
100
+ for (; r < i && /[a-zA-Z0-9_]/.test(e[r]);) a += e[r], r++;
101
+ if (t && t.has(a)) {
102
+ let e = t.get(a);
103
+ n.push({
104
+ type: "NUMBER",
105
+ value: String(e),
106
+ numericValue: e
107
+ });
108
+ } else n.push({
504
109
  type: "IDENT",
505
- value: i
110
+ value: a
506
111
  });
507
- } else throw Error(`Unexpected character '${i}' at position ${n} in: "${e}"`);
112
+ } else throw Error(`Unexpected character '${a}' at position ${r} in: "${e}"`);
508
113
  }
509
- return t;
114
+ return n;
510
115
  }
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 {
116
+ var fe = class {
529
117
  tokens;
530
118
  pos = 0;
531
119
  resolver;
@@ -546,28 +134,20 @@ var ce = class {
546
134
  for (; this.pos < this.tokens.length;) {
547
135
  let t = this.peek();
548
136
  if (!t) break;
549
- if (t.type === "PLUS") this.consume(), e = oe(e, this.parseTerm());
550
- else if (t.type === "MINUS") this.consume(), e = se(e, this.parseTerm());
137
+ if (t.type === "PLUS") this.consume(), e = e.add(this.parseTerm());
138
+ else if (t.type === "MINUS") this.consume(), e = e.sub(this.parseTerm());
551
139
  else break;
552
140
  }
553
- return e instanceof D && e.quadTerms.size === 0 ? new O(e.linearTerms, e.constant) : e;
141
+ return e instanceof A && e.quadTerms.size === 0 ? new j(e.linearTerms, e.constant) : e;
554
142
  }
555
143
  parseTerm() {
556
144
  let e = this.parseFactor();
557
145
  for (; this.pos < this.tokens.length;) {
558
146
  let t = this.peek();
559
147
  if (!t) break;
560
- if (t.type === "STAR") {
561
- this.consume();
562
- let t = this.parseFactor();
563
- e = N(e, t);
564
- } else if (t.type === "SLASH") {
565
- this.consume();
566
- let t = this.parseFactor(), n = t instanceof D ? t.linearTerms : t.terms, r = t instanceof D ? t.quadTerms.size : 0;
567
- if (n.size > 0 || r > 0) throw Error("Cannot divide by variable in expression");
568
- if (Math.abs(t.constant) < 1e-12) throw Error("Division by zero in expression");
569
- e = e.div(t.constant);
570
- } else break;
148
+ if (t.type === "STAR") this.consume(), e = e.mul(this.parseFactor());
149
+ else if (t.type === "SLASH") this.consume(), e = e.div(this.parseFactor());
150
+ else break;
571
151
  }
572
152
  return e;
573
153
  }
@@ -579,20 +159,20 @@ var ce = class {
579
159
  let t;
580
160
  if (e.type === "NUMBER") {
581
161
  this.consume();
582
- let n = parseFloat(e.value);
162
+ let n = e.numericValue ?? Number(e.value);
583
163
  if (this.peek()?.type === "IDENT" || this.peek()?.type === "LPAREN") {
584
164
  let e;
585
165
  if (this.peek()?.type === "IDENT") {
586
166
  let t = this.consume(), n = this.resolve(t.value);
587
- e = n instanceof M || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new O(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
167
+ e = n instanceof b || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new j(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
588
168
  } else this.consume("LPAREN"), e = this.parseExpression(), this.consume("RPAREN");
589
169
  return this.applyPower(e).mul(n);
590
170
  }
591
- t = new O(/* @__PURE__ */ new Map(), n);
171
+ t = new j(/* @__PURE__ */ new Map(), n);
592
172
  } else if (e.type === "IDENT") {
593
173
  this.consume();
594
174
  let n = this.resolve(e.value);
595
- t = n instanceof M || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new O(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
175
+ t = n instanceof b || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new j(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
596
176
  } else if (e.type === "LPAREN") this.consume("LPAREN"), t = this.parseExpression(), this.consume("RPAREN");
597
177
  else throw Error(`Unexpected token '${e.value}' in expression`);
598
178
  return this.applyPower(t);
@@ -602,24 +182,27 @@ var ce = class {
602
182
  let t = [];
603
183
  for (; this.peek()?.type === "CARET";) {
604
184
  this.consume();
605
- let e = this.peek();
606
- if (!e || e.type !== "NUMBER") throw Error("Exponent must be a non-negative integer number");
607
- this.consume();
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);
185
+ let e = this.tokens[this.pos]?.type === "LPAREN" && this.tokens[this.pos + 1]?.type === "NUMBER" && this.tokens[this.pos + 2]?.type === "RPAREN";
186
+ e && this.consume("LPAREN");
187
+ let n = this.peek();
188
+ if (!n || n.type !== "NUMBER") throw Error("Exponent must be a non-negative integer number");
189
+ this.consume(), e && this.consume("RPAREN");
190
+ let r = n.numericValue ?? Number(n.value);
191
+ if (!Number.isInteger(r) || r < 0) throw Error("Exponent must be a non-negative integer");
192
+ t.push(r);
611
193
  }
612
194
  let n = t[t.length - 1];
613
195
  for (let e = t.length - 2; e >= 0; e--) n = t[e] ** +n;
614
196
  if (!Number.isFinite(n) || n < 0) throw Error("Exponent creates an invalid or out-of-range power");
615
- let r = e instanceof D, i = r ? e.quadTerms.size : 0, a = r ? e.linearTerms.size : e.terms.size;
197
+ let r = e instanceof A, i = r ? e.quadTerms.size : 0, a = r ? e.linearTerms.size : e.terms.size;
616
198
  if (i === 0 && a === 0) {
617
199
  let t = e.constant ** +n;
618
- return new O(/* @__PURE__ */ new Map(), t);
200
+ if (e.constant !== 0 && n > 0 && t === 0) throw Error("Constant exponentiation underflows to zero.");
201
+ return new j(/* @__PURE__ */ new Map(), t);
619
202
  }
620
- if (n === 0) return new O(/* @__PURE__ */ new Map(), 1);
203
+ if (n === 0) return new j(/* @__PURE__ */ new Map(), 1);
621
204
  if (n === 1) return e;
622
- if (n === 2) return N(e, e);
205
+ if (n === 2) return e.mul(e);
623
206
  throw Error(`Exponent ${n} creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)`);
624
207
  }
625
208
  getRemainingToken() {
@@ -631,143 +214,170 @@ var ce = class {
631
214
  return t;
632
215
  }
633
216
  };
634
- function P(e, t) {
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;
217
+ function B(e, t, n) {
218
+ let r = new fe(de(e, n), t), i = r.parseExpression(), a = r.getRemainingToken();
219
+ if (a) throw Error(`Unexpected token '${a.value}' after expression in "${e}"`);
220
+ return _e(i), i;
221
+ }
222
+ function pe(e, t) {
223
+ return B(e, t);
224
+ }
225
+ function me(e, t, n, r) {
226
+ let i = e.match(/(<=|>=|==|=<|=>|=)/);
227
+ if (!i) throw Error(`Constraint must contain a comparison operator (<=, >=, ==, =): "${e}"`);
228
+ let a = i[0], o = i.index, s = e.substring(0, o).trim(), c = e.substring(o + a.length).trim(), l;
229
+ if (a === "<=" || a === "=<") l = "<=";
230
+ else if (a === ">=" || a === "=>") l = ">=";
231
+ else if (a === "==" || a === "=") l = "==";
232
+ else throw Error(`Unsupported operator "${a}"`);
233
+ let u = B(s, t, r), d = B(c, t, r);
234
+ if (u instanceof A && u.quadTerms.size > 0 || d instanceof A && d.quadTerms.size > 0) throw Error("Quadratic constraints are not supported (only linear constraints are allowed in MILP/LP/QP)");
235
+ let f = u instanceof A ? new j(u.linearTerms, u.constant) : u, p = d instanceof A ? new j(d.linearTerms, d.constant) : d, m;
236
+ if (m = l === "<=" ? f.le(p, n) : l === ">=" ? f.ge(p, n) : f.eq(p, n), _e(m.lhs), !Number.isFinite(m.rhs)) throw Error(`Invalid non-finite right-hand side "${m.rhs}" in constraint.`);
237
+ return m;
238
+ }
239
+ function he(e, t, n) {
240
+ return me(e, t, n);
241
+ }
242
+ function ge(e) {
243
+ return e instanceof b || e instanceof j || e instanceof A ? !0 : typeof e != "object" || !e ? !1 : "terms" in e && e.terms instanceof Map || "quadTerms" in e && e.quadTerms instanceof Map || "id" in e && "name" in e && "lb" in e && "ub" in e && "type" in e && typeof e.mul == "function";
244
+ }
245
+ function _e(e) {
246
+ if ("constant" in e && !Number.isFinite(e.constant)) throw Error(`Invalid non-finite constant "${e.constant}" in expression.`);
247
+ if ("terms" in e && e.terms instanceof Map) {
248
+ for (let [, t] of e.terms) if (!Number.isFinite(t)) throw Error(`Invalid non-finite coefficient "${t}" in expression.`);
249
+ }
250
+ if ("linearTerms" in e && e.linearTerms instanceof Map) {
251
+ for (let [, t] of e.linearTerms) if (!Number.isFinite(t)) throw Error(`Invalid non-finite coefficient "${t}" in expression.`);
252
+ }
253
+ if ("quadTerms" in e && e.quadTerms instanceof Map) {
254
+ for (let [, t] of e.quadTerms) if (!Number.isFinite(t.coeff)) throw Error(`Invalid non-finite quadratic coefficient "${t.coeff}" in expression.`);
255
+ }
638
256
  }
639
- function F(e, t, n) {
640
- let r = e.match(/(<=|>=|==|=<|=>|=)/);
641
- if (!r) throw Error(`Constraint must contain a comparison operator (<=, >=, ==, =): "${e}"`);
642
- let i = r[0], a = r.index, o = e.substring(0, a).trim(), s = e.substring(a + i.length).trim(), c;
643
- if (i === "<=" || i === "=<") c = "<=";
644
- else if (i === ">=" || i === "=>") c = ">=";
645
- else if (i === "==" || i === "=") c = "==";
646
- else throw Error(`Unsupported operator "${i}"`);
647
- let l = P(o, t), u = P(s, t);
648
- if (l instanceof D && l.quadTerms.size > 0 || u instanceof D && u.quadTerms.size > 0) throw Error("Quadratic constraints are not supported (only linear constraints are allowed in MILP/LP/QP)");
649
- let d = l instanceof D ? new O(l.linearTerms, l.constant) : l, f = u instanceof D ? new O(u.linearTerms, u.constant) : u;
650
- return c === "<=" ? d.le(f, n) : c === ">=" ? d.ge(f, n) : d.eq(f, n);
257
+ function ve(e) {
258
+ return e instanceof c || typeof e == "object" && !!e && "sense" in e && "lhs" in e && "rhs" in e;
651
259
  }
652
- function I(e, t) {
653
- let n = /* @__PURE__ */ new Map(), r = "";
654
- for (let i = 0; i < e.length; i++) if (r += e[i], i < t.length) {
260
+ function ye(e, t) {
261
+ let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), i = e.join(""), a = "__washi_";
262
+ for (; i.includes(a);) a += "_";
263
+ let o = "";
264
+ for (let i = 0; i < e.length; i++) if (o += e[i], i < t.length) {
655
265
  let e = t[i];
656
- if (typeof e == "number") r += `(${e})`;
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}__`;
659
- n.set(t, e), r += t;
660
- }
266
+ if (typeof e == "number") {
267
+ if (!Number.isFinite(e)) throw Error(`Invalid numeric value "${e}" in template expression: interpolated numbers must be finite.`);
268
+ let t = `${a}num_${i}__`;
269
+ r.set(t, e), o += `(${t})`;
270
+ } else if (ve(e)) throw Error("Cannot interpolate a constraint comparison (<=, >=, ==) inside a template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
271
+ else if (ge(e)) {
272
+ _e(e);
273
+ let t = `${a}ph_${i}__`;
274
+ n.set(t, e), o += ` ${t} `;
275
+ } else throw Error("Unsupported interpolation value in template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
661
276
  }
662
277
  return {
663
- fullText: r,
664
- resolver: (e) => n.get(e)
278
+ fullText: o,
279
+ resolver: (e) => n.get(e),
280
+ numberMap: r
665
281
  };
666
282
  }
667
- function L(e, ...t) {
668
- let { fullText: n, resolver: r } = I(e, t);
669
- return F(n, r);
670
- }
671
- function R(e, ...t) {
672
- let { fullText: n, resolver: r } = I(e, t);
673
- return /(<=|>=|==|=<|=>|=)/.test(n) ? F(n, r) : P(n, r);
283
+ function be(e, ...t) {
284
+ let { fullText: n, resolver: r, numberMap: i } = ye(e, t);
285
+ return /(<=|>=|==|=<|=>|=)/.test(n) ? me(n, r, void 0, i) : B(n, r, i);
674
286
  }
675
287
  //#endregion
676
- //#region src/modeler/lp-writer.ts
677
- function z(e, t, n) {
678
- let r = e.replace(/[^a-zA-Z0-9_]/g, "_");
679
- return /^[0-9]/.test(r) && (r = `${t}_${r}`), (!r || r.length === 0) && (r = `${t}_${n}`), r;
288
+ //#region src/modeler/solvers/highs/worker-client.ts
289
+ var V = null, xe = 0, H = /* @__PURE__ */ new Map();
290
+ function Se(e, t) {
291
+ return e ? {
292
+ Status: "Interrupted",
293
+ StatusCode: 17,
294
+ HasPrimalSolution: !0,
295
+ IsMip: !0,
296
+ ObjectiveValue: e.objectiveValue,
297
+ ObjectiveOffsetApplied: !0,
298
+ ...t?.objectiveBound === void 0 ? e.mipDualBound === void 0 ? {} : { MipDualBound: e.mipDualBound } : { MipDualBound: t.objectiveBound },
299
+ ...t?.relGap === void 0 ? e.mipGap === void 0 ? {} : { MipGap: e.mipGap } : { MipGap: t.relGap },
300
+ Columns: e.columns,
301
+ Rows: []
302
+ } : {
303
+ Status: "Interrupted",
304
+ StatusCode: 17,
305
+ HasPrimalSolution: !1,
306
+ ObjectiveValue: NaN,
307
+ ObjectiveOffsetApplied: !0,
308
+ ...t?.objectiveBound === void 0 ? {} : { MipDualBound: t.objectiveBound },
309
+ ...t?.relGap === void 0 ? {} : { MipGap: t.relGap },
310
+ Columns: {},
311
+ Rows: []
312
+ };
680
313
  }
681
- function B(e) {
682
- let { sense: t, objective: n, constraints: r, variables: i } = e, a = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
683
- for (let e of i) {
684
- let t = z(e.name, "x", e.id), n = t, r = 1;
685
- for (; c.has(n);) n = `${t}_${r++}`;
686
- c.add(n), o.set(e, n), a.set(n, e);
687
- }
688
- let l = /* @__PURE__ */ new Set(), u = /* @__PURE__ */ new Map();
689
- for (let e of r) {
690
- let t = z(e.name, "c", e.id), n = t, r = 1;
691
- for (; l.has(n);) n = `${t}_${r++}`;
692
- l.add(n), u.set(e, n), s.set(n, e);
693
- }
694
- let d = [];
695
- d.push(t && t.toLowerCase() === "maximize" ? "Maximize" : "Minimize");
696
- let f = [], p = !0, m = n instanceof D ? n.linearTerms : n.terms;
697
- if (m) for (let [e, t] of m) {
698
- if (Math.abs(t) < 1e-12) continue;
699
- let n = o.get(e), r = t >= 0 ? p ? "" : "+ " : "- ", i = Math.abs(t), a = i === 1 ? "" : `${i} `;
700
- f.push(`${r}${a}${n}`), p = !1;
701
- }
702
- if (n instanceof D && n.quadTerms.size > 0) {
703
- let e = [], t = !0;
704
- for (let r of n.quadTerms.values()) {
705
- if (Math.abs(r.coeff) < 1e-12) continue;
706
- let n = 2 * r.coeff, i = n >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(n), s = a === 1 ? "" : `${a} `, c = o.get(r.var1), l = o.get(r.var2);
707
- r.var1 === r.var2 ? e.push(`${i}${s}${c} ^ 2`) : e.push(`${i}${s}${c} * ${l}`), t = !1;
708
- }
709
- if (e.length > 0) {
710
- let t = `[ ${e.join(" ")} ] / 2`;
711
- f.length > 0 ? f.push("+", t) : f.push(t);
314
+ function U(e) {
315
+ let t = H.values().next().value;
316
+ if (t && !t.dispatched) {
317
+ t.dispatched = !0;
318
+ try {
319
+ e.postMessage({
320
+ type: "SOLVE",
321
+ id: t.id,
322
+ lpString: t.lpString,
323
+ options: t.workerOptions,
324
+ ...t.reportProgress ? { reportProgress: !0 } : {}
325
+ });
326
+ } catch (n) {
327
+ H.delete(t.id), t.cleanupAbort?.(), t.reject(n), U(e);
712
328
  }
713
329
  }
714
- let h = f.length > 0 ? f.join(" ") : "0";
715
- d.push(` obj: ${h}`), d.push("Subject To");
716
- for (let e of r) {
717
- let t = u.get(e), n = [], r = !0;
718
- for (let [t, i] of e.lhs.terms) {
719
- if (Math.abs(i) < 1e-12) continue;
720
- let e = o.get(t), a = i >= 0 ? r ? "" : "+ " : "- ", s = Math.abs(i), c = s === 1 ? "" : `${s} `;
721
- n.push(`${a}${c}${e}`), r = !1;
722
- }
723
- let i = n.length > 0 ? n.join(" ") : "0", a = e.sense === "==" ? "=" : e.sense;
724
- d.push(` ${t}: ${i} ${a} ${e.rhs}`);
725
- }
726
- d.push("Bounds");
727
- let g = [], _ = [];
728
- for (let e of i) {
729
- let t = o.get(e);
730
- if (e.type === "Binary") {
731
- _.push(t);
732
- continue;
330
+ }
331
+ function Ce() {
332
+ let e = V;
333
+ e && (V = null, e.terminate());
334
+ for (let e of H.values()) e.dispatched = !1;
335
+ if (H.size > 0) {
336
+ let e = we();
337
+ if (e) U(e);
338
+ else {
339
+ let e = /* @__PURE__ */ Error("[WaSHI] Failed to recreate HiGHS Worker after interruption.");
340
+ for (let t of Array.from(H.values())) H.delete(t.id), t.cleanupAbort?.(), t.reject(e);
733
341
  }
734
- e.type === "Integer" && g.push(t);
735
- let n = e.lb === -Infinity, r = e.ub === Infinity;
736
- n && r ? d.push(` ${t} free`) : n && !r ? d.push(` -infinity <= ${t} <= ${e.ub}`) : !n && r ? e.lb !== 0 && d.push(` ${t} >= ${e.lb}`) : d.push(` ${e.lb} <= ${t} <= ${e.ub}`);
737
- }
738
- if (g.length > 0) {
739
- d.push("Generals");
740
- for (let e = 0; e < g.length; e += 10) d.push(" " + g.slice(e, e + 10).join(" "));
741
- }
742
- if (_.length > 0) {
743
- d.push("Binary");
744
- for (let e = 0; e < _.length; e += 10) d.push(" " + _.slice(e, e + 10).join(" "));
745
- }
746
- return d.push("End"), {
747
- lpString: d.join("\n") + "\n",
748
- nameToVar: a,
749
- nameToConstraint: s
750
- };
342
+ }
751
343
  }
752
- //#endregion
753
- //#region src/modeler/solvers/highs/worker-client.ts
754
- var V = null, le = 0, H = /* @__PURE__ */ new Map();
755
- function ue() {
344
+ function we() {
756
345
  if (typeof window > "u" || typeof Worker > "u") return null;
757
346
  if (!V) try {
758
- V = ee();
347
+ V = ne();
759
348
  let e = V;
760
- V.onmessage = (e) => {
761
- let { type: t, id: n, result: r, runTime: i, error: a } = e.data, o = H.get(n);
762
- o && (H.delete(n), t === "SOLVE_SUCCESS" ? o.resolve({
763
- result: r,
764
- runTime: i
765
- }) : o.reject(Error(a || "Worker solve failed")));
349
+ V.onmessage = (t) => {
350
+ let { type: n, id: r, result: i, runTime: a, error: o, progress: s, incumbent: c } = t.data, l = H.get(r);
351
+ if (l) {
352
+ if (n === "SOLVE_PROGRESS") {
353
+ if (s) {
354
+ l.lastProgress = s;
355
+ try {
356
+ l.onProgress?.(s);
357
+ } catch (e) {
358
+ let t = H.get(r);
359
+ if (t) {
360
+ let n = H.keys().next().value;
361
+ H.delete(r), t.cleanupAbort?.(), n === r && Ce(), t.reject(e);
362
+ }
363
+ }
364
+ }
365
+ return;
366
+ }
367
+ if (n === "SOLVE_INCUMBENT") {
368
+ c && (l.lastIncumbent = c);
369
+ return;
370
+ }
371
+ H.delete(r), l.cleanupAbort?.(), n === "SOLVE_SUCCESS" ? l.resolve({
372
+ result: i,
373
+ runTime: a
374
+ }) : l.reject(Error(o || "Worker solve failed")), V === e && U(e);
375
+ }
766
376
  };
767
377
  let t = (t) => {
768
378
  if (V === e) {
769
379
  V = null, e.terminate();
770
- for (let e of H.values()) e.reject(t);
380
+ for (let e of H.values()) e.cleanupAbort?.(), e.reject(t);
771
381
  H.clear();
772
382
  }
773
383
  };
@@ -777,47 +387,97 @@ function ue() {
777
387
  }
778
388
  return V;
779
389
  }
780
- async function U(e, t = {}) {
781
- let n = await _(t.wasmUrl), r = t.useWorker ?? typeof window < "u" ? ue() : null;
782
- if (!r) return m(e, t);
783
- let i = {
784
- ...t,
785
- wasmUrl: n
786
- }, a = `req_${++le}`;
390
+ async function W(e, t = {}) {
391
+ if (t.signal?.aborted) return {
392
+ result: Se(),
393
+ runTime: 0
394
+ };
395
+ let n = await I(t.wasmUrl);
396
+ if (t.signal?.aborted) return {
397
+ result: Se(),
398
+ runTime: 0
399
+ };
400
+ let r = t.useWorker ?? typeof window < "u" ? we() : null;
401
+ if (!r) return N(e, t);
402
+ let { signal: i, onProgress: a, ...o } = t, s = {};
403
+ for (let [e, t] of Object.entries(o)) typeof t != "function" && (s[e] = t);
404
+ s.wasmUrl = n;
405
+ let c = !!(a || i), l = `req_${++xe}`, u = performance.now();
787
406
  return new Promise((t, n) => {
788
- H.set(a, {
407
+ let o = {
408
+ id: l,
409
+ lpString: e,
410
+ workerOptions: s,
411
+ reportProgress: c,
412
+ startTime: u,
413
+ onProgress: a,
789
414
  resolve: t,
790
415
  reject: n
791
- });
792
- try {
793
- r.postMessage({
794
- type: "SOLVE",
795
- id: a,
796
- lpString: e,
797
- options: i
798
- });
799
- } catch (e) {
800
- H.delete(a), n(e);
416
+ };
417
+ if (i) {
418
+ let e = () => {
419
+ let e = H.get(l);
420
+ if (!e) return;
421
+ let t = H.keys().next().value;
422
+ H.delete(l), e.cleanupAbort?.(), t === l && Ce();
423
+ let n = (performance.now() - e.startTime) / 1e3;
424
+ e.resolve({
425
+ result: Se(e.lastIncumbent, e.lastProgress),
426
+ runTime: n
427
+ });
428
+ };
429
+ i.addEventListener("abort", e, { once: !0 }), o.cleanupAbort = () => i.removeEventListener("abort", e);
801
430
  }
431
+ H.set(l, o), U(r);
802
432
  });
803
433
  }
804
434
  //#endregion
805
435
  //#region src/modeler/solvers/highs/solver.ts
806
- function W(e) {
436
+ function G(e, t) {
437
+ if (typeof t == "number") switch (t) {
438
+ case 0: return "NotSolved";
439
+ case 1:
440
+ case 2:
441
+ case 3:
442
+ case 4:
443
+ case 5: return "Error";
444
+ case 6: return "Unknown";
445
+ case 7: return "Optimal";
446
+ case 8: return "Infeasible";
447
+ case 9: return "InfeasibleOrUnbounded";
448
+ case 10: return "Unbounded";
449
+ case 11: return "ObjectiveBound";
450
+ case 12: return "ObjectiveTarget";
451
+ case 13: return "TimeLimit";
452
+ case 14: return "IterationLimit";
453
+ case 15: return "Unknown";
454
+ case 16: return "SolutionLimit";
455
+ case 17: return "Interrupted";
456
+ case 18: return "MemoryLimit";
457
+ }
807
458
  if (typeof e != "string") return "Unknown";
808
- let t = e.trim();
809
- if (!t) return "Unknown";
810
- switch (t) {
459
+ let n = e.trim();
460
+ if (!n) return "Unknown";
461
+ switch (n) {
811
462
  case "Optimal": return "Optimal";
812
463
  case "Infeasible": return "Infeasible";
813
464
  case "Unbounded": return "Unbounded";
814
- case "Primal infeasible or unbounded": return "Unknown";
465
+ case "Primal infeasible or unbounded":
466
+ case "InfeasibleOrUnbounded": return "InfeasibleOrUnbounded";
815
467
  case "Time limit reached":
816
468
  case "TimeLimit": return "TimeLimit";
817
469
  case "Iteration limit reached":
818
470
  case "IterationLimit": return "IterationLimit";
471
+ case "Solution limit reached":
472
+ case "SolutionLimit": return "SolutionLimit";
473
+ case "Memory limit reached":
474
+ case "MemoryLimit": return "MemoryLimit";
819
475
  case "Bound on objective reached":
476
+ case "ObjectiveBound": return "ObjectiveBound";
820
477
  case "Target for objective reached":
478
+ case "ObjectiveTarget": return "ObjectiveTarget";
479
+ case "Interrupted":
480
+ case "User interrupt": return "Interrupted";
821
481
  case "Feasible": return "Feasible";
822
482
  case "Not Set": return "NotSolved";
823
483
  case "Load error":
@@ -829,13 +489,32 @@ function W(e) {
829
489
  case "Empty":
830
490
  case "Unknown": return "Unknown";
831
491
  }
832
- let n = t.toLowerCase();
833
- return n.includes("infeasible") && n.includes("unbounded") ? "Unknown" : n.includes("infeasible") ? "Infeasible" : n.includes("unbounded") ? "Unbounded" : n.includes("time limit") || n.includes("timelimit") ? "TimeLimit" : n.includes("iteration limit") || n.includes("iterationlimit") ? "IterationLimit" : n.includes("error") ? "Error" : n === "optimal" ? "Optimal" : "Unknown";
492
+ let r = n.toLowerCase();
493
+ return r.includes("infeasible") && r.includes("unbounded") ? "InfeasibleOrUnbounded" : r.includes("infeasible") ? "Infeasible" : r.includes("unbounded") ? "Unbounded" : r.includes("time limit") || r.includes("timelimit") ? "TimeLimit" : r.includes("iteration limit") || r.includes("iterationlimit") ? "IterationLimit" : r.includes("solution limit") || r.includes("solutionlimit") ? "SolutionLimit" : r.includes("memory limit") || r.includes("memorylimit") ? "MemoryLimit" : r.includes("bound on objective") ? "ObjectiveBound" : r.includes("target for objective") ? "ObjectiveTarget" : r.includes("interrupt") ? "Interrupted" : r.includes("error") ? "Error" : r === "optimal" ? "Optimal" : "Unknown";
834
494
  }
835
- var G = class e {
495
+ function K(e, t, n) {
496
+ switch (G(e, t)) {
497
+ case "Optimal": return "Optimal";
498
+ case "Infeasible": return "Infeasible";
499
+ case "Unbounded": return "Unbounded";
500
+ case "TimeLimit": return "TimeLimit";
501
+ case "IterationLimit": return "IterationLimit";
502
+ case "Feasible": return "Feasible";
503
+ case "ObjectiveBound":
504
+ case "ObjectiveTarget":
505
+ case "SolutionLimit": return n === !1 ? "Unknown" : "Feasible";
506
+ case "MemoryLimit":
507
+ case "Interrupted": return n ? "Feasible" : "Unknown";
508
+ case "NotSolved": return "NotSolved";
509
+ case "Error": return "Error";
510
+ default: return "Unknown";
511
+ }
512
+ }
513
+ var q = class e {
836
514
  static capabilities = {
837
515
  supportsMIP: !0,
838
- supportsQP: !0
516
+ supportsQP: !0,
517
+ supportsWarmStart: !0
839
518
  };
840
519
  name = "HiGHS";
841
520
  version = "1.15.3";
@@ -844,184 +523,816 @@ var G = class e {
844
523
  constructor(e = {}) {
845
524
  this.options = e;
846
525
  }
847
- async solve(e, t, n = {}) {
848
- let r = {
526
+ async solve(e, t = {}, n = {}) {
527
+ let r = E(t), i = r ? n : t, a = {
849
528
  ...this.options,
850
- ...n
851
- }, { lpString: i, nameToVar: a, nameToConstraint: o } = t, { result: s, runTime: c } = await U(i, r), l = W(s?.Status);
852
- if (l === "Infeasible" || l === "Unbounded") return {
853
- status: l,
529
+ ...i
530
+ }, o = e.objective.constant || 0;
531
+ for (let t of e.variables) d(t);
532
+ let { lpString: s, nameToVar: c, nameToConstraint: l } = r ? t : C(e), u = Object.create(null), p = !1, m = /* @__PURE__ */ new Set();
533
+ for (let [e, t] of c.entries()) {
534
+ m.add(t);
535
+ let n = w(t);
536
+ n !== void 0 && (u[e] = n, p = !0);
537
+ }
538
+ for (let t = 0; t < e.variables.length; t++) {
539
+ let n = e.variables[t];
540
+ if (!m.has(n)) {
541
+ let e = w(n);
542
+ if (e !== void 0) {
543
+ let r = f(n.name, "x", t);
544
+ Object.prototype.hasOwnProperty.call(u, r) || (u[r] = e, p = !0);
545
+ }
546
+ }
547
+ }
548
+ let h = a;
549
+ (o !== 0 || p || h.initialValues !== void 0) && (h = {
550
+ ...h,
551
+ ...o === 0 ? {} : { objectiveOffset: o },
552
+ initialValues: p ? u : void 0
553
+ });
554
+ let { result: g, runTime: _ } = await W(s, h), v = g?.ObjectiveOffsetApplied ? 0 : o, y = G(g?.Status, g?.StatusCode), b = typeof g?.IsMip == "boolean" ? g.IsMip : e.variables.some((e) => e.type === "Integer" || e.type === "Binary"), x;
555
+ if (typeof g?.HasPrimalSolution == "boolean") x = g.HasPrimalSolution;
556
+ else {
557
+ let e = g?.Columns ? Object.values(g.Columns) : [], t = e.length > 0 && e.some((e) => typeof e?.Primal == "number" && Number.isFinite(e.Primal)), n = typeof g?.ObjectiveValue == "number" && Number.isFinite(g.ObjectiveValue);
558
+ x = y === "Infeasible" || y === "Unbounded" || y === "InfeasibleOrUnbounded" || y === "Error" || y === "NotSolved" ? !1 : y === "Optimal" || y === "Feasible" ? n || t : n && (e.length === 0 || t);
559
+ }
560
+ let S = K(g?.Status, g?.StatusCode, x), T = null;
561
+ x && typeof g?.ObjectiveValue == "number" && Number.isFinite(g.ObjectiveValue) && (T = g.ObjectiveValue + v);
562
+ let D, O, k;
563
+ if (typeof g?.MipDualBound == "number" && Number.isFinite(g.MipDualBound) ? D = g.MipDualBound + v : !b && y === "Optimal" && T !== null && (D = T), T !== null && D !== void 0 && Number.isFinite(D) && (k = Math.abs(T - D)), v !== 0 && b && T !== null && D !== void 0 && k !== void 0) {
564
+ if (k === 0) O = 0;
565
+ else if (Math.abs(T) > 0) {
566
+ let e = k / Math.abs(T);
567
+ O = Number.isFinite(e) ? e : void 0;
568
+ } else O = void 0;
569
+ } else typeof g?.MipGap == "number" && Number.isFinite(g.MipGap) ? O = g.MipGap : b && y === "Optimal" && x && (k === void 0 || k === 0) && (O = 0);
570
+ if (!x) return {
571
+ status: S,
572
+ terminationStatus: y,
573
+ hasPrimalSolution: !1,
854
574
  objectiveValue: null,
575
+ ...D === void 0 ? {} : { objectiveBound: D },
576
+ ...O === void 0 ? {} : {
577
+ relGap: O,
578
+ mipGap: O
579
+ },
580
+ ...k === void 0 ? {} : { absGap: k },
855
581
  values: {},
856
582
  reducedCosts: {},
857
583
  duals: {},
858
584
  slacks: {},
859
- runTime: c,
860
- raw: s
585
+ runTime: _,
586
+ raw: g
861
587
  };
862
- let u = s.ObjectiveValue, d = typeof u == "number" ? u + e.objective.constant : null, f = {}, p = {}, m = {}, h = {};
863
- if (s.Columns) for (let [e, t] of Object.entries(s.Columns)) {
864
- let n = a.get(e);
588
+ let A = (e, t, n) => {
589
+ Object.defineProperty(e, t, {
590
+ value: n,
591
+ enumerable: !0,
592
+ writable: !0,
593
+ configurable: !0
594
+ });
595
+ }, j = {}, ee = {}, M = {}, N = {};
596
+ if (g.Columns) for (let [e, t] of Object.entries(g.Columns)) {
597
+ let n = c.get(e);
865
598
  if (n) {
866
- let e = Math.abs(t.Primal) < 1e-9 ? 0 : t.Primal;
867
- f[n.name] = e, t.Dual !== void 0 && (m[n.name] = Math.abs(t.Dual) < 1e-9 ? 0 : t.Dual);
599
+ if (typeof t.Primal == "number" && Number.isFinite(t.Primal)) {
600
+ let e = Math.abs(t.Primal) < 1e-9 ? 0 : t.Primal;
601
+ A(j, n.name, e);
602
+ }
603
+ typeof t.Dual == "number" && Number.isFinite(t.Dual) && A(M, n.name, Math.abs(t.Dual) < 1e-9 ? 0 : t.Dual);
868
604
  }
869
605
  }
870
- if (s.Rows) {
871
- let e = Array.isArray(s.Rows) ? s.Rows : Object.values(s.Rows);
606
+ if (g.Rows) {
607
+ let e = Array.isArray(g.Rows) ? g.Rows : Object.values(g.Rows);
872
608
  for (let t of e) {
873
- let e = t.Name, n = o.get(e);
874
- if (n && (t.Dual !== void 0 && (p[n.name] = Math.abs(t.Dual) < 1e-9 ? 0 : t.Dual), t.Primal !== void 0)) {
609
+ let e = t.Name, n = e ? l.get(e) : void 0;
610
+ if (n && (typeof t.Dual == "number" && Number.isFinite(t.Dual) && A(ee, n.name, Math.abs(t.Dual) < 1e-9 ? 0 : t.Dual), typeof t.Primal == "number" && Number.isFinite(t.Primal))) {
875
611
  let e = n.rhs - t.Primal;
876
- h[n.name] = Math.abs(e) < 1e-9 ? 0 : e;
612
+ A(N, n.name, Math.abs(e) < 1e-9 ? 0 : e);
877
613
  }
878
614
  }
879
615
  }
880
616
  return {
881
- status: l,
882
- objectiveValue: d,
883
- values: f,
884
- reducedCosts: m,
885
- duals: p,
886
- slacks: h,
887
- runTime: c,
888
- raw: s
617
+ status: S,
618
+ terminationStatus: y,
619
+ hasPrimalSolution: !0,
620
+ objectiveValue: T,
621
+ ...D === void 0 ? {} : { objectiveBound: D },
622
+ ...O === void 0 ? {} : {
623
+ relGap: O,
624
+ mipGap: O
625
+ },
626
+ ...k === void 0 ? {} : { absGap: k },
627
+ values: j,
628
+ reducedCosts: M,
629
+ duals: ee,
630
+ slacks: N,
631
+ runTime: _,
632
+ raw: g
889
633
  };
890
634
  }
891
- }, K = G;
892
- function q() {
893
- d("highs", (e) => new G(e)), l((e) => new G(e));
635
+ }, J = q;
636
+ function Y() {
637
+ T("highs", (e) => new q(e)), _((e) => new q(e));
894
638
  }
895
- q();
639
+ Y();
896
640
  //#endregion
897
641
  //#region src/modeler/solvers/highs/index.ts
898
- var J = /* @__PURE__ */ S({
899
- HiGHS: () => K,
900
- HighsSolver: () => G,
901
- OFFICIAL_HIGHS_CDN_WASM_URL: () => b,
902
- getHighs: () => g,
903
- getHighsWasmUrl: () => v,
904
- isValidWasmHeader: () => h,
905
- mapHighsStatus: () => W,
906
- probeWasmUrl: () => p,
907
- registerHighsSolver: () => q,
908
- resolveBrowserWasmUrl: () => _,
909
- setHighsWasmUrl: () => y,
910
- solveLp: () => U,
911
- solveLpWithHighs: () => m
642
+ var Te = /* @__PURE__ */ se({
643
+ HiGHS: () => J,
644
+ HighsSolver: () => q,
645
+ OFFICIAL_HIGHS_CDN_WASM_URL: () => te,
646
+ getHighs: () => F,
647
+ getHighsWasmUrl: () => L,
648
+ isValidWasmHeader: () => P,
649
+ mapHighsStatus: () => K,
650
+ mapHighsTerminationStatus: () => G,
651
+ probeWasmUrl: () => M,
652
+ registerHighsSolver: () => Y,
653
+ resolveBrowserWasmUrl: () => I,
654
+ setHighsWasmUrl: () => R,
655
+ solveLp: () => W,
656
+ solveLpWithHighs: () => N
912
657
  });
913
- import * as de from "./highs-worker-factory.js";
914
- w(J, de);
915
- import * as fe from "./highs-assets.js";
916
- w(J, fe);
658
+ import * as Ee from "./highs-worker-factory.js";
659
+ z(Te, Ee);
660
+ import * as De from "./highs-assets.js";
661
+ z(Te, De);
917
662
  //#endregion
918
663
  //#region src/modeler/solvers/highs.ts
919
- var Y = /* @__PURE__ */ S({
920
- HiGHS: () => K,
921
- HighsSolver: () => G,
922
- OFFICIAL_HIGHS_CDN_WASM_URL: () => b,
923
- getHighs: () => g,
924
- getHighsWasmUrl: () => v,
925
- isValidWasmHeader: () => h,
926
- mapHighsStatus: () => W,
927
- probeWasmUrl: () => p,
928
- registerHighsSolver: () => q,
929
- resolveBrowserWasmUrl: () => _,
930
- setHighsWasmUrl: () => y,
931
- solveLp: () => U,
932
- solveLpWithHighs: () => m
664
+ var Oe = /* @__PURE__ */ se({
665
+ HiGHS: () => J,
666
+ HighsSolver: () => q,
667
+ OFFICIAL_HIGHS_CDN_WASM_URL: () => te,
668
+ getHighs: () => F,
669
+ getHighsWasmUrl: () => L,
670
+ isValidWasmHeader: () => P,
671
+ mapHighsStatus: () => K,
672
+ mapHighsTerminationStatus: () => G,
673
+ probeWasmUrl: () => M,
674
+ registerHighsSolver: () => Y,
675
+ resolveBrowserWasmUrl: () => I,
676
+ setHighsWasmUrl: () => R,
677
+ solveLp: () => W,
678
+ solveLpWithHighs: () => N
933
679
  });
934
- w(Y, J);
680
+ z(Oe, Te);
935
681
  //#endregion
936
682
  //#region src/modeler/solvers/mock.ts
937
- var X = class {
683
+ var ke = class {
938
684
  name;
939
685
  capabilities;
940
686
  options;
941
687
  constructor(e = {}) {
942
688
  this.name = e.name || "MockSolver", this.capabilities = e.capabilities || {
943
689
  supportsMIP: !0,
944
- supportsQP: !0
690
+ supportsQP: !0,
691
+ supportsWarmStart: !0
945
692
  }, this.options = e;
946
693
  }
947
- async solve(e, t, n = {}) {
948
- let r = {
694
+ async solve(e, t = {}, n = {}) {
695
+ let r = E(t) ? n : t, i = {
949
696
  ...this.options,
950
- ...n
697
+ ...r
698
+ }, a = !!(i.values && Object.keys(i.values).length > 0 || i.boolValues && Object.keys(i.boolValues).length > 0);
699
+ if (i.signal?.aborted) return {
700
+ status: "Unknown",
701
+ terminationStatus: "Interrupted",
702
+ hasPrimalSolution: !1,
703
+ objectiveValue: null,
704
+ values: {},
705
+ runTime: 0,
706
+ raw: { mock: !0 }
951
707
  };
952
- return r.delayMs && r.delayMs > 0 && await new Promise((e) => setTimeout(e, r.delayMs)), {
953
- status: r.status || "Optimal",
954
- objectiveValue: r.objectiveValue ?? 0,
955
- values: r.values || {},
956
- reducedCosts: r.reducedCosts,
957
- duals: r.duals,
958
- slacks: r.slacks,
708
+ if (i.delayMs && i.delayMs > 0 && (await new Promise((e) => {
709
+ let t = setTimeout(() => {
710
+ i.signal?.removeEventListener("abort", n), e();
711
+ }, i.delayMs), n = () => {
712
+ clearTimeout(t), e();
713
+ };
714
+ i.signal?.addEventListener("abort", n, { once: !0 });
715
+ }), i.signal?.aborted)) {
716
+ let e = !!(i.hasPrimalSolution ?? a);
717
+ return {
718
+ status: e ? "Feasible" : "Unknown",
719
+ terminationStatus: "Interrupted",
720
+ hasPrimalSolution: e,
721
+ objectiveValue: e ? i.objectiveValue ?? 0 : null,
722
+ ...i.objectiveBound === void 0 ? {} : { objectiveBound: i.objectiveBound },
723
+ ...i.relGap === void 0 ? i.mipGap === void 0 ? {} : {
724
+ relGap: i.mipGap,
725
+ mipGap: i.mipGap
726
+ } : {
727
+ relGap: i.relGap,
728
+ mipGap: i.relGap
729
+ },
730
+ ...i.absGap === void 0 ? {} : { absGap: i.absGap },
731
+ values: e && i.values || {},
732
+ ...e && i.boolValues !== void 0 ? { boolValues: i.boolValues } : {},
733
+ runTime: .001,
734
+ raw: { mock: !0 }
735
+ };
736
+ }
737
+ if (i.onProgress && Array.isArray(i.progressEvents)) for (let e of i.progressEvents) {
738
+ if (i.signal?.aborted) break;
739
+ i.onProgress(e);
740
+ }
741
+ let o = i.status || "Optimal", s = i.terminationStatus ?? o, c = i.hasPrimalSolution === void 0 ? o === "Optimal" || o === "Feasible" || o === "Sat" || (o === "TimeLimit" || o === "IterationLimit" || s === "Interrupted") && a : i.hasPrimalSolution;
742
+ if (i.onProgress && !Array.isArray(i.progressEvents) && !i.signal?.aborted) {
743
+ let e = c ? i.objectiveValue ?? 0 : void 0;
744
+ i.onProgress({
745
+ elapsedTime: .001,
746
+ elapsedSeconds: .001,
747
+ ...typeof e == "number" && Number.isFinite(e) ? { objectiveValue: e } : {},
748
+ ...i.objectiveBound === void 0 ? {} : { objectiveBound: i.objectiveBound },
749
+ ...i.relGap === void 0 ? i.mipGap === void 0 ? {} : {
750
+ relGap: i.mipGap,
751
+ mipGap: i.mipGap
752
+ } : {
753
+ relGap: i.relGap,
754
+ mipGap: i.relGap
755
+ },
756
+ ...i.absGap === void 0 ? {} : { absGap: i.absGap }
757
+ });
758
+ }
759
+ return i.signal?.aborted && (s = "Interrupted", c = i.hasPrimalSolution === void 0 ? a : i.hasPrimalSolution, o = c ? "Feasible" : "Unknown"), {
760
+ status: o,
761
+ terminationStatus: s,
762
+ hasPrimalSolution: c,
763
+ objectiveValue: c ? i.objectiveValue ?? 0 : null,
764
+ ...i.objectiveBound === void 0 ? {} : { objectiveBound: i.objectiveBound },
765
+ ...i.relGap === void 0 ? i.mipGap === void 0 ? {} : {
766
+ relGap: i.mipGap,
767
+ mipGap: i.mipGap
768
+ } : {
769
+ relGap: i.relGap,
770
+ mipGap: i.relGap
771
+ },
772
+ ...i.absGap === void 0 ? {} : { absGap: i.absGap },
773
+ values: c && i.values || {},
774
+ ...c && i.boolValues !== void 0 ? { boolValues: i.boolValues } : {},
775
+ reducedCosts: i.reducedCosts,
776
+ duals: i.duals,
777
+ slacks: i.slacks,
959
778
  runTime: .001,
960
779
  raw: { mock: !0 }
961
780
  };
962
781
  }
963
782
  };
964
- function Z() {
965
- d("mock", (e) => new X(e));
783
+ function Ae() {
784
+ T("mock", (e) => new ke(e));
966
785
  }
967
- Z();
786
+ Ae();
968
787
  //#endregion
969
788
  //#region src/modeler/solvers/index.ts
970
- var Q = /* @__PURE__ */ S({
971
- HiGHS: () => K,
972
- HighsSolver: () => G,
973
- MockSolver: () => X,
974
- OFFICIAL_HIGHS_CDN_WASM_URL: () => b,
975
- getHighs: () => g,
976
- getHighsWasmUrl: () => v,
977
- getSolver: () => f,
978
- isValidWasmHeader: () => h,
979
- listAvailableSolvers: () => u,
980
- mapHighsStatus: () => W,
981
- probeWasmUrl: () => p,
982
- registerHighsSolver: () => q,
983
- registerMockSolver: () => Z,
984
- registerSolver: () => d,
985
- resolveBrowserWasmUrl: () => _,
986
- setDefaultSolver: () => l,
987
- setHighsWasmUrl: () => y,
988
- solveLp: () => U,
989
- solveLpWithHighs: () => m
789
+ var je = /* @__PURE__ */ se({
790
+ HiGHS: () => J,
791
+ HighsSolver: () => q,
792
+ MockSolver: () => ke,
793
+ OFFICIAL_HIGHS_CDN_WASM_URL: () => te,
794
+ getHighs: () => F,
795
+ getHighsWasmUrl: () => L,
796
+ getSolver: () => D,
797
+ isValidWasmHeader: () => P,
798
+ listAvailableSolvers: () => S,
799
+ mapHighsStatus: () => K,
800
+ mapHighsTerminationStatus: () => G,
801
+ probeWasmUrl: () => M,
802
+ registerHighsSolver: () => Y,
803
+ registerMockSolver: () => Ae,
804
+ registerSolver: () => T,
805
+ resolveBrowserWasmUrl: () => I,
806
+ setDefaultSolver: () => _,
807
+ setHighsWasmUrl: () => R,
808
+ solveLp: () => W,
809
+ solveLpWithHighs: () => N
990
810
  });
991
- w(Q, Y);
811
+ z(je, Oe);
812
+ //#endregion
813
+ //#region src/modeler/solution-validator.ts
814
+ function Me(e, t) {
815
+ if (e === void 0) return 1e-6;
816
+ if (typeof e != "number" || !Number.isFinite(e) || e < 0) throw Error(`Invalid ${t}: expected a finite non-negative number, received ${String(e)}.`);
817
+ return e;
818
+ }
819
+ function Ne(e, t = {}) {
820
+ let r = Me(t.feasibilityTolerance, "feasibilityTolerance"), i = Me(t.integralityTolerance, "integralityTolerance"), a = t.evaluateLogicalConstraints === void 0 || !!t.evaluateLogicalConstraints, s = t.values !== void 0 && t.values !== null;
821
+ if (t.values !== void 0 && (typeof t.values != "object" || t.values === null || Array.isArray(t.values))) throw Error("Invalid values option: expected a plain object mapping variable names to values.");
822
+ let l = t.values, u = [], d = Object.create(null), f = [], p = [], m = 0, h = (e) => {
823
+ typeof e == "number" && !Number.isNaN(e) && e > m && (m = e);
824
+ }, g = (e) => {
825
+ u.push(e), Object.prototype.hasOwnProperty.call(d, e.name) || (d[e.name] = []), d[e.name].push(e), e.type !== "missing_value" && e.type !== "unchecked_constraint" && h(e.violation);
826
+ }, _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), y = 0, b = 0, x = 0, S = 0;
827
+ for (let t of e.variables) {
828
+ let e = s ? Object.prototype.hasOwnProperty.call(l, t.name) ? l[t.name] : void 0 : t.value;
829
+ if (e == null) {
830
+ p.push(t.name), g({
831
+ type: "missing_value",
832
+ target: "variable",
833
+ name: t.name,
834
+ actual: e ?? null,
835
+ violation: Infinity,
836
+ message: `Variable "${t.name}" has no assigned solution value.`
837
+ });
838
+ continue;
839
+ }
840
+ if (typeof e != "number" || !Number.isFinite(e)) {
841
+ g({
842
+ type: "non_finite_value",
843
+ target: "variable",
844
+ name: t.name,
845
+ actual: e,
846
+ violation: Infinity,
847
+ message: `Variable "${t.name}" has non-finite or non-numeric value: ${String(e)}.`
848
+ });
849
+ continue;
850
+ }
851
+ _.set(t, e), y++;
852
+ let n = t.type === "Binary" || t.type === "BINARY", a = n || t.type === "Integer" || t.type === "INTEGER", o = n ? Math.max(0, t.lb) : t.lb, c = n ? Math.min(1, t.ub) : t.ub, u = typeof t.lb == "number" && !Number.isNaN(t.lb) && t.lb !== Infinity, d = typeof t.ub == "number" && !Number.isNaN(t.ub) && t.ub !== -Infinity;
853
+ if (!u) g({
854
+ type: "lower_bound",
855
+ target: "variable",
856
+ name: t.name,
857
+ actual: e,
858
+ limit: t.lb,
859
+ violation: Infinity,
860
+ message: `Variable "${t.name}" has invalid lower bound (${String(t.lb)}).`
861
+ });
862
+ else if (o !== -Infinity) {
863
+ let n = e - o, i = Math.max(0, o - e);
864
+ h(i), i > r && g({
865
+ type: "lower_bound",
866
+ target: "variable",
867
+ name: t.name,
868
+ actual: e,
869
+ limit: o,
870
+ violation: i,
871
+ signedViolation: n,
872
+ message: `Variable "${t.name}" value (${e}) violates lower bound (${o}) by ${i}.`
873
+ });
874
+ }
875
+ if (!d) g({
876
+ type: "upper_bound",
877
+ target: "variable",
878
+ name: t.name,
879
+ actual: e,
880
+ limit: t.ub,
881
+ violation: Infinity,
882
+ message: `Variable "${t.name}" has invalid upper bound (${String(t.ub)}).`
883
+ });
884
+ else if (c !== Infinity) {
885
+ let n = e - c, i = Math.max(0, e - c);
886
+ h(i), i > r && g({
887
+ type: "upper_bound",
888
+ target: "variable",
889
+ name: t.name,
890
+ actual: e,
891
+ limit: c,
892
+ violation: i,
893
+ signedViolation: n,
894
+ message: `Variable "${t.name}" value (${e}) violates upper bound (${c}) by ${i}.`
895
+ });
896
+ }
897
+ if (u && d && o > c && o - e <= r && e - c <= r) {
898
+ let n = o - c;
899
+ g({
900
+ type: "lower_bound",
901
+ target: "variable",
902
+ name: t.name,
903
+ actual: e,
904
+ limit: o,
905
+ violation: n,
906
+ signedViolation: e - o,
907
+ message: `Variable "${t.name}" has inverted bounds [${o}, ${c}].`
908
+ });
909
+ }
910
+ if (a) {
911
+ let r = Math.round(e), a = e - r, o = Math.abs(a);
912
+ h(o), o > i && g({
913
+ type: "integrality",
914
+ target: "variable",
915
+ name: t.name,
916
+ varType: n ? "Binary" : "Integer",
917
+ actual: e,
918
+ nearestInteger: r,
919
+ violation: o,
920
+ signedViolation: a,
921
+ message: `${n ? "Binary" : "Integer"} variable "${t.name}" value (${e}) violates integrality by ${o} (nearest integer: ${r}).`
922
+ });
923
+ }
924
+ }
925
+ for (let t of e.boolVars) {
926
+ let e = s ? Object.prototype.hasOwnProperty.call(l, t.name) ? l[t.name] : void 0 : t.value;
927
+ if (e == null) {
928
+ p.push(t.name), g({
929
+ type: "missing_value",
930
+ target: "bool_variable",
931
+ name: t.name,
932
+ actual: e ?? null,
933
+ violation: Infinity,
934
+ message: `Boolean variable "${t.name}" has no assigned solution value.`
935
+ });
936
+ continue;
937
+ }
938
+ if (typeof e != "boolean") {
939
+ g({
940
+ type: "invalid_boolean_value",
941
+ target: "bool_variable",
942
+ name: t.name,
943
+ actual: e,
944
+ violation: Infinity,
945
+ message: `Boolean variable "${t.name}" has non-boolean value: ${String(e)}.`
946
+ });
947
+ continue;
948
+ }
949
+ v.set(t, e), b++;
950
+ }
951
+ let C = (e) => {
952
+ let t = e.constant === void 0 ? 0 : e.constant;
953
+ if (typeof t != "number" || !Number.isFinite(t)) return {
954
+ ok: !1,
955
+ reason: `non-finite constant (${String(t)})`
956
+ };
957
+ let n = t;
958
+ for (let [t, r] of e.terms) {
959
+ if (typeof r != "number" || !Number.isFinite(r)) return {
960
+ ok: !1,
961
+ reason: `non-finite coefficient (${String(r)}) for variable "${t.name}"`
962
+ };
963
+ if (r !== 0) {
964
+ if (!_.has(t)) return {
965
+ ok: !1,
966
+ reason: `missing or invalid value for variable "${t.name}"`
967
+ };
968
+ if (n += r * _.get(t), !Number.isFinite(n)) return {
969
+ ok: !1,
970
+ reason: "linear expression evaluation overflowed finite range"
971
+ };
972
+ }
973
+ }
974
+ return {
975
+ ok: !0,
976
+ value: n
977
+ };
978
+ }, w = (e, t = r) => {
979
+ if (typeof e.rhs != "number" || !Number.isFinite(e.rhs)) return {
980
+ status: "unchecked",
981
+ reason: `non-finite right-hand side (${String(e.rhs)})`
982
+ };
983
+ let n = C(e.lhs);
984
+ if (!n.ok) return {
985
+ status: "unchecked",
986
+ reason: n.reason
987
+ };
988
+ let i = n.value, a = i - e.rhs;
989
+ if (!Number.isFinite(a)) return {
990
+ status: "unchecked",
991
+ reason: "constraint residual overflowed finite range"
992
+ };
993
+ let o = e.sense === "<=" ? Math.max(0, a) : e.sense === ">=" ? Math.max(0, -a) : Math.abs(a);
994
+ return o > t ? {
995
+ status: "violated",
996
+ lhsVal: i,
997
+ signed: a,
998
+ violation: o,
999
+ message: `Constraint "${e.name}" (${i} ${e.sense} ${e.rhs}) violated by ${o}.`
1000
+ } : {
1001
+ status: "satisfied",
1002
+ lhsVal: i,
1003
+ signed: a,
1004
+ violation: o
1005
+ };
1006
+ };
1007
+ for (let t of e.constraints) {
1008
+ let e = w(t);
1009
+ e.status === "unchecked" ? (f.push(t.name), g({
1010
+ type: "unchecked_constraint",
1011
+ target: "constraint",
1012
+ name: t.name,
1013
+ sense: t.sense,
1014
+ limit: t.rhs,
1015
+ rhs: t.rhs,
1016
+ violation: Infinity,
1017
+ message: `Constraint "${t.name}" could not be evaluated: ${e.reason}.`
1018
+ })) : e.status === "violated" ? (x++, g({
1019
+ type: "linear_constraint",
1020
+ target: "constraint",
1021
+ name: t.name,
1022
+ sense: t.sense,
1023
+ actual: e.lhsVal,
1024
+ limit: t.rhs,
1025
+ rhs: t.rhs,
1026
+ violation: e.violation,
1027
+ signedViolation: e.signed,
1028
+ message: e.message
1029
+ })) : (x++, h(e.violation));
1030
+ }
1031
+ let T = (e) => {
1032
+ if (e instanceof o) return v.has(e) ? {
1033
+ ok: !0,
1034
+ value: v.get(e),
1035
+ violation: 0
1036
+ } : {
1037
+ ok: !1,
1038
+ reason: `missing or invalid value for Boolean variable "${e.name}"`
1039
+ };
1040
+ if (e instanceof c) {
1041
+ let t = w(e, 0);
1042
+ if (t.status === "unchecked") return {
1043
+ ok: !1,
1044
+ reason: t.reason
1045
+ };
1046
+ if (r > 0) {
1047
+ let n = Math.abs(t.lhsVal - e.rhs);
1048
+ if (n > 0 && n <= r) return {
1049
+ ok: !1,
1050
+ reason: `numeric comparison "${e.name}" lies within feasibilityTolerance (${r}) of boundary (${t.lhsVal} vs ${e.rhs})`
1051
+ };
1052
+ }
1053
+ return {
1054
+ ok: !0,
1055
+ value: t.status === "satisfied",
1056
+ violation: 0
1057
+ };
1058
+ }
1059
+ if (e instanceof n) switch (e.op) {
1060
+ case "not": {
1061
+ let t = T(e.children[0]);
1062
+ return t.ok ? {
1063
+ ok: !0,
1064
+ value: !t.value,
1065
+ violation: 0
1066
+ } : t;
1067
+ }
1068
+ case "and": {
1069
+ let t = 0;
1070
+ for (let n of e.children) {
1071
+ let e = T(n);
1072
+ if (!e.ok) return e;
1073
+ if (!e.value) return {
1074
+ ok: !0,
1075
+ value: !1,
1076
+ violation: 0
1077
+ };
1078
+ e.violation > t && (t = e.violation);
1079
+ }
1080
+ return {
1081
+ ok: !0,
1082
+ value: !0,
1083
+ violation: t
1084
+ };
1085
+ }
1086
+ case "or": {
1087
+ let t = !1, n = Infinity;
1088
+ for (let r of e.children) {
1089
+ let e = T(r);
1090
+ if (!e.ok) return e;
1091
+ e.value && (t = !0, e.violation < n && (n = e.violation));
1092
+ }
1093
+ return {
1094
+ ok: !0,
1095
+ value: t,
1096
+ violation: t ? n : 0
1097
+ };
1098
+ }
1099
+ case "implies": {
1100
+ let t = T(e.children[0]);
1101
+ if (!t.ok) return t;
1102
+ if (!t.value) return {
1103
+ ok: !0,
1104
+ value: !0,
1105
+ violation: 0
1106
+ };
1107
+ let n = T(e.children[1]);
1108
+ return n.ok ? {
1109
+ ok: !0,
1110
+ value: n.value,
1111
+ violation: n.value ? n.violation : 0
1112
+ } : n;
1113
+ }
1114
+ case "xor": {
1115
+ let t = !1, n = 0;
1116
+ for (let r of e.children) {
1117
+ let e = T(r);
1118
+ if (!e.ok) return e;
1119
+ e.value && (t = !t, e.violation > n && (n = e.violation));
1120
+ }
1121
+ return {
1122
+ ok: !0,
1123
+ value: t,
1124
+ violation: t ? n : 0
1125
+ };
1126
+ }
1127
+ default: return {
1128
+ ok: !1,
1129
+ reason: `unsupported logical operator "${String(e.op)}"`
1130
+ };
1131
+ }
1132
+ return {
1133
+ ok: !1,
1134
+ reason: "unsupported logical expression node"
1135
+ };
1136
+ };
1137
+ for (let t = 0; t < e.logicalConstraints.length; t++) {
1138
+ let n = e.logicalConstraints[t], r = n.name || `lc_${t + 1}`;
1139
+ if (!a) {
1140
+ f.push(r), g({
1141
+ type: "unchecked_constraint",
1142
+ target: "logical_constraint",
1143
+ name: r,
1144
+ violation: Infinity,
1145
+ message: `Logical constraint "${r}" was not evaluated because evaluateLogicalConstraints is false.`
1146
+ });
1147
+ continue;
1148
+ }
1149
+ let i = T(n.expr);
1150
+ if (!i.ok) {
1151
+ f.push(r), g({
1152
+ type: "unchecked_constraint",
1153
+ target: "logical_constraint",
1154
+ name: r,
1155
+ violation: Infinity,
1156
+ message: `Logical constraint "${r}" could not be evaluated: ${i.reason}.`
1157
+ });
1158
+ continue;
1159
+ }
1160
+ S++, i.value ? h(i.violation) : g({
1161
+ type: "logical_constraint",
1162
+ target: "logical_constraint",
1163
+ name: r,
1164
+ actual: !1,
1165
+ limit: !0,
1166
+ violation: 1,
1167
+ signedViolation: -1,
1168
+ message: `Logical constraint "${r}" evaluated to false.`
1169
+ });
1170
+ }
1171
+ let E = y === e.variables.length && b === e.boolVars.length && x === e.constraints.length && S === e.logicalConstraints.length && f.length === 0 && p.length === 0;
1172
+ return {
1173
+ valid: E && u.length === 0,
1174
+ complete: E,
1175
+ violations: u,
1176
+ violationsByName: d,
1177
+ uncheckedConstraints: f,
1178
+ missingVariables: p,
1179
+ maxViolation: m,
1180
+ summary: {
1181
+ checkedVariables: y,
1182
+ totalVariables: e.variables.length,
1183
+ checkedBoolVariables: b,
1184
+ totalBoolVariables: e.boolVars.length,
1185
+ checkedLinearConstraints: x,
1186
+ totalLinearConstraints: e.constraints.length,
1187
+ checkedLogicalConstraints: S,
1188
+ totalLogicalConstraints: e.logicalConstraints.length
1189
+ }
1190
+ };
1191
+ }
1192
+ //#endregion
1193
+ //#region src/modeler/big-m.ts
1194
+ function Pe(e, t) {
1195
+ if (typeof e != "number" || !Number.isFinite(e) || e <= 0) throw Error(`Invalid Big-M value for indicator constraint "${t}": expected a finite positive number, received ${e}.`);
1196
+ }
1197
+ function Fe(e, t, n) {
1198
+ let r = e.constant === void 0 ? 0 : e.constant;
1199
+ if (!Number.isFinite(t) || !Number.isFinite(r)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": constraint contains non-finite constant (${r}) or right-hand side (${t}).`);
1200
+ let i = t - r;
1201
+ if (!Number.isFinite(i)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": effective right-hand side (${t} - ${r}) overflows finite floating-point range. Please rescale coefficients/constants.`);
1202
+ for (let [t, r] of e.terms) {
1203
+ if (!Number.isFinite(r)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" has non-finite coefficient (${r}).`);
1204
+ if (Number.isNaN(t.lb) || Number.isNaN(t.ub) || t.lb === Infinity || t.ub === -Infinity || t.lb > t.ub) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" has invalid bounds [${t.lb}, ${t.ub}].`);
1205
+ }
1206
+ return i;
1207
+ }
1208
+ function Ie(e, t, n) {
1209
+ let r = Fe(e, t, n), i = 0;
1210
+ for (let [t, r] of e.terms) {
1211
+ if (r === 0) continue;
1212
+ let e;
1213
+ if (r > 0) {
1214
+ if (!Number.isFinite(t.ub)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite upper bound (required because coefficient ${r} is positive in <= constraint). Please set an explicit finite upper bound on the variable or specify { M } explicitly in indicator options.`);
1215
+ e = t.ub;
1216
+ } else {
1217
+ if (!Number.isFinite(t.lb)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite lower bound (required because coefficient ${r} is negative in <= constraint). Please set an explicit finite lower bound on the variable or specify { M } explicitly in indicator options.`);
1218
+ e = t.lb;
1219
+ }
1220
+ let a = r * e;
1221
+ if (i += a, !Number.isFinite(a) || !Number.isFinite(i)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while bounding contribution of variable "${t.name}". Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
1222
+ }
1223
+ let a = i - r;
1224
+ if (!Number.isFinite(a)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while computing Big-M (${i} - ${r}). Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
1225
+ let o = Math.max(0, a);
1226
+ if (!Number.isFinite(o) || !Number.isFinite(r + o)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": derived Big-M (${o}) or shifted right-hand side overflows finite floating-point range. Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
1227
+ return o;
1228
+ }
1229
+ function Le(e, t, n) {
1230
+ let r = Fe(e, t, n), i = 0;
1231
+ for (let [t, r] of e.terms) {
1232
+ if (r === 0) continue;
1233
+ let e;
1234
+ if (r > 0) {
1235
+ if (!Number.isFinite(t.lb)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite lower bound (required because coefficient ${r} is positive in >= constraint). Please set an explicit finite lower bound on the variable or specify { M } explicitly in indicator options.`);
1236
+ e = t.lb;
1237
+ } else {
1238
+ if (!Number.isFinite(t.ub)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite upper bound (required because coefficient ${r} is negative in >= constraint). Please set an explicit finite upper bound on the variable or specify { M } explicitly in indicator options.`);
1239
+ e = t.ub;
1240
+ }
1241
+ let a = r * e;
1242
+ if (i += a, !Number.isFinite(a) || !Number.isFinite(i)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while bounding contribution of variable "${t.name}". Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
1243
+ }
1244
+ let a = r - i;
1245
+ if (!Number.isFinite(a)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while computing Big-M (${r} - ${i}). Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
1246
+ let o = Math.max(0, a);
1247
+ if (!Number.isFinite(o) || !Number.isFinite(r - o)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": derived Big-M (${o}) or shifted right-hand side overflows finite floating-point range. Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
1248
+ return o;
1249
+ }
1250
+ function X(e, t, n, r, i, a, o) {
1251
+ if (!(e instanceof b && (e.type === "Binary" || e.type === "Integer" && e.lb === 0 && e.ub === 1))) throw Error(`Indicator variable "${e?.name ?? String(e)}" must be a Binary variable (or Integer variable with bounds [0, 1]), received "${e?.type ?? typeof e}" with bounds [${e?.lb}, ${e?.ub}].`);
1252
+ if (!Number.isFinite(e.lb) || !Number.isFinite(e.ub) || e.lb < 0 || e.ub > 1 || e.lb > e.ub) throw Error(`Binary indicator variable "${e.name}" has invalid bounds [${e.lb}, ${e.ub}]. Binary variables must stay within [0, 1] with lb <= ub.`);
1253
+ let s = Fe(t, r, o);
1254
+ if (i !== 0 && i !== 1) throw Error(`Invalid activeValue: ${i}. Indicator activation value must be 0 or 1.`);
1255
+ if (n !== "<=" && n !== ">=") throw Error(`Invalid indicator sense for "${o}": expected "<=" or ">=", received "${String(n)}".`);
1256
+ if (!Number.isFinite(a) || a < 0) throw Error(`Invalid Big-M value for indicator constraint "${o}": expected a finite non-negative number, received ${a}.`);
1257
+ let c = t.terms.get(e);
1258
+ if (c !== void 0 && c !== 0) throw Error(`Indicator constraint "${o}" cannot include its own binary activation variable "${e.name}" in the linear expression.`);
1259
+ let l, u;
1260
+ if (i === 1 ? n === "<=" ? (l = a, u = s + a) : (l = -a, u = s - a) : n === "<=" ? (l = -a, u = s) : (l = a, u = s), !Number.isFinite(u)) throw Error(`Cannot construct finite indicator constraint "${o}": shifted right-hand side overflows finite floating-point range. Please rescale coefficients/bounds or specify a smaller finite { M }.`);
1261
+ let d = /* @__PURE__ */ new Map();
1262
+ for (let [e, n] of t.terms) n !== 0 && d.set(e, n);
1263
+ return l !== 0 && d.set(e, l), {
1264
+ lhs: new j(d, 0),
1265
+ rhs: u
1266
+ };
1267
+ }
992
1268
  //#endregion
993
1269
  //#region src/modeler/model.ts
994
- var $ = class {
1270
+ function Z(e) {
1271
+ return Array.isArray(e) || typeof e == "object" && !!e && !(e instanceof String) && typeof e[Symbol.iterator] == "function";
1272
+ }
1273
+ function Q(e) {
1274
+ return typeof e == "object" && !!e && !Array.isArray(e) && !(e instanceof String) && typeof e[Symbol.iterator] != "function";
1275
+ }
1276
+ function $(e, t) {
1277
+ if (!Number.isInteger(e) || e < 0) throw Error(`Invalid count (${e}) for ${t} variable creation: count must be a non-negative integer.`);
1278
+ }
1279
+ var Re = class {
995
1280
  name;
996
- sense;
997
- objective;
1281
+ _sense;
1282
+ _objectiveExpr;
998
1283
  variables = [];
999
1284
  constraints = [];
1000
1285
  boolVars = [];
1001
1286
  logicalConstraints = [];
1002
- unsatCore = [];
1287
+ unsatCore = void 0;
1003
1288
  values = /* @__PURE__ */ new Map();
1004
1289
  varMapByName = /* @__PURE__ */ new Map();
1290
+ varPrefixCounters = /* @__PURE__ */ new Map();
1005
1291
  boolVarMapByName = /* @__PURE__ */ new Map();
1006
1292
  boolVarPrefixCounters = /* @__PURE__ */ new Map();
1007
1293
  constrMapByName = /* @__PURE__ */ new Map();
1294
+ constrPrefixCounters = /* @__PURE__ */ new Map();
1295
+ logicalConstrMapByName = /* @__PURE__ */ new Map();
1296
+ logicalConstrCounter = 0;
1008
1297
  status = "NotSolved";
1298
+ terminationStatus = "NotSolved";
1299
+ hasPrimalSolution = !1;
1009
1300
  objectiveValue = null;
1301
+ objectiveBound = void 0;
1302
+ relGap = void 0;
1303
+ mipGap = void 0;
1304
+ absGap = void 0;
1010
1305
  runTime = 0;
1011
1306
  solution = null;
1012
1307
  solver = null;
1308
+ hasSolutionState = !1;
1309
+ modelRevision = 0;
1310
+ activeOperationId = 0;
1311
+ batchDepth = 0;
1312
+ batchMutated = !1;
1313
+ batchUndoActions = [];
1013
1314
  constructor(e = {}, t) {
1014
1315
  let n;
1015
1316
  n = typeof e == "string" ? {
1016
1317
  ...t,
1017
1318
  name: e
1018
- } : e, this.name = n.name || "OptimizationModel", this.sense = T(n.sense), this.objective = new O(), n.solver && (this.solver = f(n.solver));
1319
+ } : e, this.name = n.name || "OptimizationModel", this._sense = le(n.sense), this._objectiveExpr = new j(), n.solver && (this.solver = D(n.solver));
1320
+ }
1321
+ get sense() {
1322
+ return this._sense;
1019
1323
  }
1020
- get vars() {
1021
- return this.variables;
1324
+ set sense(e) {
1325
+ let t = le(e);
1326
+ this._sense !== t && (this._sense = t, this.recordModelMutation());
1022
1327
  }
1023
- get constrs() {
1024
- return this.constraints;
1328
+ get objectiveExpr() {
1329
+ return this._objectiveExpr.clone();
1330
+ }
1331
+ set objectiveExpr(e) {
1332
+ this.applyObjective(e);
1333
+ }
1334
+ get conflicts() {
1335
+ return this.unsatCore;
1025
1336
  }
1026
1337
  get numVars() {
1027
1338
  return this.variables.length;
@@ -1029,50 +1340,123 @@ var $ = class {
1029
1340
  get numConstrs() {
1030
1341
  return this.constraints.length;
1031
1342
  }
1032
- createDomainVars(e, t, n, r) {
1033
- if (typeof n == "number" || Array.isArray(n)) {
1034
- let i = typeof t == "number" ? Array.from({ length: t }, (e, t) => t) : t, a = typeof n == "number" ? Array.from({ length: n }, (e, t) => t) : n, o = r || {}, s = o.prefix || o.name || "x", c = {};
1035
- for (let t of i) {
1036
- c[t] = {};
1037
- for (let n of a) c[t][n] = this.addVar({
1038
- ...o,
1039
- type: e,
1040
- name: `${s}_${t}_${n}`
1041
- });
1343
+ clearSolutionFields() {
1344
+ if (this.hasSolutionState || this.status !== "NotSolved" || this.terminationStatus !== "NotSolved" || this.hasPrimalSolution || this.solution !== null || this.unsatCore !== void 0) {
1345
+ this.hasSolutionState = !1, this.status = "NotSolved", this.terminationStatus = "NotSolved", this.hasPrimalSolution = !1, this.objectiveValue = null, this.objectiveBound = void 0, this.relGap = void 0, this.mipGap = void 0, this.absGap = void 0, this.solution = null, this.runTime = 0, this.unsatCore = void 0, this.values.clear();
1346
+ for (let e of this.variables) e.value = null, e.reducedCost = null;
1347
+ for (let e of this.boolVars) e.value = null;
1348
+ for (let e of this.constraints) e.dual = null, e.slack = null;
1349
+ }
1350
+ }
1351
+ recordModelMutation() {
1352
+ if (this.batchDepth > 0) {
1353
+ this.batchMutated = !0;
1354
+ return;
1355
+ }
1356
+ this.modelRevision++, this.clearSolutionFields();
1357
+ }
1358
+ notifyMutation() {
1359
+ this.recordModelMutation();
1360
+ }
1361
+ resetSolutionState() {
1362
+ this.recordModelMutation();
1363
+ }
1364
+ runTransactionalBatch(e) {
1365
+ if (this.batchDepth > 0) return e();
1366
+ let t = this.variables.length, n = this.boolVars.length, r = this.constraints.length, i = this.logicalConstraints.length, a = new Map(this.varPrefixCounters), o = new Map(this.boolVarPrefixCounters), s = new Map(this.constrPrefixCounters), c = this.logicalConstrCounter;
1367
+ this.batchDepth = 1, this.batchMutated = !1, this.batchUndoActions = [];
1368
+ try {
1369
+ let t = e();
1370
+ this.batchDepth = 0;
1371
+ let n = this.batchMutated;
1372
+ return this.batchMutated = !1, this.batchUndoActions = [], n && this.recordModelMutation(), t;
1373
+ } catch (e) {
1374
+ this.batchDepth = 0, this.batchMutated = !1;
1375
+ for (let e = t; e < this.variables.length; e++) {
1376
+ let t = this.variables[e];
1377
+ this.varMapByName.delete(t.name), t.ownerModel = null, g(t, this);
1378
+ }
1379
+ this.variables.length = t;
1380
+ for (let e = n; e < this.boolVars.length; e++) {
1381
+ let t = this.boolVars[e];
1382
+ this.boolVarMapByName.delete(t.name);
1042
1383
  }
1043
- return c;
1384
+ this.boolVars.length = n;
1385
+ for (let e = r; e < this.constraints.length; e++) {
1386
+ let t = this.constraints[e];
1387
+ this.constrMapByName.delete(t.name);
1388
+ }
1389
+ this.constraints.length = r;
1390
+ for (let e = i; e < this.logicalConstraints.length; e++) {
1391
+ let t = this.logicalConstraints[e];
1392
+ this.logicalConstrMapByName.delete(t.name);
1393
+ }
1394
+ this.logicalConstraints.length = i;
1395
+ for (let e = this.batchUndoActions.length - 1; e >= 0; e--) this.batchUndoActions[e]();
1396
+ throw this.batchUndoActions = [], this.varPrefixCounters = a, this.boolVarPrefixCounters = o, this.constrPrefixCounters = s, this.logicalConstrCounter = c, e;
1044
1397
  }
1045
- if (typeof t == "string") {
1046
- let r = n || {};
1398
+ }
1399
+ createDomainVars(e, t, n, r) {
1400
+ let i = e.toLowerCase(), a = typeof t == "number", o = typeof n == "number", s = Z(t), c = Z(n);
1401
+ if (o || c) {
1402
+ if (a && $(t, i), o && $(n, i), !a && !s || r !== void 0 && !Q(r)) throw Error(`Invalid arguments provided for ${i} variable creation`);
1403
+ let c = a ? Array.from({ length: t }, (e, t) => t) : Array.from(t), l = o ? Array.from({ length: n }, (e, t) => t) : n === t ? c : Array.from(n), u = r || {}, d = u.prefix || u.name || "x";
1404
+ return this.runTransactionalBatch(() => {
1405
+ let t = a ? [] : {};
1406
+ for (let n of c) {
1407
+ let r = o ? [] : {};
1408
+ for (let t of l) r[t] = this.addVar({
1409
+ ...u,
1410
+ type: e,
1411
+ name: `${d}_${n}_${t}`
1412
+ });
1413
+ t[n] = r;
1414
+ }
1415
+ return t;
1416
+ });
1417
+ }
1418
+ if (typeof t == "string" || t === void 0) {
1419
+ if (n !== void 0 && !Q(n)) throw Error(`Invalid arguments provided for ${i} variable creation`);
1420
+ let r = n || {}, a = typeof t == "string" ? t : r.name;
1047
1421
  return this.addVar({
1048
1422
  ...r,
1049
1423
  type: e,
1050
- name: t
1424
+ name: a
1051
1425
  });
1052
1426
  }
1053
- let i = n || {}, a = i.prefix || i.name;
1054
- if (typeof t == "number") {
1055
- let n = [], r = a || "x";
1056
- for (let a = 0; a < t; a++) n.push(this.addVar({
1057
- ...i,
1427
+ if (Q(t)) {
1428
+ if (n !== void 0) throw Error(`Invalid arguments provided for ${i} variable creation`);
1429
+ let r = t;
1430
+ return this.addVar({
1431
+ ...r,
1432
+ type: e
1433
+ });
1434
+ }
1435
+ if (n !== void 0 && !Q(n)) throw Error(`Invalid arguments provided for ${i} variable creation`);
1436
+ let l = n || {}, u = l.prefix || l.name;
1437
+ if (typeof t == "number") return $(t, i), this.runTransactionalBatch(() => {
1438
+ let n = [], r = u || "x";
1439
+ for (let i = 0; i < t; i++) n.push(this.addVar({
1440
+ ...l,
1058
1441
  type: e,
1059
- name: `${r}_${a}`
1442
+ name: void 0,
1443
+ prefix: r
1060
1444
  }));
1061
1445
  return n;
1062
- }
1063
- if (Array.isArray(t) || t && typeof t[Symbol.iterator] == "function") {
1446
+ });
1447
+ if (Z(t)) return this.runTransactionalBatch(() => {
1064
1448
  let n = {};
1065
1449
  for (let r of t) {
1066
- let t = a ? `${a}_${r}` : `${r}`;
1450
+ let t = u ? `${u}_${r}` : `${r}`;
1067
1451
  n[r] = this.addVar({
1068
- ...i,
1452
+ ...l,
1069
1453
  type: e,
1070
1454
  name: t
1071
1455
  });
1072
1456
  }
1073
1457
  return n;
1074
- }
1075
- throw Error(`Invalid arguments provided for ${e.toLowerCase()} variable creation`);
1458
+ });
1459
+ throw Error(`Invalid arguments provided for ${i} variable creation`);
1076
1460
  }
1077
1461
  binary(e, t, n) {
1078
1462
  return this.createDomainVars("Binary", e, t, n);
@@ -1084,52 +1468,96 @@ var $ = class {
1084
1468
  return this.createDomainVars("Continuous", e, t, n);
1085
1469
  }
1086
1470
  bool(e, t, n) {
1087
- if (typeof t == "number" || Array.isArray(t)) {
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 = {};
1089
- for (let e of r) {
1090
- s[e] = {};
1091
- for (let t of i) s[e][t] = this.createBoolVar(`${o}_${e}_${t}`);
1092
- }
1093
- return s;
1471
+ let r = typeof e == "number", i = typeof t == "number", a = Z(e), o = Z(t);
1472
+ if (i || o) {
1473
+ if (r && $(e, "boolean"), i && $(t, "boolean"), !r && !a || n !== void 0 && !Q(n)) throw Error("Invalid arguments provided for boolean variable creation");
1474
+ let o = r ? Array.from({ length: e }, (e, t) => t) : Array.from(e), s = i ? Array.from({ length: t }, (e, t) => t) : t === e ? o : Array.from(t), c = n || {}, l = c.prefix || c.name || "p";
1475
+ return this.runTransactionalBatch(() => {
1476
+ let e = r ? [] : {};
1477
+ for (let t of o) {
1478
+ let n = i ? [] : {};
1479
+ for (let e of s) n[e] = this.createBoolVar(`${l}_${t}_${e}`);
1480
+ e[t] = n;
1481
+ }
1482
+ return e;
1483
+ });
1094
1484
  }
1095
- if (typeof e == "string" || e === void 0) return this.createBoolVar(e);
1096
- let r = t || {}, i = r.prefix || r.name;
1097
- if (typeof e == "number") {
1098
- let t = [], n = i || "p";
1099
- for (let r = 0; r < e; r++) t.push(this.createBoolVar(this.getNextBoolVarName(n)));
1100
- return t;
1485
+ if (typeof e == "string" || e === void 0) {
1486
+ if (t !== void 0 && !Q(t)) throw Error("Invalid arguments provided for boolean variable creation");
1487
+ let n = t || {}, r = typeof e == "string" ? e : n.name;
1488
+ return this.createBoolVar(r, n.prefix);
1489
+ }
1490
+ if (Q(e)) {
1491
+ if (t !== void 0) throw Error("Invalid arguments provided for boolean variable creation");
1492
+ let n = e;
1493
+ return this.createBoolVar(n.name, n.prefix);
1101
1494
  }
1102
- if (Array.isArray(e) || e && typeof e[Symbol.iterator] == "function") {
1495
+ if (t !== void 0 && !Q(t)) throw Error("Invalid arguments provided for boolean variable creation");
1496
+ let s = t || {}, c = s.prefix || s.name;
1497
+ if (typeof e == "number") return $(e, "boolean"), this.runTransactionalBatch(() => {
1498
+ let t = [], n = c || "p";
1499
+ for (let r = 0; r < e; r++) t.push(this.createBoolVar(void 0, n));
1500
+ return t;
1501
+ });
1502
+ if (Z(e)) return this.runTransactionalBatch(() => {
1103
1503
  let t = {};
1104
1504
  for (let n of e) {
1105
- let e = i ? `${i}_${n}` : `${n}`;
1505
+ let e = c ? `${c}_${n}` : `${n}`;
1106
1506
  t[n] = this.createBoolVar(e);
1107
1507
  }
1108
1508
  return t;
1109
- }
1509
+ });
1110
1510
  throw Error("Invalid arguments provided for boolean variable creation");
1111
1511
  }
1112
1512
  hasVarName(e) {
1113
1513
  return this.varMapByName.has(e) || this.boolVarMapByName.has(e);
1114
1514
  }
1515
+ getNextVarName(e) {
1516
+ let t = this.varPrefixCounters.get(e) ?? 0, n = `${e}_${t}`;
1517
+ for (; this.hasVarName(n);) t++, n = `${e}_${t}`;
1518
+ return this.varPrefixCounters.set(e, t + 1), n;
1519
+ }
1115
1520
  getNextBoolVarName(e) {
1116
1521
  let t = this.boolVarPrefixCounters.get(e) ?? 0, n = `${e}_${t}`;
1117
- for (; this.hasVarName(n);) t++, n = `${e}_${t}`;
1522
+ for (; this.hasVarName(n) || this.hasConstraintName(n);) t++, n = `${e}_${t}`;
1118
1523
  return this.boolVarPrefixCounters.set(e, t + 1), n;
1119
1524
  }
1120
- 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;
1525
+ hasConstraintName(e) {
1526
+ return this.constrMapByName.has(e) || this.logicalConstrMapByName.has(e);
1527
+ }
1528
+ hasBoolVarName(e) {
1529
+ return this.boolVarMapByName.has(e);
1530
+ }
1531
+ getNextConstrName(e = "c") {
1532
+ let t = this.constrPrefixCounters.get(e) ?? 1, n = `${e}_${t}`;
1533
+ for (; this.hasConstraintName(n) || this.hasBoolVarName(n);) t++, n = `${e}_${t}`;
1534
+ return this.constrPrefixCounters.set(e, t + 1), n;
1535
+ }
1536
+ getNextLogicalConstrName() {
1537
+ let e = this.logicalConstrCounter + 1, t = `lc_${e}`;
1538
+ for (; this.hasConstraintName(t) || this.hasBoolVarName(t);) e++, t = `lc_${e}`;
1539
+ return this.logicalConstrCounter = e, t;
1540
+ }
1541
+ createBoolVar(e, t) {
1542
+ let n = typeof e == "string" ? e.trim() : void 0, r = typeof t == "string" ? t.trim() : "", i = r.length > 0 ? r : "p", a = n && n.length > 0 ? n : this.getNextBoolVarName(i);
1543
+ if (this.hasVarName(a)) throw Error(`Variable with name '${a}' already exists in model`);
1544
+ if (this.hasConstraintName(a)) throw Error(`Boolean variable name '${a}' conflicts with an existing constraint in model`);
1545
+ let s = new o(a);
1546
+ return this.boolVars.push(s), this.boolVarMapByName.set(s.name, s), this.recordModelMutation(), s;
1125
1547
  }
1126
1548
  addVar(e) {
1127
- let t = e || {}, n = typeof t.name == "string" ? t.name.trim() : void 0, r = n && n.length > 0 ? n : void 0, i = 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;
1549
+ let t = e || {}, n = typeof t.name == "string" ? t.name.trim() : void 0, r = n && n.length > 0 ? n : void 0, i = typeof t.prefix == "string" ? t.prefix.trim() : "", a = i.length > 0 ? i : "x", o = this.varPrefixCounters.get(a), s = r ?? this.getNextVarName(a);
1550
+ try {
1551
+ if (this.hasVarName(s)) throw Error(`Variable with name '${s}' already exists in model`);
1552
+ let e = new b({
1553
+ ...t,
1554
+ name: s,
1555
+ prefix: a
1556
+ });
1557
+ return e.hasExplicitName = r !== void 0, d(e), m(e, this), e.ownerModel = this, this.variables.push(e), this.varMapByName.set(e.name, e), this.recordModelMutation(), e;
1558
+ } catch (e) {
1559
+ throw r === void 0 && (o === void 0 ? this.varPrefixCounters.delete(a) : this.varPrefixCounters.set(a, o)), e;
1560
+ }
1133
1561
  }
1134
1562
  getVarByName(e) {
1135
1563
  return this.varMapByName.get(e);
@@ -1140,28 +1568,41 @@ var $ = class {
1140
1568
  getConstraintByName(e) {
1141
1569
  return this.constrMapByName.get(e);
1142
1570
  }
1143
- setObjective(e, t) {
1144
- if (e instanceof c) throw Error("Cannot set objective to a constraint comparison (<=, >=, ==). Did you mean to use m.constrain(expr`... <= ...`)? For objectives, supply an unconstrained expression like expr`45 * ${x} + 80 * ${y}`.");
1145
- t && (this.sense = T(t)), this.objective = typeof e == "string" ? P(e, (e) => this.getVarByName(e)) : typeof e == "number" ? new O(/* @__PURE__ */ new Map(), e) : e instanceof D || "terms" in e ? e.clone() : new O(/* @__PURE__ */ new Map([[e, 1]]), 0);
1146
- }
1147
- maximize(e) {
1148
- this.setObjective(e, "Maximize");
1149
- }
1150
- minimize(e) {
1151
- this.setObjective(e, "Minimize");
1152
- }
1153
- constrain(e, t) {
1154
- if (Array.isArray(e)) {
1155
- for (let t of e) this.constrain(t);
1571
+ getLogicalConstraintByName(e) {
1572
+ return this.logicalConstrMapByName.get(e);
1573
+ }
1574
+ objective(e) {
1575
+ return e ? (this.applyObjective(e.expr, e.sense), this) : this.objectiveExpr;
1576
+ }
1577
+ applyObjective(e, t) {
1578
+ if (e instanceof c || typeof e == "object" && e && "sense" in e && "lhs" in e && "rhs" in e || typeof e == "string" && /(<=|>=|==|=<|=>|=)/.test(e)) throw Error(typeof e == "string" ? "Cannot use a comparison constraint as an objective. Did you mean to use m.constraint(expr`... <= ...`)?" : "Cannot use a Constraint as an objective. Did you mean to use m.constraint(expr`... <= ...`)? For objectives, supply an unconstrained expression like expr`45 * ${x} + 80 * ${y}`.");
1579
+ let n = t === void 0 ? this.sense : le(t), r;
1580
+ if (typeof e == "string") r = pe(e, (e) => this.getVarByName(e));
1581
+ else if (typeof e == "number") r = new j(/* @__PURE__ */ new Map(), e);
1582
+ else if (e instanceof A) r = e.clone();
1583
+ else if (e instanceof j) r = e.clone();
1584
+ else if (typeof e == "object" && e && "quadTerms" in e && e.quadTerms instanceof Map && "linearTerms" in e && e.linearTerms instanceof Map && typeof e.constant == "number") {
1585
+ let t = e;
1586
+ r = new A(t.linearTerms, t.quadTerms, t.constant);
1587
+ } else if (typeof e == "object" && e && "terms" in e && e.terms instanceof Map && typeof e.constant == "number") {
1588
+ let t = e;
1589
+ r = new j(t.terms, t.constant);
1590
+ } else if (e instanceof b || typeof e == "object" && e && "id" in e && "name" in e && "lb" in e && "ub" in e) r = new j(/* @__PURE__ */ new Map([[e, 1]]), 0);
1591
+ else throw Error("Invalid objective expression: expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.");
1592
+ ee(r, this.name, (e) => this.varMapByName.get(e.name) === e), this._sense = n, this._objectiveExpr = r, this.recordModelMutation();
1593
+ }
1594
+ constraint(e, t) {
1595
+ if (Array.isArray(e)) return this.runTransactionalBatch(() => {
1596
+ for (let t of e) this.constraint(t);
1156
1597
  return this;
1157
- }
1158
- if (e instanceof 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).");
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().");
1598
+ });
1599
+ if (e instanceof A || typeof e == "object" && e && "quadTerms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a quadratic expression as a constraint.");
1600
+ if (e instanceof j || typeof e == "object" && e && "terms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a linear expression without a comparison operator. Use expr`... <= ...` or .le(), .ge(), .eq().");
1160
1601
  return this.addConstraint(e, t), this;
1161
1602
  }
1162
1603
  getValues(e) {
1163
1604
  if (e == null) return null;
1164
- if (e instanceof M || e instanceof n) return e.value;
1605
+ if (e instanceof b || e instanceof o) return e.value;
1165
1606
  if (Array.isArray(e)) return e.map((e) => this.getValues(e));
1166
1607
  if (typeof e == "object") {
1167
1608
  let t = {};
@@ -1171,198 +1612,396 @@ var $ = class {
1171
1612
  return null;
1172
1613
  }
1173
1614
  addConstraint(e, t) {
1174
- if (e instanceof 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).");
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().");
1176
- if (e instanceof i) {
1177
- let n = t || `lc_${this.logicalConstraints.length + 1}`;
1178
- return this.logicalConstraints.push({
1179
- name: n,
1615
+ if (e instanceof A || typeof e == "object" && e && "quadTerms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a quadratic expression as a constraint.");
1616
+ if (e instanceof j || typeof e == "object" && e && "terms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a linear expression without a comparison operator. Use expr`... <= ...` or .le(), .ge(), .eq().");
1617
+ if (e instanceof r) {
1618
+ let n = typeof t == "string" && t.trim().length > 0 ? t.trim() : void 0;
1619
+ if (n !== void 0) {
1620
+ if (this.hasConstraintName(n)) throw Error(`Constraint with name '${n}' already exists in model`);
1621
+ if (this.hasBoolVarName(n)) throw Error(`Constraint name '${n}' conflicts with an existing Boolean variable in model`);
1622
+ }
1623
+ let r = this.logicalConstrCounter, i = n ?? this.getNextLogicalConstrName();
1624
+ try {
1625
+ l(e, i, this.name, (e) => this.varMapByName.get(e.name) === e, (e) => this.boolVarMapByName.get(e.name) === e, this);
1626
+ } catch (e) {
1627
+ throw n === void 0 && (this.logicalConstrCounter = r), e;
1628
+ }
1629
+ O(e, this, this.batchDepth > 0 ? this.batchUndoActions : void 0);
1630
+ let a = {
1631
+ name: i,
1180
1632
  expr: e
1181
- }), e;
1633
+ };
1634
+ return this.logicalConstraints.push(a), this.logicalConstrMapByName.set(i, a), this.recordModelMutation(), e;
1182
1635
  }
1183
- let n;
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`);
1185
- return this.constraints.push(n), this.constrMapByName.set(n.name, n), n;
1186
- }
1187
- add(e, t) {
1188
- if (Array.isArray(e)) {
1189
- for (let t of e) this.add(t);
1190
- return this;
1636
+ let n = typeof e == "string" ? he(e, (e) => this.getVarByName(e), t) : e;
1637
+ n.ownerModel && n.ownerModel !== this && (h(n, this.name, (e) => this.varMapByName.get(e.name) === e, n.name), p(n, this));
1638
+ let i = typeof t == "string" && t.trim().length > 0 ? t.trim() : n.hasExplicitName ? n.name.trim() : void 0;
1639
+ if (i !== void 0) {
1640
+ if (this.hasConstraintName(i)) throw Error(`Constraint with name '${i}' already exists in model`);
1641
+ if (this.hasBoolVarName(i)) throw Error(`Constraint name '${i}' conflicts with an existing Boolean variable in model`);
1191
1642
  }
1192
- 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);
1643
+ let a = this.constrPrefixCounters.get("c"), o = i ?? this.getNextConstrName("c"), s;
1644
+ try {
1645
+ h(n, this.name, (e) => this.varMapByName.get(e.name) === e, o), s = p(n, this);
1646
+ } catch (e) {
1647
+ throw i === void 0 && (a === void 0 ? this.constrPrefixCounters.delete("c") : this.constrPrefixCounters.set("c", a)), e;
1648
+ }
1649
+ let c = n.name, u = n.hasExplicitName, d = n.ownerModel, f = s;
1650
+ return this.batchUndoActions.push(() => {
1651
+ n.ownerModel = d, n._assignModelName(c, u), x(n, this, f);
1652
+ }), this.batchDepth === 0 && (this.batchUndoActions = []), n._assignModelName(o, !0), n.ownerModel = this, this.constraints.push(n), this.constrMapByName.set(n.name, n), this.recordModelMutation(), n;
1193
1653
  }
1194
1654
  indicator(e, t, n = {}) {
1195
- if (t instanceof D) throw Error("Quadratic expressions or constraints are not supported in indicator constraints (only linear constraints are allowed).");
1655
+ if (!(e instanceof b)) throw Error("Invalid binary variable passed to indicator(). Expected a binary Var instance.");
1656
+ if (!(e.type === "Binary" || e.type === "Integer" && e.lb === 0 && e.ub === 1)) throw Error(`Invalid variable "${e.name}" passed to indicator(): variable has type "${e.type}" with bounds [${e.lb}, ${e.ub}]. Indicator activation variable must be a Binary variable (or Integer variable with bounds [0, 1]).`);
1657
+ if (t instanceof A) throw Error("Quadratic expressions or constraints are not supported in indicator constraints (only linear constraints are allowed).");
1196
1658
  if (!("sense" in t) || !("lhs" in t)) throw Error("Invalid constraint expression passed to indicator(). Expression must include a comparison operator (<=, >=, ==).");
1197
- let r = t, i = n.activeValue === void 0 ? 1 : n.activeValue, a = n.M === void 0 ? 1e5 : n.M, o = n.name || `ind_${e.name}_${r.name}`, s = [], { lhs: c, sense: l, rhs: u } = r;
1198
- if (i === 1) {
1199
- if (l === "<=" || l === "==") {
1200
- let t = this.addConstraint(c.add(e.mul(a)).le(u + a), l === "==" ? `${o}_le` : o);
1201
- s.push(t);
1202
- }
1203
- if (l === ">=" || l === "==") {
1204
- let t = this.addConstraint(c.sub(e.mul(a)).ge(u - a), l === "==" ? `${o}_ge` : o);
1205
- s.push(t);
1206
- }
1207
- } else {
1659
+ let r = t, i = n.activeValue === void 0 ? 1 : n.activeValue;
1660
+ if (i !== 0 && i !== 1) throw Error(`Invalid activeValue: ${i}. Indicator activeValue must be 0 or 1.`);
1661
+ if (this.varMapByName.get(e.name) !== e) throw Error(`Variable "${e.name}" passed to indicator() does not belong to model "${this.name}". All variables must belong to the model by object identity.`);
1662
+ let a = typeof n.name == "string" && n.name.trim().length > 0 ? n.name.trim() : void 0, o = this.constrPrefixCounters.get("c"), { lhs: s, sense: l, rhs: u } = r, d, f, p;
1663
+ if (a !== void 0) d = a, f = l === "==" ? `${d}_le` : d, p = l === "==" ? `${d}_ge` : d;
1664
+ else if (r.hasExplicitName) d = `ind_${e.name}_${r.name.trim()}`, f = l === "==" ? `${d}_le` : d, p = l === "==" ? `${d}_ge` : d;
1665
+ else do {
1666
+ let t = this.getNextConstrName("c");
1667
+ d = `ind_${e.name}_${t}`, f = l === "==" ? `${d}_le` : d, p = l === "==" ? `${d}_ge` : d;
1668
+ } while ((l === "<=" || l === "==") && (this.hasConstraintName(f) || this.hasBoolVarName(f)) || (l === ">=" || l === "==") && (this.hasConstraintName(p) || this.hasBoolVarName(p)));
1669
+ let m = [];
1670
+ try {
1671
+ if ((l === "<=" || l === "==") && (this.hasConstraintName(f) || this.hasBoolVarName(f))) throw Error(this.hasBoolVarName(f) ? `Constraint name '${f}' conflicts with an existing Boolean variable in model` : `Constraint with name '${f}' already exists in model`);
1672
+ if ((l === ">=" || l === "==") && (this.hasConstraintName(p) || this.hasBoolVarName(p))) throw Error(this.hasBoolVarName(p) ? `Constraint name '${p}' conflicts with an existing Boolean variable in model` : `Constraint with name '${p}' already exists in model`);
1673
+ n.M !== void 0 && Pe(n.M, d);
1674
+ let t = (e) => this.varMapByName.get(e.name) === e;
1675
+ for (let [e] of s.terms) if (!t(e)) throw Error(`Variable "${e.name}" in constraint "${d}" does not belong to model "${this.name}". All variables must belong to the model by object identity.`);
1208
1676
  if (l === "<=" || l === "==") {
1209
- let t = this.addConstraint(c.sub(e.mul(a)).le(u), l === "==" ? `${o}_le` : o);
1210
- s.push(t);
1677
+ let t = X(e, s, "<=", u, i, n.M === void 0 ? Ie(s, u, f) : n.M, f);
1678
+ m.push([new c(t.lhs, "<=", t.rhs, f), f]);
1211
1679
  }
1212
1680
  if (l === ">=" || l === "==") {
1213
- let t = this.addConstraint(c.add(e.mul(a)).ge(u), l === "==" ? `${o}_ge` : o);
1214
- s.push(t);
1681
+ let t = X(e, s, ">=", u, i, n.M === void 0 ? Le(s, u, p) : n.M, p);
1682
+ m.push([new c(t.lhs, ">=", t.rhs, p), p]);
1215
1683
  }
1684
+ for (let [e, n] of m) h(e, this.name, t, n);
1685
+ } catch (e) {
1686
+ throw o === void 0 ? this.constrPrefixCounters.delete("c") : this.constrPrefixCounters.set("c", o), e;
1216
1687
  }
1217
- return s;
1688
+ return this.runTransactionalBatch(() => m.map(([e, t]) => this.addConstraint(e, t)));
1218
1689
  }
1219
1690
  toLpString() {
1220
- let { lpString: e } = B({
1691
+ this.validateIntegrity();
1692
+ let { lpString: e } = C({
1221
1693
  name: this.name,
1222
1694
  sense: this.sense,
1223
- objective: this.objective,
1695
+ objective: this.objectiveExpr,
1224
1696
  constraints: this.constraints,
1225
1697
  variables: this.variables
1226
1698
  });
1227
1699
  return e;
1228
1700
  }
1229
- async optimize(e, t) {
1230
- let n, r;
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.`);
1233
- let i = {
1701
+ validateIntegrity() {
1702
+ k(this);
1703
+ }
1704
+ ensureExecutionValid(e, t, n) {
1705
+ if (this.modelRevision !== e) throw this.activeOperationId === t && this.clearSolutionFields(), Error(`Model "${this.name}" was modified while ${n}() was in progress; stale solver result was discarded.`);
1706
+ if (this.activeOperationId !== t) throw Error(`Stale ${n}() result discarded because a newer solve or check operation was started on model "${this.name}".`);
1707
+ }
1708
+ wrapSolveOptions(e, t, n) {
1709
+ let r = e.onProgress;
1710
+ return r ? {
1711
+ ...e,
1712
+ onProgress: (e) => {
1713
+ this.activeOperationId === n && this.modelRevision === t && r(e);
1714
+ }
1715
+ } : e;
1716
+ }
1717
+ hasPrimalFromResult(e) {
1718
+ if (typeof e.hasPrimalSolution == "boolean") return e.hasPrimalSolution;
1719
+ let t = e.status, n = e.terminationStatus ?? t, r = e.values || {}, i = e.boolValues || {};
1720
+ return t !== "Infeasible" && t !== "Unsat" && t !== "Unbounded" && t !== "Error" && t !== "NotSolved" && n !== "Infeasible" && n !== "Unsat" && n !== "Unbounded" && n !== "InfeasibleOrUnbounded" && n !== "Error" && n !== "NotSolved" && (t === "Optimal" || t === "Feasible" || t === "Sat" || n === "Optimal" || n === "Feasible" || n === "Sat" || typeof e.objectiveValue == "number" && Number.isFinite(e.objectiveValue) || Object.values(r).some((e) => typeof e == "number" && Number.isFinite(e) || typeof e == "boolean") || Object.values(i).some((e) => typeof e == "boolean"));
1721
+ }
1722
+ resolveSolverAndOptions(e, t) {
1723
+ if (e && typeof e == "object" && "solve" in e && typeof e.solve == "function") {
1724
+ let { solver: n, ...r } = t || {};
1725
+ return {
1726
+ activeSolver: e,
1727
+ activeOptions: r
1728
+ };
1729
+ }
1730
+ if (typeof e == "function") {
1731
+ let { solver: n, ...r } = t || {};
1732
+ return {
1733
+ activeSolver: new e(r),
1734
+ activeOptions: r
1735
+ };
1736
+ }
1737
+ if (typeof e == "string") {
1738
+ let { solver: n, ...r } = t || {};
1739
+ return {
1740
+ activeSolver: D(e, r),
1741
+ activeOptions: r
1742
+ };
1743
+ }
1744
+ let { solver: n, ...r } = e || {};
1745
+ return n ? {
1746
+ activeSolver: D(n, r),
1747
+ activeOptions: r
1748
+ } : {
1749
+ activeSolver: this.solver || D(),
1750
+ activeOptions: r
1751
+ };
1752
+ }
1753
+ async solve(e, t) {
1754
+ let n = ++this.activeOperationId, r = this.modelRevision;
1755
+ this.clearSolutionFields(), this.validateIntegrity();
1756
+ let { activeSolver: i, activeOptions: a } = this.resolveSolverAndOptions(e, t);
1757
+ if (this._objectiveExpr instanceof A && this._objectiveExpr.quadTerms.size > 0 && i.capabilities?.supportsQP === !1) throw Error(`Solver "${i.name}" does not support quadratic objectives (QP). Please use a QP-capable solver such as HiGHS or Clarabel.`);
1758
+ if (this.logicalConstraints.length > 0 && i.capabilities?.supportsSMT !== !0) throw Error(`Solver "${i.name}" does not support SMT / logical constraints (or, implies, not, xor). Please use an SMT-capable solver such as Z3.`);
1759
+ if (this.variables.some((e) => e.initialValue !== void 0) && i.capabilities?.supportsWarmStart !== !0) throw Error(`Solver "${i.name}" does not support primal initial values (initialValue). Please use a solver with warm-start support such as HiGHS.`);
1760
+ let o = {
1234
1761
  name: this.name,
1235
1762
  sense: this.sense,
1236
- objective: this.objective,
1763
+ objective: this._objectiveExpr,
1237
1764
  constraints: this.constraints,
1238
1765
  variables: this.variables,
1239
1766
  logicalConstraints: this.logicalConstraints,
1240
1767
  boolVars: this.boolVars
1241
- }, a = B(i), o = await n.solve(i, a, r);
1242
- this.runTime = o.runTime ?? 0, this.status = o.status, this.objectiveValue = o.objectiveValue ?? null;
1243
- let s = {}, c = {}, l = {}, u = {};
1244
- this.values.clear();
1245
- for (let e of this.variables) e.value = null, e.reducedCost = null;
1246
- for (let e of this.boolVars) e.value = null;
1247
- for (let e of this.constraints) e.dual = null, e.slack = null;
1248
- if (a?.nameToVar) for (let e of a.nameToVar.values()) e.value = null, e.reducedCost = null;
1249
- if (a?.nameToConstraint) for (let e of a.nameToConstraint.values()) e.dual = null, e.slack = null;
1250
- if (o.values && o.status !== "Infeasible" && o.status !== "Unbounded") {
1251
- for (let [e, t] of Object.entries(o.values)) if (typeof t == "number" && !Number.isNaN(t)) {
1252
- this.values.set(e, t);
1253
- let n = this.getVarByName(e) || a.nameToVar.get(e);
1254
- n && (n.value = t, s[n.name] = t);
1255
- let r = this.boolVars.find((t) => t.name === e);
1256
- r && (r.value = !!t);
1768
+ }, s = this.wrapSolveOptions(a, r, n), c;
1769
+ try {
1770
+ c = await i.solve(o, s);
1771
+ } catch (e) {
1772
+ throw this.activeOperationId === n && this.clearSolutionFields(), e;
1773
+ }
1774
+ this.ensureExecutionValid(r, n, "solve"), this.runTime = c.runTime ?? 0, this.status = c.status, this.terminationStatus = c.terminationStatus ?? c.status;
1775
+ let l = this.hasPrimalFromResult(c);
1776
+ this.hasPrimalSolution = l, this.objectiveValue = l && typeof c.objectiveValue == "number" && Number.isFinite(c.objectiveValue) ? c.objectiveValue : null, this.objectiveBound = typeof c.objectiveBound == "number" && Number.isFinite(c.objectiveBound) ? c.objectiveBound : void 0;
1777
+ let u = typeof c.relGap == "number" && Number.isFinite(c.relGap) ? c.relGap : typeof c.mipGap == "number" && Number.isFinite(c.mipGap) ? c.mipGap : void 0;
1778
+ this.relGap = u, this.mipGap = u, this.absGap = typeof c.absGap == "number" && Number.isFinite(c.absGap) ? c.absGap : this.objectiveValue !== null && this.objectiveBound !== void 0 ? Math.abs(this.objectiveValue - this.objectiveBound) : void 0;
1779
+ let d = (e, t, n) => {
1780
+ Object.defineProperty(e, t, {
1781
+ value: n,
1782
+ enumerable: !0,
1783
+ writable: !0,
1784
+ configurable: !0
1785
+ });
1786
+ }, f = {}, p = {}, m = {}, h = {};
1787
+ if (this.values.clear(), l && c.values) {
1788
+ for (let [e, t] of Object.entries(c.values)) if (typeof t == "number" && Number.isFinite(t)) {
1789
+ let n = this.getVarByName(e), r = this.getBoolVarByName(e);
1790
+ n && (n.value = t, d(f, n.name, t), this.values.set(n.name, t)), r && (r.value = !!t, this.values.set(r.name, t)), !n && !r && this.values.set(e, t);
1791
+ } else if (typeof t == "boolean") {
1792
+ let n = t, r = this.getBoolVarByName(e);
1793
+ r ? (r.value = n, d(f, r.name, +!!n), this.values.set(r.name, n)) : this.values.set(e, n);
1257
1794
  }
1258
1795
  }
1259
- if (o.reducedCosts) for (let [e, t] of Object.entries(o.reducedCosts)) {
1260
- let n = this.getVarByName(e) || a.nameToVar.get(e);
1261
- n && (n.reducedCost = t, l[n.name] = t);
1796
+ if (l && c.boolValues) for (let [e, t] of Object.entries(c.boolValues)) {
1797
+ if (typeof t != "boolean") continue;
1798
+ let n = this.getBoolVarByName(e);
1799
+ n ? (n.value = t, this.values.has(n.name) || this.values.set(n.name, t)) : this.values.has(e) || this.values.set(e, t);
1800
+ }
1801
+ if (l && c.reducedCosts) for (let [e, t] of Object.entries(c.reducedCosts)) {
1802
+ if (typeof t != "number" || !Number.isFinite(t)) continue;
1803
+ let n = this.getVarByName(e);
1804
+ n && (n.reducedCost = t, d(m, n.name, t));
1262
1805
  }
1263
- if (o.duals) for (let [e, t] of Object.entries(o.duals)) {
1264
- let n = this.getConstraintByName(e) || a.nameToConstraint.get(e);
1265
- n && (n.dual = t, c[n.name] = t);
1806
+ if (c.duals) for (let [e, t] of Object.entries(c.duals)) {
1807
+ if (typeof t != "number" || !Number.isFinite(t)) continue;
1808
+ let n = this.getConstraintByName(e);
1809
+ n && (n.dual = t, d(p, n.name, t));
1266
1810
  }
1267
- if (o.slacks) for (let [e, t] of Object.entries(o.slacks)) {
1268
- let n = this.getConstraintByName(e) || a.nameToConstraint.get(e);
1269
- n && (n.slack = t, u[n.name] = t);
1811
+ if (c.slacks) for (let [e, t] of Object.entries(c.slacks)) {
1812
+ if (typeof t != "number" || !Number.isFinite(t)) continue;
1813
+ let n = this.getConstraintByName(e);
1814
+ n && (n.slack = t, d(h, n.name, t));
1270
1815
  }
1271
1816
  return this.solution = {
1272
1817
  status: this.status,
1818
+ terminationStatus: this.terminationStatus,
1819
+ hasPrimalSolution: this.hasPrimalSolution,
1273
1820
  objectiveValue: this.objectiveValue,
1274
- values: s,
1275
- duals: c,
1276
- reducedCosts: l,
1277
- slacks: u,
1821
+ ...this.objectiveBound === void 0 ? {} : { objectiveBound: this.objectiveBound },
1822
+ ...this.relGap === void 0 ? {} : {
1823
+ relGap: this.relGap,
1824
+ mipGap: this.mipGap
1825
+ },
1826
+ ...this.absGap === void 0 ? {} : { absGap: this.absGap },
1827
+ values: f,
1828
+ duals: p,
1829
+ reducedCosts: m,
1830
+ slacks: h,
1278
1831
  runTime: this.runTime,
1279
- raw: o.raw
1280
- }, this.status;
1281
- }
1282
- async solve(e, t) {
1283
- return this.optimize(e, t);
1832
+ raw: c.raw
1833
+ }, this.hasSolutionState = !0, this.status;
1284
1834
  }
1285
1835
  async check(e, t) {
1286
- let n, r;
1287
- 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.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.`);
1288
- if (typeof n.check == "function") {
1289
- let e = await n.check({
1290
- name: this.name,
1291
- variables: this.variables,
1292
- boolVars: this.boolVars,
1293
- constraints: this.constraints,
1294
- logicalConstraints: this.logicalConstraints
1295
- }, r);
1296
- this.status = e.status, this.runTime = e.runTime ?? 0, this.unsatCore = e.unsatCore || [], this.values.clear();
1297
- for (let e of this.variables) e.value = null;
1298
- for (let e of this.boolVars) e.value = null;
1299
- if (e.values && e.status === "Sat") for (let [t, n] of Object.entries(e.values)) {
1300
- this.values.set(t, n);
1301
- let e = this.getVarByName(t);
1302
- e && typeof n == "number" && (e.value = n);
1303
- let r = this.boolVars.find((e) => e.name === t);
1304
- r && (r.value = !!n);
1836
+ let n = ++this.activeOperationId, r = this.modelRevision;
1837
+ this.clearSolutionFields(), this.validateIntegrity();
1838
+ let { activeSolver: i, activeOptions: a } = this.resolveSolverAndOptions(e, t);
1839
+ if (this.logicalConstraints.length > 0 && i.capabilities?.supportsSMT !== !0) throw Error(`Solver "${i.name}" does not support SMT / logical constraints (or, implies, not, xor). Please use an SMT-capable solver such as Z3.`);
1840
+ if (this.variables.some((e) => e.initialValue !== void 0) && i.capabilities?.supportsWarmStart !== !0) throw Error(`Solver "${i.name}" does not support primal initial values (initialValue). Please use a solver with warm-start support such as HiGHS.`);
1841
+ let o = this.wrapSolveOptions(a, r, n), s = (e, t, n) => {
1842
+ Object.defineProperty(e, t, {
1843
+ value: n,
1844
+ enumerable: !0,
1845
+ writable: !0,
1846
+ configurable: !0
1847
+ });
1848
+ }, c = {
1849
+ name: this.name,
1850
+ variables: this.variables,
1851
+ boolVars: this.boolVars,
1852
+ constraints: this.constraints,
1853
+ logicalConstraints: this.logicalConstraints
1854
+ };
1855
+ if (typeof i.check == "function") {
1856
+ let e;
1857
+ try {
1858
+ e = await i.check(c, o);
1859
+ } catch (e) {
1860
+ throw this.activeOperationId === n && this.clearSolutionFields(), e;
1305
1861
  }
1306
- return e;
1307
- }
1308
- let i = this.objective, a = this.sense;
1309
- try {
1310
- this.objective = new O(), this.sense = "Minimize";
1311
- let e = await this.optimize(n, r), t = e === "Optimal" || e === "Feasible", i = e === "Infeasible", a = {};
1312
- if (t) {
1313
- for (let e of this.variables) e.value !== null && (a[e.name] = e.value);
1314
- for (let e of this.boolVars) e.value !== null && (a[e.name] = e.value);
1862
+ this.ensureExecutionValid(r, n, "check"), this.status = e.status, this.terminationStatus = a.signal?.aborted ? "Interrupted" : e.status, this.hasPrimalSolution = e.status === "Sat", this.runTime = e.runTime ?? 0, this.unsatCore = e.unsatCore === void 0 ? void 0 : Object.freeze([...e.unsatCore]);
1863
+ let t = {};
1864
+ if (e.values && e.status === "Sat") {
1865
+ for (let [n, r] of Object.entries(e.values)) if (typeof r == "number") {
1866
+ if (!Number.isFinite(r)) continue;
1867
+ let e = this.getVarByName(n), i = this.getBoolVarByName(n);
1868
+ e && (e.value = r, this.values.set(e.name, r), s(t, e.name, r)), i && (i.value = !!r, this.values.set(i.name, i.value), s(t, i.name, i.value)), !e && !i && (this.values.set(n, r), s(t, n, r));
1869
+ } else if (typeof r == "boolean") {
1870
+ let e = this.getBoolVarByName(n);
1871
+ e ? (e.value = r, this.values.set(e.name, r), s(t, e.name, r)) : (this.values.set(n, r), s(t, n, r));
1872
+ }
1315
1873
  }
1316
- return {
1317
- status: t ? "Sat" : i ? "Unsat" : "Unknown",
1318
- values: a,
1874
+ return this.hasSolutionState = !0, {
1875
+ status: e.status,
1876
+ values: t,
1877
+ unsatCore: this.unsatCore,
1878
+ conflicts: this.unsatCore,
1319
1879
  runTime: this.runTime
1320
1880
  };
1321
- } finally {
1322
- this.objective = i, this.sense = a;
1323
1881
  }
1882
+ let l = {
1883
+ name: this.name,
1884
+ sense: "Minimize",
1885
+ objective: new j(),
1886
+ constraints: this.constraints,
1887
+ variables: this.variables,
1888
+ logicalConstraints: this.logicalConstraints,
1889
+ boolVars: this.boolVars
1890
+ }, u;
1891
+ try {
1892
+ u = await i.solve(l, o);
1893
+ } catch (e) {
1894
+ throw this.activeOperationId === n && this.clearSolutionFields(), e;
1895
+ }
1896
+ this.ensureExecutionValid(r, n, "check"), this.runTime = u.runTime ?? 0;
1897
+ let d = u.status, f = u.terminationStatus ?? d, p = this.hasPrimalFromResult(u) || d === "Optimal" || d === "Feasible", m = p ? "Sat" : d === "Infeasible" ? "Unsat" : "Unknown";
1898
+ this.status = m, this.terminationStatus = a.signal?.aborted || f === "Interrupted" ? "Interrupted" : f === "Optimal" || f === "Feasible" || f === "Infeasible" ? m : f, this.hasPrimalSolution = p, this.objectiveValue = null, this.objectiveBound = void 0, this.relGap = void 0, this.mipGap = void 0, this.absGap = void 0, this.solution = null, this.values.clear();
1899
+ let h = {};
1900
+ if (p && u.values) {
1901
+ for (let [e, t] of Object.entries(u.values)) if (typeof t == "number" && Number.isFinite(t)) {
1902
+ let n = this.getVarByName(e), r = this.getBoolVarByName(e);
1903
+ n && (n.value = t, this.values.set(n.name, t), s(h, n.name, t)), r && (r.value = !!t, this.values.set(r.name, r.value), s(h, r.name, r.value)), !n && !r && (this.values.set(e, t), s(h, e, t));
1904
+ } else if (typeof t == "boolean") {
1905
+ let n = t, r = this.getBoolVarByName(e);
1906
+ r ? (r.value = n, this.values.set(r.name, n), s(h, r.name, n)) : (this.values.set(e, n), s(h, e, n));
1907
+ }
1908
+ }
1909
+ if (p && u.boolValues) for (let [e, t] of Object.entries(u.boolValues)) {
1910
+ if (typeof t != "boolean") continue;
1911
+ let n = this.getBoolVarByName(e);
1912
+ n ? (n.value = t, this.values.set(n.name, t), s(h, n.name, t)) : (this.values.set(e, t), s(h, e, t));
1913
+ }
1914
+ if (u.slacks) for (let [e, t] of Object.entries(u.slacks)) {
1915
+ if (typeof t != "number" || !Number.isFinite(t)) continue;
1916
+ let n = this.getConstraintByName(e);
1917
+ n && (n.slack = t);
1918
+ }
1919
+ return this.hasSolutionState = !0, {
1920
+ status: m,
1921
+ values: h,
1922
+ runTime: this.runTime
1923
+ };
1924
+ }
1925
+ validateSolution(e = {}) {
1926
+ return Ne(this, e);
1324
1927
  }
1325
1928
  };
1326
- w(/* @__PURE__ */ S({
1327
- BoolExpr: () => i,
1328
- BoolOp: () => o,
1329
- BoolVar: () => n,
1929
+ //#endregion
1930
+ //#region src/modeler/objective.ts
1931
+ function ze(e, t) {
1932
+ let n = e;
1933
+ if (n instanceof c || typeof n == "object" && n && "sense" in n && "lhs" in n && "rhs" in n) throw Error(`Cannot use a Constraint as an objective in ${t}(). Use model.constraint(expr\`... <= ...\`) for constraints, or supply an unconstrained arithmetic expression to ${t}().`);
1934
+ if (typeof n == "string" && /(<=|>=|==|=<|=>|=)/.test(n)) throw Error(`Cannot use a comparison constraint as an objective in ${t}(). Use model.constraint(expr\`... <= ...\`) for constraints, or supply an unconstrained arithmetic expression to ${t}().`);
1935
+ if (typeof n == "number") {
1936
+ if (!Number.isFinite(n)) throw Error(`Invalid non-finite objective constant "${n}" passed to ${t}().`);
1937
+ return n;
1938
+ }
1939
+ if (typeof n == "string" || n instanceof j || n instanceof A || n instanceof b || typeof n == "object" && n && ("terms" in n && n.terms instanceof Map && typeof n.constant == "number" || "quadTerms" in n && n.quadTerms instanceof Map && "linearTerms" in n && n.linearTerms instanceof Map && typeof n.constant == "number" || "id" in n && "name" in n && "lb" in n && "ub" in n)) return n;
1940
+ throw Error(`Invalid expression passed to ${t}(): expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.`);
1941
+ }
1942
+ function Be(e) {
1943
+ return {
1944
+ expr: ze(e, "maximize"),
1945
+ sense: "Maximize"
1946
+ };
1947
+ }
1948
+ function Ve(e) {
1949
+ return {
1950
+ expr: ze(e, "minimize"),
1951
+ sense: "Minimize"
1952
+ };
1953
+ }
1954
+ z(/* @__PURE__ */ se({
1955
+ BoolExpr: () => r,
1956
+ BoolOp: () => n,
1957
+ BoolVar: () => o,
1330
1958
  Constraint: () => c,
1331
- HiGHS: () => K,
1332
- HighsSolver: () => G,
1333
- LinExpr: () => O,
1334
- MockSolver: () => X,
1335
- Model: () => $,
1336
- OFFICIAL_HIGHS_CDN_WASM_URL: () => b,
1337
- QuadExpr: () => D,
1338
- Var: () => M,
1339
- and: () => e,
1340
- c: () => L,
1341
- dot: () => A,
1342
- expr: () => R,
1343
- generateLpString: () => B,
1344
- getHighs: () => g,
1345
- getHighsWasmUrl: () => v,
1346
- getSolver: () => f,
1347
- implies: () => a,
1348
- isValidWasmHeader: () => h,
1349
- listAvailableSolvers: () => u,
1350
- mapHighsStatus: () => W,
1351
- not: () => s,
1352
- or: () => t,
1353
- parseConstraint: () => F,
1354
- parseExpr: () => P,
1355
- probeWasmUrl: () => p,
1356
- registerHighsSolver: () => q,
1357
- registerMockSolver: () => Z,
1358
- registerSolver: () => d,
1359
- resolveBrowserWasmUrl: () => _,
1360
- setDefaultSolver: () => l,
1361
- setHighsWasmUrl: () => y,
1362
- solveLp: () => U,
1363
- solveLpWithHighs: () => m,
1364
- sum: () => k,
1365
- xor: () => r
1366
- }), Q);
1959
+ HiGHS: () => J,
1960
+ HighsSolver: () => q,
1961
+ LinExpr: () => j,
1962
+ MockSolver: () => ke,
1963
+ Model: () => Re,
1964
+ OFFICIAL_HIGHS_CDN_WASM_URL: () => te,
1965
+ QuadExpr: () => A,
1966
+ Var: () => b,
1967
+ and: () => y,
1968
+ buildIndicatorLinearization: () => X,
1969
+ buildLpSymbolMaps: () => u,
1970
+ deriveBigMForGe: () => Le,
1971
+ deriveBigMForLe: () => Ie,
1972
+ dot: () => s,
1973
+ expr: () => be,
1974
+ generateLpString: () => C,
1975
+ getHighs: () => F,
1976
+ getHighsWasmUrl: () => L,
1977
+ getSolver: () => D,
1978
+ implies: () => e,
1979
+ isLpExportResult: () => E,
1980
+ isValidWasmHeader: () => P,
1981
+ listAvailableSolvers: () => S,
1982
+ mapHighsStatus: () => K,
1983
+ mapHighsTerminationStatus: () => G,
1984
+ maximize: () => Be,
1985
+ minimize: () => Ve,
1986
+ not: () => v,
1987
+ or: () => i,
1988
+ parseConstraint: () => he,
1989
+ parseExpr: () => pe,
1990
+ probeWasmUrl: () => M,
1991
+ registerHighsSolver: () => Y,
1992
+ registerMockSolver: () => Ae,
1993
+ registerSolver: () => T,
1994
+ resolveBrowserWasmUrl: () => I,
1995
+ sanitizeIdentifier: () => f,
1996
+ setDefaultSolver: () => _,
1997
+ setHighsWasmUrl: () => R,
1998
+ solveLp: () => W,
1999
+ solveLpWithHighs: () => N,
2000
+ sum: () => t,
2001
+ validateModelIntegrity: () => k,
2002
+ validateModelSolution: () => Ne,
2003
+ validateUserBigM: () => Pe,
2004
+ xor: () => a
2005
+ }), je);
1367
2006
  //#endregion
1368
- export { 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 };
2007
+ export { r as BoolExpr, n as BoolOp, o as BoolVar, c as Constraint, J as HiGHS, q as HighsSolver, j as LinExpr, ke as MockSolver, Re as Model, A as QuadExpr, b as Var, y as and, X as buildIndicatorLinearization, u as buildLpSymbolMaps, Le as deriveBigMForGe, Ie as deriveBigMForLe, s as dot, be as expr, C as generateLpString, F as getHighs, L as getHighsWasmUrl, D as getSolver, e as implies, E as isLpExportResult, S as listAvailableSolvers, Be as maximize, Ve as minimize, le as normalizeSense, v as not, i as or, he as parseConstraint, pe as parseExpr, T as registerSolver, f as sanitizeIdentifier, _ as setDefaultSolver, R as setHighsWasmUrl, N as solveLpWithHighs, t as sum, k as validateModelIntegrity, Ne as validateModelSolution, Pe as validateUserBigM, a as xor };