ULSAlgorithms executes its portable LinearModel with the first usable engine selected from the repository-wide priority:
This execution layer is used directly by the four solver-backed formulation strategies and by both (l,S) cutting-plane strategies.
For a mixed-integer model the orchestration layer automatically requires MixedIntegerLinearProgramming; for a continuous model it requires LinearProgramming.
An explicitly requested solver is strict by default. Set AllowFallbackWhenExplicit = true only when fallback is desired.
The discovery layer first validates the CPLEX runtime. Execution then invokes the stand-alone cplex program from the selected CPLEX runtime directory, submits the portable LP file and parses the XML .sol file.
The backend invokes gurobi_cl with a ResultFile solution target and parses portable v_<id> variable names.
The backend reuses the optional Optimizer.dll runtime and invokes XPRSprob.ReadProb, Optimize and GetSolution through reflection. Variable values are mapped by portable column name where the loaded Xpress API exposes GetIndex, with a column-order fallback only when vector length is exact.
The backend invokes the stand-alone cbc executable with -solve and -solu and parses the generated text solution.
The v0.29.0 qualification pipeline exercises CBC end to end against all six public solver-backed strategies with fallback disabled.
The LP writer uses:
instead of semantic names such as x[0] or q[2,7]. This makes solution parsing independent of punctuation and solver-specific name normalization.
The original semantic mapping remains available in UlsFormulation.Variables.
Before the independent checker sees a solver solution, raw floating-point values are normalized.
Repository defaults are:
Examples:
Normalization and feasibility checking deliberately solve different numerical problems:
For a constraint with right-hand side b, coefficients a_i and returned values x_i, the checker uses the row scale
\[s = \max\left(1,\lvert b\rvert,\sum_i \lvert a_i x_i\rvert\right). \]
A constraint is accepted when
\[\frac{\text{absolute violation}}{s} \le \text{FeasibilityTolerance}. \]
The scale floor of one preserves the original absolute protection for small rows, while larger rows are not falsely rejected because of harmless floating-point/text-solution residuals.
MaximumConstraintViolation remains the raw absolute diagnostic value; the scaled value is used internally for the feasibility decision.
A returned native solution is never trusted solely because an optimization engine reports "optimal".
LinearModelSolutionValidator independently checks:
If a native solver reports an optimal or feasible solution that fails this independent check, the normalized result is Failed, not Optimal.
The validation report exposes:
LinearModelSolveResult records:
Set KeepTemporaryFiles = true to retain the exact LP, solution and provider artifacts. ExportModelPath can also save the exact submitted LP model without retaining the complete temporary directory.
The generic execution layer is fully connected to the public ULS Strategy surface.
For the four formulation strategies, the path is:
The current formulation strategies are:
Each implements both IUlsSolver and IAsyncUlsSolver.
The two (l,S) cutting-plane strategies reuse the same execution layer for root LP solves and the final strengthened MILP. Their final result retains solver provenance together with cutting-plane trace/convergence information.
Therefore solver discovery, model execution, numerical validation, formulation reconstruction and cutting-plane execution now form one completed end-to-end architecture rather than separate future layers.