|
Gecode 6.4.0
|
The additive version-1 bindings expose analyze_lp_sensitivity on an owning O1 observed result. They retain original IDs, selected basis, check diagnostics, and per-request availability. They perform no optimization solve and never turn an analysis into an ordinary solver Result. See the C++ sensitivity scope for the algorithm and numerical limits.
For the selected y basis, the example's objective-x coefficient range is [1,+infinity], objective-y is [-infinity,2], and common equality RHS is [0,+infinity]. These are absolute parameter values, varied one at a time for this selected basis/status assignment. They are not simultaneous-change ranges or ranges over all optimal bases. Objective slopes and limiter IDs use original coordinates and original objective sense; the objective offset is absent from the slope.
LpSensitivityResult.info separates Complete, Partial, Interrupted and Rejected analysis completion from each entry's group state/reason. A Partial result may contain accepted intervals and rejected requests. Every accepted interval is Numerical. No exact/certified option is offered. Original source termination and original O1 check results remain unchanged.
Copied dataclasses, source children and basis children survive closing the analysis, source, model or session. A selected basis still obeys the existing O2 source/revision compatibility checks. The analysis does not consult a live model after capture. Accessors do no solver, factorization or analysis work.
The initial supported source is an original continuous linear LP with timely Optimal O1 primal/dual checks and complete basis, analyzed through HiGHS/Auto. Native, MIP/semis, active indicators/globals, quadratic input, elided constant rows, unavailable basis, arbitrary replacement basis and inequality/range-side perturbations remain explicit rejections. To use an O2 result, first obtain its owning observed child. There is no implicit source solve or fallback.
LpSensitivityOptions contains purpose-built backend/time/cancellation, LpSensitivityTolerances, LpSensitivityLimits, and an explicit nonempty parameter tuple/list. It accepts no ignored SolveOptions fields. All eight C++ quotas are exposed. Limits are logical guardrails, not exact RSS/instruction bounds; time limits are cooperative across non-preemptive backend work.
One enclosing time allowance includes Python/C request preparation, C++ work, and input cleanup. Each layer deducts only its own preparation time. A whole operation limit clears every requested interval, even if completed earlier; source/basis/reference history remains available as diagnostics. The C and Python final cleanup checks apply to every index/bulk/ID interval view and its message, so a late result cannot retain stale accepted ranges.
work.preparation_visits counts C marshalling visits separately. One visit is charged per copied request and deducted once from runtime max_work. coordinator_visits retains the C++ count. Oversized request/work admission rejects before allocating/copying its array. Python uses a bounded sentinel only for this guaranteed C count-rejection path; it does not partially marshal or analyze an oversized request list.
basis_solves and max_basis_solves use attempted private factor-system calls. An allocation/argument failure may precede the underlying HiGHS FTRAN/BTRAN accessor. Factor setup has its separate attempted flag. These counts are not optimization runs or iterations.
Cancellation.copy() and C cancellation_copy produce independent owners of the same cancellation state. Closing one owner leaves the others usable; cancellation through any owner reaches all of them. cancelled / cancellation_is_cancelled reads the state. O4 Python retains a private owner through the call and final cleanup check, so explicitly closing the caller's token after admission cannot discard a returned analysis. Invalid options keep their original rejection precedence even with a stopped token or negative time.
The new records/symbols are in c_api.h, under sensitivity_* and analyze_lp_sensitivity. Existing ABI-1 record layouts are unchanged. The input is an observed-result token of the correct registry kind; ordinary Result, Model, Session, evidence, and quadratic tokens are rejected.
All new outer/nested/request record sizes must match exactly and reserved input fields must be zero. Numeric optional values have explicit presence. Outputs initialize sizes and reserved fields; counted text includes NUL. NULL with zero capacity queries a bulk/text size; a short buffer writes no elements. Default options leave the request list empty, requiring an explicit list. Invalid ABI shape returns the usual error and a zero output token. Safe semantic admission returns structured analysis rejection. NO_SENSITIVITY distinguishes a missing artifact; source copy and outer info/work/message remain usable.
The independent binding panel covers analytic min/max endpoints and offsets, logical-basis singletons, real numerical Partial results, typed IDs/tombstones, source/basis ownership, malformed records, counted buffers, quota accounting, invalid-option precedence and final cleanup. The private C++ cleanup fixture compiles its own C API object with GECODE_OPTIMIZE_TEST_SENSITIVITY_BINDING and GECODE_OPT_C_API_EXPORTS, then links only the C++ facade; it must not also link the ordinary C wrapper. The hook is absent from production. Python uses deterministic post-call cancellation/clock hooks to check its separate cleanup and token-close boundary. All standalone C/cleanup fixtures undefine NDEBUG to keep assertions active in Release. Build results and exact frozen dependency hashes are recorded with the binding evidence separately; this panel makes no performance claim.
The final isolated binding panel passed on macOS arm64: C99 against normal HiGHS/native, backend-off core, and fully instrumented standalone HiGHS; the private cleanup fixture against normal and instrumented HiGHS; and all 83 Python tests in each of those three variants. Backend-off cases verify explicit rejection and ownership rather than executing supported intervals. The instrumented Python run used the Framework Python 3.14 executable with Clang's ASan runtime preloaded, ASAN_OPTIONS=detect_leaks=0:halt_on_error=1 and UBSAN_OPTIONS=halt_on_error=1. It completed all 83 tests in 2.389 seconds without a sanitizer finding. Leak detection was disabled, and this run does not instrument the Python interpreter itself.
The saved evidence directory is implementation/agents/results/build/lp-sensitivity-bindings in this workspace. It retains per-command JSON, compile/link/run logs and completion-artifacts.json with SHA-256 hashes of the final source, frozen facade inputs and instrumented outputs. Its instrumented C wrapper hash is 30f0e3ddfa1c4f57d51a8b18fe5f12e22303077a16fb908219bc42839661d01f. These are isolated binding checks; the combined branch regression and performance comparison are separate integration gates.