@ohtaman/washi 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +55 -20
- package/README.md +55 -20
- package/README.zh-CN.md +55 -20
- package/THIRD_PARTY_LICENSES.md +3 -4
- package/dist/browser/_washi-node-only-BvRk9kiK.js +0 -0
- package/dist/browser/browser-runtime-TLCY0hkc.js +1793 -0
- package/dist/browser/highs-worker.js +1 -1
- package/dist/browser/highs.wasm +0 -0
- package/dist/browser/highs.wasm.LICENSE +1 -2
- package/dist/browser/loader-DewlSho8.js +643 -0
- package/dist/browser/solvers/glpk.js +1 -1
- package/dist/browser/solvers/glpk.min.js +1 -1
- package/dist/browser/solvers/z3.js +7 -1
- package/dist/browser/solvers/z3.min.js +1 -1
- package/dist/browser/washi.js +1096 -444
- package/dist/browser/washi.min.js +3 -4
- package/dist/lib/_washi-node-only-BvRk9kiK.js +0 -0
- package/dist/lib/highs-browser-runtime.js +2120 -4124
- package/dist/lib/highs-node-runtime.js +24 -1
- package/dist/lib/highs-runtime.js +2 -0
- package/dist/lib/highs-worker.js +1 -1
- package/dist/lib/highs.wasm +0 -0
- package/dist/lib/highs.wasm.LICENSE +1 -2
- package/dist/lib/loader-BZUQNvh4.js +649 -0
- package/dist/lib/{registry-BEfvpZW3.js → registry-C20sxTwm.js} +54 -41
- package/dist/lib/solvers/glpk.js +2 -2
- package/dist/lib/solvers/z3.js +1 -1
- package/dist/lib/washi.js +973 -305
- package/dist/types/decomposition/benders.d.ts +32 -0
- package/dist/types/decomposition/benders.d.ts.map +1 -0
- package/dist/types/decomposition/column-generation.d.ts +34 -0
- package/dist/types/decomposition/column-generation.d.ts.map +1 -0
- package/dist/types/decomposition/index.d.ts +4 -0
- package/dist/types/decomposition/index.d.ts.map +1 -0
- package/dist/types/decomposition/types.d.ts +230 -0
- package/dist/types/decomposition/types.d.ts.map +1 -0
- package/dist/types/index.d.ts +4 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/modeler/boolean-expr.d.ts.map +1 -1
- package/dist/types/modeler/constraint.d.ts +11 -0
- package/dist/types/modeler/constraint.d.ts.map +1 -1
- package/dist/types/modeler/expression.d.ts +10 -0
- package/dist/types/modeler/expression.d.ts.map +1 -1
- package/dist/types/modeler/index.d.ts +2 -1
- package/dist/types/modeler/index.d.ts.map +1 -1
- package/dist/types/modeler/linearizer.d.ts +15 -0
- package/dist/types/modeler/linearizer.d.ts.map +1 -0
- package/dist/types/modeler/lp-writer.d.ts +3 -1
- package/dist/types/modeler/lp-writer.d.ts.map +1 -1
- package/dist/types/modeler/model.d.ts +147 -2
- package/dist/types/modeler/model.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/browser-runtime.d.ts +2 -1
- package/dist/types/modeler/solvers/highs/browser-runtime.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/driver.d.ts +232 -0
- package/dist/types/modeler/solvers/highs/driver.d.ts.map +1 -0
- package/dist/types/modeler/solvers/highs/index.d.ts +1 -0
- package/dist/types/modeler/solvers/highs/index.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/loader.d.ts +4 -4
- package/dist/types/modeler/solvers/highs/loader.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/node-runtime.d.ts +2 -1
- package/dist/types/modeler/solvers/highs/node-runtime.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/solver.d.ts +1 -1
- package/dist/types/modeler/solvers/highs/solver.d.ts.map +1 -1
- package/dist/types/modeler/solvers/types.d.ts +2 -0
- package/dist/types/modeler/solvers/types.d.ts.map +1 -1
- package/dist/types/modeler/types.d.ts +27 -0
- package/dist/types/modeler/types.d.ts.map +1 -1
- package/docs/examples/index.md +4 -0
- package/docs/examples/traveling-salesperson.md +173 -0
- package/docs/examples/vehicle-routing.md +206 -0
- package/docs/getting-started/ai-agents.md +8 -4
- package/docs/guide/constraints.md +1 -1
- package/docs/guide/decomposition.md +399 -0
- package/docs/guide/unsat-core.md +10 -3
- package/docs/ja/getting-started/ai-agents.md +8 -4
- package/docs/solvers/custom-solver.md +1 -1
- package/docs/solvers/highs.md +25 -3
- package/docs/solvers/index.md +3 -3
- package/docs/zh/getting-started/ai-agents.md +8 -4
- package/llms-full.txt +831 -15
- package/llms.txt +9 -5
- package/package.json +17 -14
- package/skills/washi/SKILL.md +8 -8
- package/dist/browser/browser-runtime-D13gHOT5.js +0 -4189
- package/dist/browser/loader-CtaDHef_.js +0 -273
- package/dist/lib/loader-DmNC_UNk.js +0 -279
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# WaSHI (@ohtaman/washi)
|
|
2
2
|
|
|
3
|
-
> WaSHI: WebAssembly-backed
|
|
3
|
+
> WaSHI: WebAssembly-backed Algebraic Modeler for Mathematical Optimization & Constraint Programming (LP, MIP, QP, SMT)
|
|
4
4
|
|
|
5
5
|
WaSHI brings the algebraic modeling style of Python's **PuLP** and Julia's **JuMP** to the TypeScript and JavaScript ecosystem.
|
|
6
6
|
|
|
@@ -130,9 +130,10 @@ m.indicator(b, expr`${x} <= 50`, { activeValue: 1, name: "cap_when_b" });
|
|
|
130
130
|
- Returns `SolverStatus` (`"Optimal"`, `"Feasible"`, `"Infeasible"`, `"Unbounded"`, `"TimeLimit"`, `"IterationLimit"`, `"Error"`, `"Unknown"`, `"NotSolved"`, `"Sat"`, or `"Unsat"`). Built-in optimization solvers return the optimization statuses (`"Optimal"`, `"Feasible"`, `"Infeasible"`, `"Unbounded"`, `"TimeLimit"`, `"IterationLimit"`, `"Error"`, `"Unknown"`, `"NotSolved"`), where a time-, iteration-, or solution-limited run (or an interrupted solve) that found a valid primal incumbent returns `"Feasible"`; `"Sat"` and `"Unsat"` are included in `SolverStatus` for satisfiability/custom solver adapters (such as `MockSolver`).
|
|
131
131
|
- Read values via `x.value`, `expr`...`.value`, `m.getValues(x)`, `m.getValues(container)`, `m.objectiveValue`, `constr.dual`, `constr.slack`, and `x.reducedCost`.
|
|
132
132
|
- Call `m.validateSolution()` after solving to independently verify variable finiteness, variable bounds (`lb`/`ub`), integer/binary/boolean domains, linear constraint residuals, and logical constraints (`SolutionValidationReport`: `{ valid, complete, maxViolation, violations, ... }`). Note that `validateSolution()` checks primal feasibility of variables and constraints; it does not recompute or compare `m.objectiveValue`.
|
|
133
|
-
- **Satisfiability &
|
|
134
|
-
- Returns `CheckResult` (`{ status: "Sat" | "Unsat" | "Unknown", values: Record<string, number | boolean>, conflicts?: readonly string[], unsatCore?: readonly string[], runTime?: number }`), where `conflicts`
|
|
135
|
-
- For models containing
|
|
133
|
+
- **Satisfiability & Conflict Diagnosis (`await m.check(options?)`)**:
|
|
134
|
+
- Returns `CheckResult` (`{ status: "Sat" | "Unsat" | "Unknown", values: Record<string, number | boolean>, conflicts?: readonly string[], unsatCore?: readonly string[], runTime?: number }`), where `conflicts` is populated when the model is proven `"Unsat"`.
|
|
135
|
+
- For models containing linear arithmetic constraints or logical constraints (`BoolVar`, `and`, `or`, `implies`, `xor`), `m.check()` works with any solver (including the default HiGHS and GLPK via single-solve elastic slack relaxation, automatically linearizing logical constraints into 0-1 MIP formulation) and diagnoses conflicting constraints as `conflicts` (leaving `unsatCore: undefined` for semantic rigor).
|
|
136
|
+
- Exact SMT unsatisfiable-core extraction (`result.unsatCore` and `result.conflicts`) is provided when using an SMT-capable solver (`{ solver: "z3" }`). Because Z3 asserts variable bounds (`lb`/`ub`) and binary `{0, 1}` domains directly while tracking registered constraints, `unsatCore` reports a subset of registered constraint names that conflicts *together with the model's fixed variable bounds/domains* (and is not guaranteed minimal).
|
|
136
137
|
- **No concurrent mutation during async solve/check**:
|
|
137
138
|
- Mutating variables, constraints, or the objective while `await m.solve()` or `await m.check()` is pending invalidates the in-flight execution and rejects the stale promise.
|
|
138
139
|
|
|
@@ -174,11 +175,12 @@ m.indicator(b, expr`${x} <= 50`, { activeValue: 1, name: "cap_when_b" });
|
|
|
174
175
|
- [Constraints (`m.constraint` & `m.indicator`)](docs/guide/constraints.md): Constraints restrict the feasible solution space of your mathematical or logical model.
|
|
175
176
|
- [Objectives & Solving (`m.solve` & `m.check`)](docs/guide/objectives.md): The objective function defines the goal of mathematical optimization—whether to maximize profits, minimize costs, or minimize quadratic risk variance.
|
|
176
177
|
- [Conflict Diagnosis (`unsatCore`) & Solution Validation](docs/guide/unsat-core.md): WaSHI provides built-in tools for both: **Unsat Core conflict diagnosis** via Z3 (`m.check()`), **independent solution validation** (`m.validateSolution()`), **LP formulation export** (`m.toLpString()`), and **fast unit testing** (`MockSolver`).
|
|
178
|
+
- [Advanced Decomposition Methods & Best Practices](docs/guide/decomposition.md): Mixed-Integer Programming (MIP) formulations can become slow when symmetry or coupling constraints cause branch-and-bound trees to grow large.
|
|
177
179
|
|
|
178
180
|
### Solvers
|
|
179
181
|
|
|
180
182
|
- [Solvers Overview](docs/solvers/index.md): WaSHI is designed around a pluggable, decoupled solver architecture.
|
|
181
|
-
- [HiGHS Solver Engine](docs/solvers/highs.md): **HiGHS** is high-performance mathematical optimization software developed at the University of Edinburgh.
|
|
183
|
+
- [HiGHS Solver Engine](docs/solvers/highs.md): **HiGHS** is high-performance mathematical optimization software developed at the University of Edinburgh (ERGO-Code/HiGHS).
|
|
182
184
|
- [Z3 SMT Solver Engine](docs/solvers/z3.md): **Z3** is a theorem prover and Satisfiability Modulo Theories (SMT) solver developed by Microsoft Research.
|
|
183
185
|
- [GLPK Solver Engine](docs/solvers/glpk.md): The **GNU Linear Programming Kit (GLPK)** is a long-standing, robust simplex and interior-point solver package intended for solving large-scale linear programming (LP) and mixed integer programming (MIP).
|
|
184
186
|
- [WaSHI Custom Solver Developer Guide](docs/solvers/custom-solver.md): This guide describes how to build, test, and distribute custom solver plugins for **WaSHI** (`@ohtaman/washi`).
|
|
@@ -195,3 +197,5 @@ m.indicator(b, expr`${x} <= 50`, { activeValue: 1, name: "cap_when_b" });
|
|
|
195
197
|
- [Portfolio Optimization (QP)](docs/examples/portfolio-qp.md): The Markowitz mean-variance portfolio optimization problem is the foundation of modern quantitative finance: allocate capital across risky assets to minimize overall portfolio variance (risk) subject to achieving a minimum required expected return.
|
|
196
198
|
- [SMT Security Policies](docs/examples/smt-security.md): Satisfiability Modulo Theories (SMT) combines propositional logic (Boolean SAT) with first-order theories (linear integer arithmetic, real inequalities).
|
|
197
199
|
- [Conflict Diagnosis (Unsat Core)](docs/examples/unsat-core.md): When business rules, budgets, and operational policies grow complex, constraints inevitably conflict.
|
|
200
|
+
- [Capacitated Vehicle Routing Problem (CVRP, 50 Customers via Column Generation)](docs/examples/vehicle-routing.md): The **Capacitated Vehicle Routing Problem (CVRP)** determines the minimum number of delivery vehicles needed to visit a set of customers, subject to vehicle cargo capacity, maximum customer stops per shift, and route duration limits.
|
|
201
|
+
- [Traveling Salesperson Problem (TSP via Benders Decomposition)](docs/examples/traveling-salesperson.md): The **Traveling Salesperson Problem (TSP)** seeks the shortest closed tour that visits every city in a given set once and returns to the starting city.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ohtaman/washi",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "WaSHI: WebAssembly-backed
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "WaSHI: WebAssembly-backed Algebraic Modeler for Mathematical Optimization & Constraint Programming (LP, MIP, QP, SMT)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/lib/washi.js",
|
|
7
7
|
"module": "./dist/lib/washi.js",
|
|
@@ -66,35 +66,39 @@
|
|
|
66
66
|
],
|
|
67
67
|
"scripts": {
|
|
68
68
|
"dev": "vite",
|
|
69
|
+
"ensure:highs": "node scripts/ensure-highs-wasm.mjs",
|
|
70
|
+
"build:highs-wasm": "bash scripts/build-highs-wasm.sh",
|
|
69
71
|
"build:demo": "vite build",
|
|
70
72
|
"build:types": "node -e \"import('node:fs').then(fs => fs.rmSync('dist/types', { recursive: true, force: true }))\" && tsc -p tsconfig.lib.json",
|
|
71
|
-
"build:lib": "node scripts/build-library.mjs",
|
|
73
|
+
"build:lib": "node scripts/ensure-highs-wasm.mjs && node scripts/build-library.mjs",
|
|
72
74
|
"build:llms": "node scripts/generate-llms.mjs",
|
|
73
|
-
"build": "npm run build:types && npm run build:lib && npm run build:browser && npm run build:demo",
|
|
74
|
-
"build:site": "node scripts/build-site.mjs",
|
|
75
|
+
"build": "node scripts/ensure-highs-wasm.mjs && npm run build:types && npm run build:lib && npm run build:browser && npm run build:demo",
|
|
76
|
+
"build:site": "node scripts/ensure-highs-wasm.mjs && node scripts/build-site.mjs",
|
|
75
77
|
"docs:dev": "vitepress dev docs",
|
|
76
78
|
"docs:build": "vitepress build docs && node scripts/generate-llms.mjs",
|
|
77
79
|
"docs:preview": "vitepress preview docs",
|
|
78
80
|
"preview": "vite preview",
|
|
79
81
|
"test": "vitest run",
|
|
80
82
|
"test:e2e": "RUN_E2E=1 vitest run test/e2e.test.ts",
|
|
81
|
-
"prepublishOnly": "npm run build:types && npm run build:lib && npm run build:browser && npm run build:llms",
|
|
82
|
-
"build:browser": "node scripts/build-browser.mjs",
|
|
83
|
-
"test:distribution": "npm run build:types && npm run build:lib && npm run build:browser && npm run build:llms && node --experimental-vm-modules scripts/check-distribution.mjs",
|
|
83
|
+
"prepublishOnly": "node scripts/ensure-highs-wasm.mjs && npm run build:types && npm run build:lib && npm run build:browser && npm run build:llms",
|
|
84
|
+
"build:browser": "node scripts/ensure-highs-wasm.mjs && node scripts/build-browser.mjs",
|
|
85
|
+
"test:distribution": "node scripts/ensure-highs-wasm.mjs && npm run build:types && npm run build:lib && npm run build:browser && npm run build:llms && node --experimental-vm-modules scripts/check-distribution.mjs",
|
|
84
86
|
"test:demo": "BASE_URL=/washi/ npm run build:demo && node scripts/check-demo-browser.mjs",
|
|
85
87
|
"bench": "node scripts/run-benchmarks.mjs"
|
|
86
88
|
},
|
|
87
89
|
"keywords": [
|
|
88
90
|
"optimization",
|
|
89
91
|
"mathematical-programming",
|
|
92
|
+
"constraint-programming",
|
|
90
93
|
"linear-programming",
|
|
91
94
|
"mixed-integer-programming",
|
|
92
95
|
"quadratic-programming",
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"qp",
|
|
96
|
+
"smt",
|
|
97
|
+
"z3",
|
|
96
98
|
"highs",
|
|
97
99
|
"pulp",
|
|
100
|
+
"jump",
|
|
101
|
+
"operations-research",
|
|
98
102
|
"wasm",
|
|
99
103
|
"webassembly",
|
|
100
104
|
"typescript"
|
|
@@ -113,9 +117,7 @@
|
|
|
113
117
|
"url": "https://github.com/ohtaman/washi/issues"
|
|
114
118
|
},
|
|
115
119
|
"homepage": "https://github.com/ohtaman/washi#readme",
|
|
116
|
-
"dependencies": {
|
|
117
|
-
"highs": "^1.15.3"
|
|
118
|
-
},
|
|
120
|
+
"dependencies": {},
|
|
119
121
|
"peerDependencies": {
|
|
120
122
|
"glpk.js": "^5.0.0",
|
|
121
123
|
"z3-solver": "^5.2.0"
|
|
@@ -132,6 +134,7 @@
|
|
|
132
134
|
"@types/node": "^26.6.3",
|
|
133
135
|
"async-mutex": "^0.3.2",
|
|
134
136
|
"glpk.js": "^5.0.0",
|
|
137
|
+
"katex": "^0.16.21",
|
|
135
138
|
"mermaid": "^11.17.2",
|
|
136
139
|
"playwright": "^1.63.0",
|
|
137
140
|
"typescript": "^7.0.2",
|
package/skills/washi/SKILL.md
CHANGED
|
@@ -16,9 +16,9 @@ Select the solver engine and execution method that match the problem class:
|
|
|
16
16
|
| Problem Class | Recommended Solver | Setup & Import | Execution Method |
|
|
17
17
|
| :--- | :--- | :--- | :--- |
|
|
18
18
|
| **LP / MIP / Convex QP** (including `m.indicator()` Big-M and `initialValue` warm starts) | **HiGHS** (default) | Built-in (`import { Model } from "@ohtaman/washi"`) | `await m.solve()` |
|
|
19
|
-
| **SMT Propositional Logic** (`BoolVar`, `and`, `or`, `not`, `implies`, `xor`) | **Z3**
|
|
20
|
-
| **Infeasibility / Conflict Diagnosis** (`conflicts` / `unsatCore`) | **
|
|
21
|
-
| **LP / MIP with GLPK** (GPL-3.0; no QP
|
|
19
|
+
| **SMT Propositional Logic** (`BoolVar`, `and`, `or`, `not`, `implies`, `xor`) | **HiGHS** (auto 0-1 MIP) or **Z3** (native SMT) | Built-in for HiGHS; `npm install z3-solver` + `import "@ohtaman/washi/solvers/z3"` for Z3 | `await m.solve()` or `await m.check()` |
|
|
20
|
+
| **Infeasibility / Conflict Diagnosis** (`conflicts` / `unsatCore`) | **HiGHS** (elastic slack `conflicts`) or **Z3** (`unsatCore`) | Built-in for HiGHS; `import "@ohtaman/washi/solvers/z3"` for Z3 | `await m.check()` |
|
|
21
|
+
| **LP / MIP with GLPK** (GPL-3.0; no QP or `initialValue`) | **GLPK** plugin | `npm install glpk.js` + `import "@ohtaman/washi/solvers/glpk"` | `await m.solve({ solver: "glpk" })` |
|
|
22
22
|
|
|
23
23
|
- **Browser runtime notes**:
|
|
24
24
|
- HiGHS and GLPK load local `.wasm` and Worker assets relative to the bundle (never falling back to an external CDN).
|
|
@@ -30,7 +30,7 @@ Select the solver engine and execution method that match the problem class:
|
|
|
30
30
|
|
|
31
31
|
1. **Define decision variables on `Model`**:
|
|
32
32
|
- Numeric (`Var`): `m.continuous(nameOrDims, { lb, ub, initialValue })`, `m.integer(...)`, `m.binary(...)`
|
|
33
|
-
- Propositional boolean (`BoolVar
|
|
33
|
+
- Propositional boolean (`BoolVar`): `m.bool(nameOrDims)`
|
|
34
34
|
- Indexed containers: pass a count (`number` -> `Var[]` / `Var[][]`) or key array (`readonly string[]` -> `Record<K, Var>` / `Record<R, Record<C, Var>>`).
|
|
35
35
|
- Provide finite `lb` and `ub` bounds whenever known—especially on variables used in `m.indicator()` so WaSHI can automatically derive a tight Big-M when `M` is omitted.
|
|
36
36
|
2. **Build expressions (`expr`, `sum`, `dot`)**:
|
|
@@ -38,11 +38,11 @@ Select the solver engine and execution method that match the problem class:
|
|
|
38
38
|
- Quadratic expression (`QuadExpr`, **objectives only**): `` expr`${x}^2 + 2 * ${x} * ${y} + ${y}^2` ``
|
|
39
39
|
- Linear constraint (`Constraint`): `` expr`${x} + 2 * ${y} <= 40` `` (supports `<=`, `>=`, `==`, `=`)
|
|
40
40
|
- Vector aggregations: `sum(iterable, mapper?)` and `dot(a, b)`
|
|
41
|
-
- Propositional logic
|
|
41
|
+
- Propositional logic: `and(...)`, `or(...)`, `not(...)`, `implies(a, b)`, `xor(a, b)` (or fluent `.and()`, `.or()`, `.not()`, `.implies()`, `.xor()`). Automatically linearized into 0-1 MIP binary variables and linear constraints on HiGHS/GLPK, or solved natively on Z3.
|
|
42
42
|
3. **Register objective and named constraints**:
|
|
43
43
|
- Constructing an `expr` or `.le()` / `.ge()` / `.eq()` object does **not** attach it to the model.
|
|
44
44
|
- Register the objective with `m.objective(maximize(e))` or `m.objective(minimize(e))`.
|
|
45
|
-
- Register every constraint with a descriptive name: `m.constraint(c, "resource_limit")` or `m.indicator(binVar, c, { activeValue: 1, name: "cap_when_open" })`. Descriptive names are essential for LP inspection and
|
|
45
|
+
- Register every constraint with a descriptive name: `m.constraint(c, "resource_limit")` or `m.indicator(binVar, c, { activeValue: 1, name: "cap_when_open" })`. Descriptive names are essential for LP inspection and conflict diagnosis (`conflicts` / `unsatCore`).
|
|
46
46
|
|
|
47
47
|
---
|
|
48
48
|
|
|
@@ -65,8 +65,8 @@ Never report a model solution as final without executing the verification step:
|
|
|
65
65
|
- If `report.valid === false`, inspect `report.violations`, `report.missingVariables`, `report.uncheckedConstraints`, and `report.maxViolation`.
|
|
66
66
|
- Note: `m.validateSolution()` independently checks variable finiteness, variable bounds (`lb`/`ub`), integrality (`Integer`, `Binary`, `BoolVar`), linear constraint residuals, and logical constraints. It does **not** recompute `m.objectiveValue` or verify natural-language problem coverage.
|
|
67
67
|
2. **When a model is infeasible (`"Infeasible"` or `"Unsat"`)**:
|
|
68
|
-
- Run `const res = await m.check({ solver: "z3" })
|
|
69
|
-
- When `res.status === "Unsat"`, inspect `res.conflicts` (
|
|
68
|
+
- Run `const res = await m.check()` (diagnoses with built-in HiGHS via single-solve elastic slack relaxation) or `const res = await m.check({ solver: "z3" })` (for exact SMT unsat core).
|
|
69
|
+
- When `res.status === "Unsat"`, inspect `res.conflicts` (also stored on `m.conflicts`). On HiGHS, `conflicts` reports the subset of constraints requiring relaxation to restore feasibility (with `unsatCore: undefined` for semantic rigor). On Z3, both `unsatCore` and `conflicts` report the contradictory constraint subset.
|
|
70
70
|
- Because Z3 asserts variable bounds (`lb`/`ub`) and binary `{0, 1}` domains directly while tracking named constraints, `res.conflicts` returns a subset of registered constraint names that conflicts *together with the model's fixed variable bounds/domains* (not guaranteed minimal).
|
|
71
71
|
|
|
72
72
|
---
|