Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | 1x 1x 5x 5x 5x 5x 1x 4x 4x 2x 2x 2x 2x 1x 2x 2x | /** @external {minizinc} https://www.npmjs.com/package/minizinc */
import { Model, init, solvers } from "../../assets/vendor/minizinc.mjs";
/**
* Initialize the MiniZinc WASM engine; must run before any solveModel() call.
* @return {Promise<Array<Object>>} List of available solvers (each with id etc.).
*/
export async function initSolvers() {
await init();
return solvers();
}
/**
* Wrap MiniZinc's event-based solver as a Promise.
* Implements the solve() call from Thesis' Algorithm.
* @param {string} modelName - Virtual filename for the MZN engine.
* @param {string} modelString - MZN source: variables + hard constraints (H) + optional objective (S).
* @param {string} solverId - Backend id (e.g. "gecode").
* @return {Promise<{solution: ?Object, statistics: ?Object, status: string}>}
* @throws {Error} If the solver fails to initialize, or wraps any solver-side failure via cause-chain.
*/
export async function solveModel(modelName, modelString, solverId) {
const model = new Model();
model.addFile(modelName, modelString);
const solve = model.solve({
options: { solver: solverId, statistics: true },
});
if (!solve) {
throw new Error(`Solver '${solverId}' failed to initialize.`);
}
let result;
try {
result = await solve;
} catch (e) {
console.error("Solver error:", e, JSON.stringify(e));
const detail =
[e?.message, e?.stderr, e?.output].find(Boolean) ?? JSON.stringify(e);
throw new Error(
`Solver failed (code ${e?.code}, type ${e?.type}): ${detail}`,
{ cause: e },
);
}
if (!["SATISFIED", "OPTIMAL_SOLUTION"].includes(result.status)) {
console.info(`Solver status: ${result.status}`, result);
}
const { solution, statistics, status } = result;
return { solution, statistics, status };
}
|