1use oximo_expr::{Expr, VarId};
2use smol_str::SmolStr;
3
4use crate::domain::Domain;
5use crate::model::Model;
6
7#[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#[must_use]
24pub fn var_name(vars: &[Variable], v: VarId) -> String {
25 vars.get(v.index()).map_or_else(|| format!("variable #{}", v.index()), |x| x.name.to_string())
26}
27
28#[must_use = "VarBuilder does nothing until you call .build()"]
31pub struct VarBuilder<'a> {
32 pub(crate) model: &'a Model,
33 pub(crate) name: SmolStr,
34 pub(crate) lb: f64,
35 pub(crate) ub: f64,
36 pub(crate) domain: Domain,
37 pub(crate) initial: Option<f64>,
38}
39
40impl<'a> std::fmt::Debug for VarBuilder<'a> {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 f.debug_struct("VarBuilder")
43 .field("name", &self.name)
44 .field("lb", &self.lb)
45 .field("ub", &self.ub)
46 .field("domain", &self.domain)
47 .finish()
48 }
49}
50
51impl<'a> VarBuilder<'a> {
52 pub fn lb(mut self, v: f64) -> Self {
53 self.lb = v;
54 self
55 }
56
57 pub fn ub(mut self, v: f64) -> Self {
58 self.ub = v;
59 self
60 }
61
62 pub fn bounds(mut self, lb: f64, ub: f64) -> Self {
63 self.lb = lb;
64 self.ub = ub;
65 self
66 }
67
68 pub fn fix(self, value: f64) -> Self {
69 self.bounds(value, value)
70 }
71
72 pub fn domain(mut self, d: Domain) -> Self {
73 self.domain = d;
74 self
75 }
76
77 pub fn integer(mut self) -> Self {
78 self.domain = Domain::Integer;
79 self
80 }
81
82 pub fn binary(mut self) -> Self {
83 self.domain = Domain::Binary;
84 self.lb = 0.0;
85 self.ub = 1.0;
86 self
87 }
88
89 pub fn initial(mut self, v: f64) -> Self {
90 self.initial = Some(v);
91 self
92 }
93
94 pub fn build(self) -> Expr<'a> {
95 self.model.register_var(self)
96 }
97}