reference

API reference.

The complete public surface of the grove package as of v0.1. Items are grouped by type; within each type, fields and methods appear in declaration order. For the always-current view, see pkg.go.dev.

Constants and package-level vars

var Inf float64

Positive infinity (math.Inf(1)). Pass as either end of Bounds for an unbounded side. Use -grove.Inf for a free left side.

const WarnLPRelaxationOnly = "grove: LP-relaxation only"

Stable prefix of the warning grove appends to Result.Warnings when an Integer/Binary model was silently solved as its LP relaxation. strings.HasPrefix against this to gate CI.

var ErrHiGHSNotBuilt error

Returned by the HiGHS solver stub when the binary wasn’t built with -tags highs. Detectable with errors.Is.

Sense, VarKind, ConstraintType, Status

All four are small int-backed enums with a String method.

type Sense int

Optimization direction. Values: grove.Maximize, grove.Minimize.

type VarKind int

Domain of a variable. Values: grove.Continuous, grove.Integer, grove.Binary. The latter two are solved as their LP relaxation in v0.1 — see Integer variables.

type ConstraintType int

Relation used by AddConstraint. Values: grove.LTE, grove.GTE, grove.EQ.

type Status int

Outcome of a solve. Values: Optimal, Infeasible, Unbounded, IterationLimit, NumericalError, NotSolved.

Var

A decision variable, created via Problem.NewVar. Don’t construct Var values directly.

func (v *Var) Name() string

The name given at construction.

func (v *Var) Kind() VarKind

The declared kind.

func (v *Var) Low() float64

Lower bound. -grove.Inf for a free left side.

func (v *Var) High() float64

Upper bound. grove.Inf for a free right side.

VarOption

type VarOption func(*Var)

Functional option passed to NewVar. v0.1 exposes exactly one: Bounds.

func Bounds(low, high float64) VarOption

Sets the closed interval [low, high]. Use ±grove.Inf for open ends.

Expr

type Expr map[*Var]float64

A sparse linear expression. The map is the expression directly; no wrapper type.

func (e Expr) Add(other Expr) Expr

Adds other into e in place; returns e.

func (e Expr) Scale(k float64) Expr

Multiplies every coefficient in e by k; returns e.

Constraint

func (c *Constraint) Name() string

The name given at construction.

func (c *Constraint) Expr() Expr

The LHS expression.

func (c *Constraint) Type() ConstraintType

The relation (LTE / GTE / EQ).

func (c *Constraint) RHS() float64

The right-hand-side scalar.

Problem

The root object of a grove model. Construct with NewProblem and attach variables, objective, and constraints before calling Solve.

Fields

Solver Solver

Backend used by Solve. nil ⇒ default pure-Go simplex. Set to &grove.HiGHS{} for the HiGHS stub (real backend lands in v0.3).

Verbose bool

When true, streams Phase I/II pivot detail to stderr. Off by default.

MaxIterations int

Hard pivot cap. 0 (the default) means “use the solver default” — effectively unbounded.

SkipPresolve bool

When true, Solve bypasses the v0.2 presolve pass (fixed-variable substitution, empty-row/empty-column removal). Off by default. Useful for debugging solver behaviour or for reproducing results against an external reference; most callers should leave it alone. See Presolve.

Construction

func NewProblem(name string, sense Sense) *Problem

Returns a fresh *Problem. name is used in error messages, exports, and the sensitivity report.

Read-only accessors

func (p *Problem) Name() string

Problem name.

func (p *Problem) Sense() Sense

Optimization direction.

func (p *Problem) Vars() []*Var

All variables, in declaration order.

func (p *Problem) Constraints() []*Constraint

All constraints, in declaration order.

func (p *Problem) Objective() Expr

The objective expression.

func (p *Problem) ObjectiveConstant() float64

The constant offset (0 unless set explicitly).

func (p *Problem) VarByName(name string) *Var

Lookup; nil if not found.

func (p *Problem) ConstraintByName(name string) *Constraint

Lookup; nil if not found.

func (p *Problem) String() string

Human-readable summary of the whole model — useful for logging or test assertions.

