Skip to main content

oximo_core/
var.rs

1use oximo_expr::{Expr, VarId};
2use smol_str::SmolStr;
3
4use crate::domain::Domain;
5use crate::model::Model;
6
7/// Variable metadata held by the [`Model`]. Users do not construct this
8/// directly, they get an [`Expr`] back from [`VarBuilder::build`] and look up
9/// solution values via [`crate::Model`] / `oximo_solver::SolverResult`.
10#[derive(Clone, Debug)]
11pub struct Variable {
12    pub id: VarId,
13    pub name: SmolStr,
14    pub domain: Domain,
15    pub lb: f64,
16    pub ub: f64,
17    pub initial: Option<f64>,
18}
19
20/// Builder returned by [`Model::var`]. Configure bounds / domain, then call
21/// [`Self::build`] to register the variable and obtain an `Expr` handle.
22#[must_use = "VarBuilder does nothing until you call .build()"]
23pub struct VarBuilder<'a> {
24    pub(crate) model: &'a Model,
25    pub(crate) name: SmolStr,
26    pub(crate) lb: f64,
27    pub(crate) ub: f64,
28    pub(crate) domain: Domain,
29    pub(crate) initial: Option<f64>,
30}
31
32impl<'a> std::fmt::Debug for VarBuilder<'a> {
33    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34        f.debug_struct("VarBuilder")
35            .field("name", &self.name)
36            .field("lb", &self.lb)
37            .field("ub", &self.ub)
38            .field("domain", &self.domain)
39            .finish()
40    }
41}
42
43impl<'a> VarBuilder<'a> {
44    pub fn lb(mut self, v: f64) -> Self {
45        self.lb = v;
46        self
47    }
48
49    pub fn ub(mut self, v: f64) -> Self {
50        self.ub = v;
51        self
52    }
53
54    pub fn bounds(mut self, lb: f64, ub: f64) -> Self {
55        self.lb = lb;
56        self.ub = ub;
57        self
58    }
59
60    pub fn fix(self, value: f64) -> Self {
61        self.bounds(value, value)
62    }
63
64    pub fn domain(mut self, d: Domain) -> Self {
65        self.domain = d;
66        self
67    }
68
69    pub fn integer(mut self) -> Self {
70        self.domain = Domain::Integer;
71        self
72    }
73
74    pub fn binary(mut self) -> Self {
75        self.domain = Domain::Binary;
76        self.lb = 0.0;
77        self.ub = 1.0;
78        self
79    }
80
81    pub fn initial(mut self, v: f64) -> Self {
82        self.initial = Some(v);
83        self
84    }
85
86    pub fn build(self) -> Expr<'a> {
87        self.model.register_var(self)
88    }
89}