@ohtaman/washi 0.3.0 → 0.4.0

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