system_of_linear_inequalities/
system_of_linear_inequalities.rs

1use orx_imp_vec::*;
2use std::{
3    fmt::{Display, Formatter, Result},
4    ops::{Add, Index, Mul},
5};
6
7/// # Scope
8///
9/// It is a bag of things,
10/// analogous to variables, expressions, etc. defined
11/// in the scope of a code block.
12#[derive(Default)]
13struct Scope<'a> {
14    vectors: ImpVec<Vector<'a>>,
15    exprs: ImpVec<Expr<'a>>,
16    terms: ImpVec<Term<'a>>,
17    vars: ImpVec<Var<'a>>,
18}
19
20impl<'a> Scope<'a> {
21    fn same_scope_as(&self, other: &Self) -> bool {
22        self as *const Self == other as *const Self
23    }
24}
25
26impl<'a> Scope<'a> {
27    fn new_var_vec(&'a self, symbol: &str) -> &'a Vector<'a> {
28        self.vectors.imp_push_get_ref(Vector {
29            scope: self,
30            symbol: symbol.to_string(),
31        })
32    }
33}
34
35/// # VarVec
36struct Vector<'a> {
37    scope: &'a Scope<'a>,
38    symbol: String,
39}
40
41impl<'a> Display for Vector<'a> {
42    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
43        write!(f, "{}", self.symbol)
44    }
45}
46
47impl<'a> Index<usize> for &'a Vector<'a> {
48    type Output = Var<'a>;
49
50    fn index(&self, index: usize) -> &Self::Output {
51        self.scope.vars.imp_push_get_ref(Var {
52            scope: self.scope,
53            var_vec: self,
54            index,
55        })
56    }
57}
58
59/// # Expr
60struct Expr<'a> {
61    scope: &'a Scope<'a>,
62    terms: Vec<&'a Term<'a>>,
63}
64
65impl<'a> Display for Expr<'a> {
66    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
67        let mut terms = self.terms.iter();
68        if let Some(term) = terms.next() {
69            write!(f, "{}", term)?;
70            for term in terms {
71                write!(f, " + {}", term)?;
72            }
73        }
74        Ok(())
75    }
76}
77
78impl<'a> Add<&'a Term<'a>> for &'a Expr<'a> {
79    type Output = &'a Expr<'a>;
80
81    fn add(self, rhs: &'a Term<'a>) -> Self::Output {
82        assert!(self.scope.same_scope_as(rhs.scope));
83
84        let mut terms = self.terms.clone();
85        terms.push(rhs);
86        self.scope.exprs.imp_push_get_ref(Expr {
87            scope: self.scope,
88            terms,
89        })
90    }
91}
92
93/// # Term
94#[derive(Clone, Copy)]
95struct Term<'a> {
96    scope: &'a Scope<'a>,
97    coef: i64,
98    var: Var<'a>,
99}
100
101impl<'a> Display for Term<'a> {
102    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
103        write!(f, "{}.{}", self.coef, self.var)
104    }
105}
106
107impl<'a> Add<&'a Term<'a>> for &'a Term<'a> {
108    type Output = &'a Expr<'a>;
109
110    fn add(self, rhs: &'a Term<'a>) -> Self::Output {
111        assert!(self.scope.same_scope_as(rhs.scope));
112
113        self.scope.exprs.imp_push_get_ref(Expr {
114            scope: self.scope,
115            terms: vec![self, rhs],
116        })
117    }
118}
119
120/// # Var
121#[derive(Clone, Copy)]
122struct Var<'a> {
123    scope: &'a Scope<'a>,
124    var_vec: &'a Vector<'a>,
125    index: usize,
126}
127
128impl<'a> Display for Var<'a> {
129    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
130        write!(f, "{}[{}]", self.var_vec, self.index)
131    }
132}
133
134impl<'a> Mul<Var<'a>> for i64 {
135    type Output = &'a Term<'a>;
136
137    fn mul(self, rhs: Var<'a>) -> Self::Output {
138        rhs.scope.terms.imp_push(Term {
139            scope: rhs.scope,
140            coef: self,
141            var: rhs,
142        });
143        &rhs.scope.terms[rhs.scope.terms.len() - 1]
144    }
145}
146
147#[allow(unused_variables)]
148fn main() {
149    /// Breakdown of types
150    fn break_down_of_types() {
151        let scope = Scope::default();
152
153        let x: &Vector = scope.new_var_vec("x");
154
155        let x0: Var = x[0];
156        let x1: Var = x[1];
157
158        let t1: &Term = 3 * x[0];
159        let t2: &Term = 4 * x[1];
160
161        let le: &Expr = t1 + t2; // or
162        let le: &Expr = 3 * x[0] + 4 * x[1];
163    }
164
165    /// Challenge #1
166    /// x: VarVec being a symbolic vector of variables,
167    /// we need x[i] operator to create a new value of the scalar type
168    /// Var and return a reference to it for an arbitrary index i.
169    fn challenge1() {
170        let scope = Scope::default();
171
172        let x: &Vector = scope.new_var_vec("x");
173
174        let x0: Var = x[0];
175        let x1: Var = x[1];
176    }
177
178    /// Challenge #2
179    /// It is very important to have the symbolic types Var and Term
180    /// to implement the Copy trait to achieve the desired expressive api.
181    fn challenge2() {
182        let scope = Scope::default();
183
184        let x: &Vector = scope.new_var_vec("x");
185
186        let t = 42 * x[0];
187        let e1 = t + 3 * x[1];
188        let e2 = t + 2 * x[0];
189    }
190
191    /// The Goal
192    fn the_goal() {
193        let scope = Scope::default();
194
195        let x = scope.new_var_vec("x");
196
197        let le = 3 * x[0] + 4 * x[1];
198
199        assert_eq!(&le.to_string(), "3.x[0] + 4.x[1]");
200        println!("{}", le);
201    }
202
203    break_down_of_types();
204    challenge1();
205    challenge2();
206    the_goal();
207}