Skip to main content

dypdl/
variable_type.rs

1//! A module defining types of values of state variables.
2
3use std::default;
4use std::fmt;
5use std::iter::{Product, Sum};
6use std::str;
7
8/// Set value.
9pub type Set = fixedbitset::FixedBitSet;
10/// Vector value.
11pub type Vector = Vec<usize>;
12/// Element value.
13pub type Element = usize;
14/// Integer numeric value.
15pub type Integer = i32;
16/// Continuous numeric value.
17pub type Continuous = f64;
18/// Continuous numeric value with a total order.
19pub type OrderedContinuous = ordered_float::OrderedFloat<Continuous>;
20
21/// Trait for string representation of variables, since the ToString trait for Set outputs binary
22/// bits, which is hard to read, ToVariableString overrides it with readable string representations.
23pub trait ToVariableString {
24    fn to_variable_string(&self) -> String;
25}
26
27impl ToVariableString for Set {
28    fn to_variable_string(&self) -> String {
29        let debug_string = format!("{:?}", self.ones().collect::<Vec<usize>>()).replace(',', "");
30        let len = debug_string.len();
31        format!("{{{} : {}}}", &debug_string[1..(len - 1)], self.len())
32    }
33}
34
35macro_rules! create_default_ToVariableString {
36    ($t:ty) => {
37        impl ToVariableString for $t {
38            fn to_variable_string(&self) -> String {
39                self.to_string()
40            }
41        }
42    };
43}
44
45create_default_ToVariableString!(Element);
46create_default_ToVariableString!(Integer);
47create_default_ToVariableString!(Continuous);
48create_default_ToVariableString!(OrderedContinuous);
49create_default_ToVariableString!(bool);
50
51/// Numeric value.
52pub trait Numeric:
53    num_traits::Num
54    + ToNumeric
55    + FromNumeric
56    + num_traits::FromPrimitive
57    + num_traits::Signed
58    + num_traits::Bounded
59    + Copy
60    + Sum
61    + Product
62    + PartialOrd
63    + str::FromStr
64    + fmt::Debug
65    + default::Default
66{
67}
68
69impl Numeric for Integer {}
70impl Numeric for Continuous {}
71impl Numeric for OrderedContinuous {}
72
73/// Trait for converting to numeric values.
74pub trait ToNumeric {
75    /// Convert to an integer value.
76    fn to_integer(self) -> Integer;
77    /// Convert to a continuous value.
78    fn to_continuous(self) -> Continuous;
79}
80
81/// Trait for converting from numeric values.
82pub trait FromNumeric {
83    /// Convert from an integer value.
84    fn from_integer(n: Integer) -> Self;
85    /// Convert from a continuos value.
86    fn from_continuous(n: Continuous) -> Self;
87    /// Convert from usize.
88    fn from_usize(n: usize) -> Self;
89    /// Convert from value that can be converted to a numeric value.
90    fn from<T: ToNumeric>(n: T) -> Self;
91}
92
93impl ToNumeric for Integer {
94    #[inline]
95    fn to_integer(self) -> Integer {
96        self
97    }
98
99    #[inline]
100    fn to_continuous(self) -> Continuous {
101        self as Continuous
102    }
103}
104
105impl FromNumeric for Integer {
106    #[inline]
107    fn from_integer(n: Integer) -> Integer {
108        n
109    }
110
111    #[inline]
112    fn from_continuous(n: Continuous) -> Integer {
113        n as Integer
114    }
115
116    #[inline]
117    fn from_usize(n: usize) -> Integer {
118        n as Integer
119    }
120
121    #[inline]
122    fn from<T: ToNumeric>(n: T) -> Integer {
123        n.to_integer()
124    }
125}
126
127impl ToNumeric for Continuous {
128    #[inline]
129    fn to_integer(self) -> Integer {
130        self as Integer
131    }
132
133    #[inline]
134    fn to_continuous(self) -> Continuous {
135        self
136    }
137}
138
139impl FromNumeric for Continuous {
140    #[inline]
141    fn from_integer(n: Integer) -> Continuous {
142        n as Continuous
143    }
144
145    #[inline]
146    fn from_continuous(n: Continuous) -> Continuous {
147        n
148    }
149
150    #[inline]
151    fn from_usize(n: usize) -> Continuous {
152        n as Continuous
153    }
154
155    #[inline]
156    fn from<T: ToNumeric>(n: T) -> Continuous {
157        n.to_continuous()
158    }
159}
160
161impl ToNumeric for OrderedContinuous {
162    #[inline]
163    fn to_integer(self) -> Integer {
164        self.to_continuous() as Integer
165    }
166
167    #[inline]
168    fn to_continuous(self) -> Continuous {
169        self.into_inner()
170    }
171}
172
173impl FromNumeric for OrderedContinuous {
174    #[inline]
175    fn from_integer(n: Integer) -> OrderedContinuous {
176        ordered_float::OrderedFloat(n as Continuous)
177    }
178
179    #[inline]
180    fn from_continuous(n: Continuous) -> OrderedContinuous {
181        ordered_float::OrderedFloat(n)
182    }
183
184    #[inline]
185    fn from_usize(n: usize) -> OrderedContinuous {
186        ordered_float::OrderedFloat(n as Continuous)
187    }
188
189    #[inline]
190    fn from<T: ToNumeric>(n: T) -> OrderedContinuous {
191        ordered_float::OrderedFloat(n.to_continuous())
192    }
193}
194
195#[cfg(test)]
196mod tests {
197    use crate::{
198        variable_type::{OrderedContinuous, ToVariableString},
199        Continuous, Element, Integer, Set,
200    };
201
202    #[test]
203    fn integer_to_variable_string() {
204        assert_eq!((10 as Integer).to_variable_string(), "10".to_owned());
205    }
206
207    #[test]
208    fn float_to_variable_string() {
209        assert_eq!((3.3 as Continuous).to_variable_string(), "3.3".to_owned());
210    }
211
212    #[test]
213    fn bool_to_variable_string() {
214        assert_eq!((false).to_variable_string(), "false".to_owned());
215    }
216
217    #[test]
218    fn element_to_variable_string() {
219        assert_eq!((10 as Element).to_variable_string(), "10".to_owned());
220    }
221
222    #[test]
223    fn ordered_continuous_to_variable_string() {
224        assert_eq!(
225            OrderedContinuous::from(3.3).to_variable_string(),
226            "3.3".to_owned()
227        );
228    }
229
230    #[test]
231    fn set_to_variable_string() {
232        let mut set = Set::with_capacity(10);
233        set.insert(1);
234        set.insert(3);
235
236        assert_eq!(set.to_variable_string(), "{1 3 : 10}".to_owned());
237    }
238}