You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is the design and tracking issue for the repository-wide numeric-domain contract. It separates three concerns that the current catalog often mixes:
the mathematical domain of a quantity;
its Rust representation inside models and reductions;
the numeric representation accepted by an external solver.
This issue defines the contract and coordinates focused follow-up migrations. It is not a request for one PR to migrate the entire catalog, redesign ILP and QUBO, change reduction execution, update HiGHS, and enable every cast lint at once.
Motivation
A mathematical variant may change the accepted instance set or a reduction precondition, such as unit, integer, or real weights. Changing storage width from i32 to i64 does not create a new mathematical problem.
Likewise, an exact integer model must not silently lose ordering or feasibility information merely because a reduction target or numerical solver uses f64. For example, the exact integers 9_007_199_254_740_992 and 9_007_199_254_740_993 are distinct, but a conversion to f64 may collapse them.
Checked conversion at boundaries where another encoding is required
Unit weight
One
Represents the mathematical constant one
Ordinary bounded exact integer, including semantically nonnegative quantities
i64
All arithmetic remains in i64; construction or reduction rejects instances whose required values do not fit
Approximate real input
finite f64
All arithmetic remains in f64; NaN and both infinities are rejected
Problem-native arbitrary-precision integer
BigInt or BigUint
Used only when arbitrary precision is part of the problem definition, such as Factoring
SAT literal or another compact protocol encoding
the protocol-required type
The encoding range is validated explicitly
The existing catalog labels One / i64 / f64 are retained to minimize churn. Their meanings are unit, ordinary bounded exact integer, and approximate real respectively. The i32 weight/coefficient variant is replaced rather than retained as a compatibility alias.
Storage width, signedness, and solver storage alone do not justify a mathematical variant. A problem-native arbitrary-precision representation also does not create a storage variant when arbitrary precision is inherent in that problem's mathematical input domain.
Arithmetic and validation
Arithmetic uses the representation of the declared mathematical domain. Ordinary exact integers use checked i64 addition, subtraction, multiplication, division, and related operations. Approximate reals use finite f64 operations.
Do not widen ordinary i64 calculations to i128, BigInt, or another larger type to rescue an instance that does not fit the chosen domain.
Constructors and reductions must validate that every required input and derived value is representable in the model's declared domain. If an ordinary exact result would exceed i64, construction or reduction returns an explicit overflow error.
evaluate() operates only on already validated instances. It must not contain fallback widening, overflow recovery, saturation, wrapping, or silent approximation.
A semantically nonnegative field uses i64 and rejects -1.
BigInt or BigUint is used when the problem definition itself requires arbitrary-precision values, for example Factoring or a problem whose mathematical object is an explicitly large bit string interpreted as an integer. This is a model-specific domain decision, not a generic intermediate-arithmetic policy.
A user-provided approximate value such as 0.1 remains the supplied finite f64; it is not rationalized or scaled into an integer.
JSON, serde, CLI, MCP, evaluation, and reductions must enforce the same domain contract.
Exact integer to approximate real
Mathematically, integers embed into the reals. In the implementation, an i64 → f64 conversion may lose precision and is therefore explicit and fallible.
Two boundaries must be treated separately:
Reduction boundary: an exact-to-approximate model conversion is valid only when that concrete model can establish that feasibility, equality, objective values, and objective ordering required by the reduction are preserved. The check is model-specific; this issue does not mandate one global formula such as n_terms * max|coefficient| ≤ 2^53.
Solver boundary: when pred solve invokes a double-based backend such as HiGHS, the adapter checks every exact integer value it converts and returns an explicit precision-loss error before invoking the backend if faithful conversion is impossible.
A blanket infallible as f64 cast is invalid at either boundary. Whether and how the reduction graph represents a fallible natural edge is a focused follow-up design problem, not part of the core representation migration.
Solver tolerances remain solver semantics; they are not mathematical reduction semantics.
Scope of this tracking issue
This issue owns:
the normative numeric-domain table and rules in docs/src/design.md;
the settled meanings of One, i64, and f64;
the distinction between ordinary bounded exact integers and problem-native arbitrary-precision integers;
the distinction between mathematical variants, internal representation, reductions, and solver conversion;
the migration workstreams and their dependency order;
consistency of the final repository-wide result.
This issue does not ask one implementation PR to touch every affected subsystem.
Follow-up workstreams
Each workstream should be implemented and verified independently. Large catalog migrations should be split further by model category when necessary.
Exact weight migration: replace i32 exact weight variants with i64; update WeightElement, registrations, schemas, examples, tests, and documentation.
ILP numeric domains: define and implement ILP variable and coefficient domains, preserving exact integer coefficients internally.
QUBO and algebraic domains: separate exact integer coefficients from approximate real coefficients and update applicable reductions.
Fallible exact-to-real reductions: define model-specific preservation checks and the error channel/graph representation for conversions that may fail.
HiGHS solver boundary: perform faithful i64 → f64 conversion checks in the pred solve adapter and fail before backend invocation.
Catalog field migration: migrate ordinary exact costs, capacities, times, bounds, and other nonnegative quantities from ad hoc primitive types to i64, split by category; retain problem-native arbitrary-precision domains where mathematically required.
Enforcement: add focused numeric_contract tests, remove remaining unsafe casts, and enable the applicable Clippy cast lints once violations have been migrated.
Repository-wide acceptance criteria
The tracking issue is complete when the contract is documented and the follow-up migrations establish that:
numeric variants describe mathematical domains rather than storage-width alternatives;
One, i64, and finite f64 have consistent meanings across public construction paths;
ordinary exact arithmetic remains checked i64 arithmetic, and oversized instances fail during construction or reduction;
problem-native arbitrary-precision models retain BigInt or BigUint only where their mathematical definition requires it;
exact-to-approximate conversions are explicit, checked, and fail with a precision error when their boundary condition is not met;
no compatibility alias retains the superseded i32 exact-weight/coefficient variant;
focused known-answer tests cover adjacent integers around 2^53, finite f64 validation, nonnegative-field validation, construction/reduction overflow, and solver-boundary rejection;
the normal formatting, lint, and test checks pass.
Out of scope
Implementing the entire migration in one PR.
Introducing generic wider-intermediate arithmetic for ordinary i64 models.
Accepting oversized ordinary instances by silently promoting them to i128, BigInt, or BigUint.
Guessing an exact decimal or rational intention from an already parsed f64.
Implementing an exact rational solver backend.
Treating numerical solver tolerances as reduction semantics.
Keeping duplicate numeric variants for backward compatibility.
Requiring one universal precision certificate for every exact-to-approximate model conversion.
Purpose
This is the design and tracking issue for the repository-wide numeric-domain contract. It separates three concerns that the current catalog often mixes:
This issue defines the contract and coordinates focused follow-up migrations. It is not a request for one PR to migrate the entire catalog, redesign ILP and QUBO, change reduction execution, update HiGHS, and enable every cast lint at once.
Motivation
A mathematical variant may change the accepted instance set or a reduction precondition, such as unit, integer, or real weights. Changing storage width from
i32toi64does not create a new mathematical problem.Likewise, an exact integer model must not silently lose ordering or feasibility information merely because a reduction target or numerical solver uses
f64. For example, the exact integers9_007_199_254_740_992and9_007_199_254_740_993are distinct, but a conversion tof64may collapse them.Relevant precedents:
https://github.com/google/or-tools/blob/stable/ortools/sat/cp_model.proto
int64_tfor profits, weights, capacities, and results:https://github.com/google/or-tools/blob/stable/ortools/algorithms/knapsack_solver.h
SCIP_Longintfor weights and capacity:https://scipopt.org/doc/html/cons__knapsack_8h.php
good_lpuse double-precision solver interfaces; that is a backend property, not a reason to discard exact provenance inside the repository:https://ergo-code.github.io/HiGHS/dev/guide/numerics/
https://docs.gurobi.com/projects/optimizer/en/current/concepts/numericguide/rounding.html
https://docs.rs/crate/good_lp/latest
https://jump.dev/JuMP.jl/stable/manual/models/
https://soplex.zib.de/doc/html/EXACT.php
Settled contract
Domains and representations
usizeOnei64i64; construction or reduction rejects instances whose required values do not fitf64f64; NaN and both infinities are rejectedBigIntorBigUintThe existing catalog labels
One/i64/f64are retained to minimize churn. Their meanings are unit, ordinary bounded exact integer, and approximate real respectively. Thei32weight/coefficient variant is replaced rather than retained as a compatibility alias.Storage width, signedness, and solver storage alone do not justify a mathematical variant. A problem-native arbitrary-precision representation also does not create a storage variant when arbitrary precision is inherent in that problem's mathematical input domain.
Arithmetic and validation
i64addition, subtraction, multiplication, division, and related operations. Approximate reals use finitef64operations.i64calculations toi128,BigInt, or another larger type to rescue an instance that does not fit the chosen domain.i64, construction or reduction returns an explicit overflow error.evaluate()operates only on already validated instances. It must not contain fallback widening, overflow recovery, saturation, wrapping, or silent approximation.i64and rejects-1.BigIntorBigUintis used when the problem definition itself requires arbitrary-precision values, for example Factoring or a problem whose mathematical object is an explicitly large bit string interpreted as an integer. This is a model-specific domain decision, not a generic intermediate-arithmetic policy.0.1remains the supplied finitef64; it is not rationalized or scaled into an integer.Exact integer to approximate real
Mathematically, integers embed into the reals. In the implementation, an
i64 → f64conversion may lose precision and is therefore explicit and fallible.Two boundaries must be treated separately:
n_terms * max|coefficient| ≤ 2^53.pred solveinvokes a double-based backend such as HiGHS, the adapter checks every exact integer value it converts and returns an explicit precision-loss error before invoking the backend if faithful conversion is impossible.A blanket infallible
as f64cast is invalid at either boundary. Whether and how the reduction graph represents a fallible natural edge is a focused follow-up design problem, not part of the core representation migration.Solver tolerances remain solver semantics; they are not mathematical reduction semantics.
Scope of this tracking issue
This issue owns:
docs/src/design.md;One,i64, andf64;This issue does not ask one implementation PR to touch every affected subsystem.
Follow-up workstreams
Each workstream should be implemented and verified independently. Large catalog migrations should be split further by model category when necessary.
i32exact weight variants withi64; updateWeightElement, registrations, schemas, examples, tests, and documentation.i64 → f64conversion checks in thepred solveadapter and fail before backend invocation.i64, split by category; retain problem-native arbitrary-precision domains where mathematically required.numeric_contracttests, remove remaining unsafe casts, and enable the applicable Clippy cast lints once violations have been migrated.Repository-wide acceptance criteria
The tracking issue is complete when the contract is documented and the follow-up migrations establish that:
One,i64, and finitef64have consistent meanings across public construction paths;i64arithmetic, and oversized instances fail during construction or reduction;BigIntorBigUintonly where their mathematical definition requires it;i32exact-weight/coefficient variant;2^53, finitef64validation, nonnegative-field validation, construction/reduction overflow, and solver-boundary rejection;Out of scope
i64models.i128,BigInt, orBigUint.f64.