Mutators

func (p *Problem) NewVar(name string, kind VarKind, opts ...VarOption) *Var

Creates a variable on this problem and returns its handle. Names must be unique per problem.

func (p *Problem) SetObjective(e Expr)

Sets the objective expression. Every *Var key in e must belong to this problem.

func (p *Problem) SetObjectiveConstant(k float64)

Sets the fixed constant added to the objective.

func (p *Problem) AddConstraint(name string, e Expr, ctype ConstraintType, rhs float64) *Constraint

Appends a constraint and returns its handle. Names must be unique per problem.

Validation & solving

func (p *Problem) Validate() []error

Returns every modeling problem it finds in one pass — an empty/nil slice means the model is valid. The checks cover missing variables/objective (except presolve-reduced models whose linear objective was folded entirely into ObjectiveConstant), all-zero objective when every stated coefficient is finite, inverted bounds and NaN bounds (±Inf remains valid for unbounded sides), NaN/±Inf objective and constraint coefficients, NaN/±Inf right-hand sides, empty LHS rows, all-zero LHS rows when every coefficient is finite, and duplicate constraint names. Each error is a *ValidationError carrying a stable Kind classifier; see Validation. Solve invokes Validate automatically and refuses to run when the returned slice is non-empty.

type ValidationError struct { Kind ValidationErrorKind Target string Message string }

Single issue returned from Problem.Validate. Kind is a stable string classifier; Target is the variable or constraint name (or "" for problem-level errors); Message is the human-readable text (Error() returns it verbatim). Pull a specific kind out of a []error with errors.As(err, &verr).

type ValidationErrorKind string

Stable classifier constants: ValidationNoVariables, ValidationNoObjective, ValidationZeroObjective, ValidationBadBound, ValidationInvertedBounds, ValidationBadObjectiveCoef, ValidationBadRHS, ValidationEmptyRow, ValidationZeroRow, ValidationBadCoefficient, ValidationDuplicateConstraint. See Validation for what each one catches.

func (p *Problem) Solve() (*Result, error)

Runs p.Solver (or the default simplex). Returns (*Result, nil) for any logical outcome including Infeasible/Unbounded; non-nil error is reserved for structural model mistakes. See Solve and Result.

func (p *Problem) Presolve(opts *PresolveOptions) (*Problem, *PresolveUndo, error)

Runs the presolve pass and returns a reduced copy of p plus the undo map required to re-expand a Result. Never mutates p. Solve invokes this automatically unless p.SkipPresolve is true. See Presolve.

type PresolveOptions struct { Tolerance float64 }

Configuration for Presolve. Tolerance (default 1e-9) is the slack used for feasibility and zero checks on reduced rows. Passing nil is equivalent to passing the zero value.

type PresolveUndo struct { Terminal Status TerminalMsg string // unexported: the original problem, settled variable values, // reduced↔original handle maps, dropped constraints, objective shift. }

Undo record produced by Presolve. Terminal is non-NotSolved when the pass decided the problem's status on its own — Infeasible for an inconsistent empty row, Unbounded for a free objective-only variable, Optimal when every variable was fixed. Solve uses the undo record to re-expand Value and duals to the original index space automatically.

File I/O

func (p *Problem) WriteLP(w io.Writer) error

Writes the problem in CPLEX-LP format.

func (p *Problem) WriteMPS(w io.Writer) error

Writes the problem in fixed-column MPS format.

func ReadLP(r io.Reader) (*Problem, error)

Parses a problem from CPLEX-LP format — the inverse of WriteLP. Accepts the usual tolerances (case-insensitive keywords, abbreviated headers, multi-line expressions, backslash comments, blank lines anywhere). Parse errors are returned as *grove.ParseError; see below.

func ReadMPS(r io.Reader, opts ...MPSOption) (*Problem, error)

Parses a problem from fixed-column or free-form MPS — the inverse of WriteMPS. Handles NAME, OBJSENSE, ROWS, COLUMNS (with INTORG/INTEND markers), RHS, RANGES, BOUNDS, and ENDATA; SOS sections are silently skipped. Auto-detects fixed vs free form by default; use MPSFixedInput() or MPSFreeInput() to override. Range rows raise an error (grove doesn’t model range constraints yet).

type MPSFormat int

Selects the MPS encoding. Values: MPSAuto (default), MPSFixed, MPSFree.

type MPSOption func(*mpsConfig)

Functional option for ReadMPS.

func MPSFixedInput() MPSOption

Forces the parser onto the strict fixed-column layout, bypassing auto-detection.

func MPSFreeInput() MPSOption

Forces the parser onto whitespace-separated free-form MPS, bypassing auto-detection.

type ParseError struct { Line, Col int Msg string Format string }

Structured error returned by ReadLP and ReadMPS. Line is 1-based; Col is 1-based when the position inside a line is meaningful and 0 otherwise. Format names the file format ("LP" or "MPS") and appears in the rendered message. Extract with errors.As to drive editor highlights, etc. Error() folds the prefix "grove: LP parse error …" or "grove: MPS parse error …" around Msg.

Result

Fields

Status Status

Outcome classification. Always set.

Objective float64

Objective value in the user-facing sense. Valid when Status == Optimal.

Iterations int

Total simplex pivots across Phase I and Phase II.

Message string

Optional human-readable detail. Includes the LP-relaxation warning when applicable.

Warnings []string

Advisory notes. v0.1 emits exactly one kind (WarnLPRelaxationOnly).

Accessor methods

func (r *Result) Value(v *Var) float64

Value of v in the optimal solution, in the original (un-shifted, un-split) variable. 0 on non-Optimal results.

func (r *Result) Values() map[*Var]float64

The full primal solution map. Safe to iterate.

func (r *Result) Dual(c *Constraint) float64

Shadow price of c: the rate at which the optimal objective changes with the constraint’s RHS.

func (r *Result) Reduced(v *Var) float64

Reduced cost of v: per-unit objective change if v were forced into the basis. Zero on basic variables at a non-degenerate optimum.

func (r *Result) NonIntegerIntegerVars(p *Problem) []*Var

Integer/Binary variables whose optimum came back non-integer (within a 1e-6 tolerance). nil if the problem is all-continuous or the solve was not Optimal.

Sensitivity

func SensitivityReport(p *Problem, r *Result) *Sensitivity

Builds a structured sensitivity snapshot from a solved problem. Returns nil if r.Status != Optimal.

type Sensitivity struct { Constraints []ConstraintSensitivity Variables []VarSensitivity }

Constraints and variables in declaration order. Use .String() for a pretty-printed block.

type ConstraintSensitivity struct { Constraint *Constraint LHS float64 // a·x at the optimum Slack float64 // LTE: b − a·x; GTE: a·x − b; EQ: 0 Dual float64 // ∂z*/∂rhs Binding bool // Slack ≈ 0 }

Per-constraint diagnostics block.

type VarSensitivity struct { Var *Var Value float64 Reduced float64 AtLower bool AtUpper bool }

Per-variable diagnostics block. AtLower/AtUpper indicate which bound the variable sits on, if any.

func (s *Sensitivity) String() string

Pretty-printed report grouped into binding constraints, slack constraints, and variables.

Solver interface

type Solver interface { Solve(p *Problem) (*Result, error) }

The single extension point. Assign any implementation to Problem.Solver and it will be used in place of the default simplex.

type SimplexSolver struct { Verbose bool MaxIterations int }

The default pure-Go simplex. You rarely construct this yourself — setting Problem.Verbose and Problem.MaxIterations forwards into a freshly-built instance.

type HiGHS struct{ /* opaque */ }

CGO-linked HiGHS backend. In v0.1, Solve returns ErrHiGHSNotBuilt; a real implementation ships behind -tags highs in v0.3.

Versioning promise

Pre-1.0 minor versions (0.1 → 0.2 → 0.3 → 0.4) are permitted to break the API as the design settles. All breakages will be called out in the release notes. The intent is that the modeling layer (Problem, Var, Expr, Constraint, Result, Solver) freezes at v1.0. See the roadmap.