dypdl/
state.rs

1use crate::effect;
2use crate::state_functions::{StateFunctionCache, StateFunctions};
3use crate::table_registry;
4use crate::util::{self, ModelErr};
5use crate::variable_type::{Continuous, Element, Integer, Set, Vector};
6use rustc_hash::{FxHashMap, FxHashSet};
7use std::cmp::Ordering;
8use std::collections::hash_map::Entry;
9use std::panic;
10
11/// Trait representing a state in DyPDL.
12pub trait StateInterface: Sized {
13    /// Returns the number of set variables;
14    fn get_number_of_set_variables(&self) -> usize;
15
16    /// Returns the value of a set variable.
17    ///
18    /// # Panics
19    ///
20    /// Panics if no variable has the id of `i`.
21    fn get_set_variable(&self, i: usize) -> &Set;
22
23    /// Returns the number of vector variables;
24    fn get_number_of_vector_variables(&self) -> usize;
25
26    /// Returns the value of a vector variable.
27    ///
28    /// # Panics
29    ///
30    /// Panics if no variable has the id of `i`.
31    fn get_vector_variable(&self, i: usize) -> &Vector;
32
33    /// Returns the number of element variables;
34    fn get_number_of_element_variables(&self) -> usize;
35
36    /// Returns the value of an element variable.
37    ///
38    /// # Panics
39    ///
40    /// Panics if no variable has the id of `i`.
41    fn get_element_variable(&self, i: usize) -> Element;
42
43    /// Returns the number of integer numeric variables;
44    fn get_number_of_integer_variables(&self) -> usize;
45
46    /// Returns the value of an integer numeric variable.
47    ///
48    /// # Panics
49    ///
50    /// Panics if no variable has the id of `i`.
51    fn get_integer_variable(&self, i: usize) -> Integer;
52
53    /// Returns the number of continuous numeric variables;
54    fn get_number_of_continuous_variables(&self) -> usize;
55
56    /// Returns the value of a continuous numeric variable.
57    ///
58    /// # Panics
59    ///
60    /// Panics if no variable has the id of `i`.
61    fn get_continuous_variable(&self, i: usize) -> Continuous;
62
63    /// Returns the number of element resource variables;
64    fn get_number_of_element_resource_variables(&self) -> usize;
65
66    /// Returns the value of an element resource variable.
67    ///
68    /// # Panics
69    ///
70    /// Panics if no variable has the id of `i`.
71    fn get_element_resource_variable(&self, i: usize) -> Element;
72
73    /// Returns the number of integer resource variables;
74    fn get_number_of_integer_resource_variables(&self) -> usize;
75
76    /// Returns the value of an integer resource variable.
77    ///
78    /// # Panics
79    ///
80    /// Panics if no variable has the id of `i`.
81    fn get_integer_resource_variable(&self, i: usize) -> Integer;
82
83    /// Returns the number of continuous resource variables;
84    fn get_number_of_continuous_resource_variables(&self) -> usize;
85
86    /// Returns the value of a continuous resource variable.
87    ///
88    /// # Panics
89    ///
90    /// Panics if no variable has the id of `i`.
91    fn get_continuous_resource_variable(&self, i: usize) -> Continuous;
92
93    /// Returns the transitioned state by the effect.
94    ///
95    /// Set and vector effects must be sorted by the indices of the variables.
96    ///
97    /// # Panics
98    ///
99    /// Panics if the cost of the transition state is used or a min/max reduce operation is performed on an empty set or vector.
100    fn apply_effect<T: From<State>>(
101        &self,
102        effect: &effect::Effect,
103        function_cache: &mut StateFunctionCache,
104        state_functions: &StateFunctions,
105        registry: &table_registry::TableRegistry,
106    ) -> T {
107        let len = self.get_number_of_set_variables();
108        let mut set_variables = Vec::with_capacity(len);
109        let mut i = 0;
110        for e in &effect.set_effects {
111            while i < e.0 {
112                set_variables.push(self.get_set_variable(i).clone());
113                i += 1;
114            }
115            set_variables.push(e.1.eval(self, function_cache, state_functions, registry));
116            i += 1;
117        }
118        while i < len {
119            set_variables.push(self.get_set_variable(i).clone());
120            i += 1;
121        }
122
123        let len = self.get_number_of_vector_variables();
124        let mut vector_variables = Vec::with_capacity(len);
125        let mut i = 0;
126        for e in &effect.vector_effects {
127            while i < e.0 {
128                vector_variables.push(self.get_vector_variable(i).clone());
129                i += 1;
130            }
131            vector_variables.push(e.1.eval(self, function_cache, state_functions, registry));
132            i += 1;
133        }
134        while i < len {
135            vector_variables.push(self.get_vector_variable(i).clone());
136            i += 1;
137        }
138
139        let mut element_variables: Vec<usize> = (0..self.get_number_of_element_variables())
140            .map(|i| self.get_element_variable(i))
141            .collect();
142        for e in &effect.element_effects {
143            element_variables[e.0] = e.1.eval(self, function_cache, state_functions, registry);
144        }
145
146        let mut integer_variables: Vec<Integer> = (0..self.get_number_of_integer_variables())
147            .map(|i| self.get_integer_variable(i))
148            .collect();
149        for e in &effect.integer_effects {
150            integer_variables[e.0] = e.1.eval(self, function_cache, state_functions, registry);
151        }
152
153        let mut continuous_variables: Vec<Continuous> = (0..self
154            .get_number_of_continuous_variables())
155            .map(|i| self.get_continuous_variable(i))
156            .collect();
157        for e in &effect.continuous_effects {
158            continuous_variables[e.0] = e.1.eval(self, function_cache, state_functions, registry);
159        }
160
161        let mut element_resource_variables: Vec<usize> = (0..self
162            .get_number_of_element_resource_variables())
163            .map(|i| self.get_element_resource_variable(i))
164            .collect();
165        for e in &effect.element_resource_effects {
166            element_resource_variables[e.0] =
167                e.1.eval(self, function_cache, state_functions, registry);
168        }
169
170        let mut integer_resource_variables: Vec<Integer> = (0..self
171            .get_number_of_integer_resource_variables())
172            .map(|i| self.get_integer_resource_variable(i))
173            .collect();
174        for e in &effect.integer_resource_effects {
175            integer_resource_variables[e.0] =
176                e.1.eval(self, function_cache, state_functions, registry);
177        }
178
179        let mut continuous_resource_variables: Vec<Continuous> = (0..self
180            .get_number_of_continuous_resource_variables())
181            .map(|i| self.get_continuous_resource_variable(i))
182            .collect();
183        for e in &effect.continuous_resource_effects {
184            continuous_resource_variables[e.0] =
185                e.1.eval(self, function_cache, state_functions, registry);
186        }
187
188        T::from(State {
189            signature_variables: SignatureVariables {
190                set_variables,
191                vector_variables,
192                element_variables,
193                integer_variables,
194                continuous_variables,
195            },
196            resource_variables: ResourceVariables {
197                element_variables: element_resource_variables,
198                integer_variables: integer_resource_variables,
199                continuous_variables: continuous_resource_variables,
200            },
201        })
202    }
203}
204
205/// State variables other than resource variables.
206#[derive(Debug, PartialEq, Clone, Default)]
207pub struct SignatureVariables {
208    /// Set variables.
209    pub set_variables: Vec<Set>,
210    /// Vector variables.
211    pub vector_variables: Vec<Vector>,
212    /// Element variables.
213    pub element_variables: Vec<Element>,
214    /// Integer numeric variables.
215    pub integer_variables: Vec<Integer>,
216    /// Continuous numeric variables.
217    pub continuous_variables: Vec<Continuous>,
218}
219
220/// Resource variables.
221#[derive(Debug, PartialEq, Clone, Default)]
222pub struct ResourceVariables {
223    /// Element variables.
224    pub element_variables: Vec<Element>,
225    /// Integer numeric variables.
226    pub integer_variables: Vec<Integer>,
227    /// Continuous numeric variables.
228    pub continuous_variables: Vec<Continuous>,
229}
230
231/// State in DyPDL.
232#[derive(Debug, PartialEq, Clone, Default)]
233pub struct State {
234    /// Variables other than resource variables
235    pub signature_variables: SignatureVariables,
236    /// Resource variables
237    pub resource_variables: ResourceVariables,
238}
239
240impl StateInterface for State {
241    /// Returns the number of set variables.
242    ///
243    /// # Examples
244    ///
245    /// ```
246    /// use dypdl::prelude::*;
247    ///
248    /// let mut model = Model::default();
249    /// let object_type = model.add_object_type("object", 4).unwrap();
250    /// let set = model.create_set(object_type, &[0, 1, 2, 3]).unwrap();
251    /// model.add_set_variable("variable", object_type, set).unwrap();
252    /// let state = model.target.clone();
253    ///
254    /// assert_eq!(state.get_number_of_set_variables(), 1);
255    /// ```
256    #[inline]
257    fn get_number_of_set_variables(&self) -> usize {
258        self.signature_variables.set_variables.len()
259    }
260
261    /// Returns the value of a set variable.
262    ///
263    /// # Panics
264    ///
265    /// Panics if no variable has the id of `i`.
266    ///
267    /// # Examples
268    ///
269    /// ```
270    /// use dypdl::prelude::*;
271    ///
272    /// let mut model = Model::default();
273    /// let object_type = model.add_object_type("object", 4).unwrap();
274    /// let set = model.create_set(object_type, &[0, 1, 2, 3]).unwrap();
275    /// let variable = model.add_set_variable("variable", object_type, set.clone()).unwrap();
276    /// let state = model.target.clone();
277    ///
278    /// assert_eq!(state.get_set_variable(variable.id()), &set);
279    /// ```
280    #[inline]
281    fn get_set_variable(&self, i: usize) -> &Set {
282        &self.signature_variables.set_variables[i]
283    }
284
285    /// Returns the number of vector variables;
286    ///
287    /// # Examples
288    ///
289    /// ```
290    /// use dypdl::prelude::*;
291    ///
292    /// let mut model = Model::default();
293    /// let object_type = model.add_object_type("object", 4).unwrap();
294    /// model.add_vector_variable("variable", object_type, vec![0, 1, 2, 3]).unwrap();
295    /// let state = model.target.clone();
296    ///
297    /// assert_eq!(state.get_number_of_vector_variables(), 1);
298    /// ```
299    #[inline]
300    fn get_number_of_vector_variables(&self) -> usize {
301        self.signature_variables.vector_variables.len()
302    }
303
304    /// Returns the value of a vector variable.
305    ///
306    /// # Panics
307    ///
308    /// Panics if no variable has the id of `i`.
309    ///
310    /// # Examples
311    ///
312    /// ```
313    /// use dypdl::prelude::*;
314    ///
315    /// let mut model = Model::default();
316    /// let object_type = model.add_object_type("object", 4).unwrap();
317    /// let variable = model.add_vector_variable("variable", object_type, vec![0, 1, 2, 3]).unwrap();
318    /// let state = model.target.clone();
319    ///
320    /// assert_eq!(state.get_vector_variable(variable.id()), &vec![0, 1, 2, 3]);
321    #[inline]
322    fn get_vector_variable(&self, i: usize) -> &Vector {
323        &self.signature_variables.vector_variables[i]
324    }
325
326    /// Returns the number of vector variables;
327    ///
328    /// # Examples
329    ///
330    /// ```
331    /// use dypdl::prelude::*;
332    ///
333    /// let mut model = Model::default();
334    /// let object_type = model.add_object_type("object", 4).unwrap();
335    /// model.add_element_variable("variable", object_type, 0).unwrap();
336    /// let state = model.target.clone();
337    ///
338    /// assert_eq!(state.get_number_of_element_variables(), 1);
339    /// ```
340    #[inline]
341    fn get_number_of_element_variables(&self) -> usize {
342        self.signature_variables.element_variables.len()
343    }
344
345    /// Returns the value of an element variable.
346    ///
347    /// # Panics
348    ///
349    /// Panics if no variable has the id of `i`.
350    ///
351    /// # Examples
352    ///
353    /// ```
354    /// use dypdl::prelude::*;
355    ///
356    /// let mut model = Model::default();
357    /// let object_type = model.add_object_type("object", 4).unwrap();
358    /// let variable = model.add_element_variable("variable", object_type, 0).unwrap();
359    /// let state = model.target.clone();
360    ///
361    /// assert_eq!(state.get_element_variable(variable.id()), 0);
362    /// ```
363    #[inline]
364    fn get_element_variable(&self, i: usize) -> Element {
365        self.signature_variables.element_variables[i]
366    }
367
368    /// Returns the number of integer numeric variables;
369    ///
370    /// # Examples
371    ///
372    /// ```
373    /// use dypdl::prelude::*;
374    ///
375    /// let mut model = Model::default();
376    /// model.add_integer_variable("variable", 0).unwrap();
377    /// let state = model.target.clone();
378    ///
379    /// assert_eq!(state.get_number_of_integer_variables(), 1);
380    /// ```
381    #[inline]
382    fn get_number_of_integer_variables(&self) -> usize {
383        self.signature_variables.integer_variables.len()
384    }
385
386    /// Returns the value of an integer numeric variable.
387    ///
388    /// # Panics
389    ///
390    /// Panics if no variable has the id of `i`.
391    ///
392    /// # Examples
393    ///
394    /// ```
395    /// use dypdl::prelude::*;
396    ///
397    /// let mut model = Model::default();
398    /// let variable = model.add_integer_variable("variable", 0).unwrap();
399    /// let state = model.target.clone();
400    ///
401    /// assert_eq!(state.get_integer_variable(variable.id()), 0);
402    /// ```
403    #[inline]
404    fn get_integer_variable(&self, i: usize) -> Integer {
405        self.signature_variables.integer_variables[i]
406    }
407
408    /// Returns the number of continuous numeric variables;
409    ///
410    /// # Examples
411    ///
412    /// ```
413    /// use dypdl::prelude::*;
414    ///
415    /// let mut model = Model::default();
416    /// model.add_continuous_variable("variable", 0.5).unwrap();
417    /// let state = model.target.clone();
418    ///
419    /// assert_eq!(state.get_number_of_continuous_variables(), 1);
420    /// ```
421    #[inline]
422    fn get_number_of_continuous_variables(&self) -> usize {
423        self.signature_variables.continuous_variables.len()
424    }
425
426    /// Returns the value of a continuous numeric variable.
427    ///
428    /// # Panics
429    ///
430    /// Panics if no variable has the id of `i`.
431    ///
432    /// # Examples
433    ///
434    /// ```
435    /// use approx::assert_relative_eq;
436    /// use dypdl::prelude::*;
437    ///
438    /// let mut model = Model::default();
439    /// let variable = model.add_continuous_variable("variable", 0.5).unwrap();
440    /// let state = model.target.clone();
441    ///
442    /// assert_relative_eq!(state.get_continuous_variable(variable.id()), 0.5);
443    /// ```
444    #[inline]
445    fn get_continuous_variable(&self, i: usize) -> Continuous {
446        self.signature_variables.continuous_variables[i]
447    }
448
449    /// Returns the number of element resource variables;
450    ///
451    /// # Examples
452    ///
453    /// ```
454    /// use dypdl::prelude::*;
455    ///
456    /// let mut model = Model::default();
457    /// let object_type = model.add_object_type("object", 4).unwrap();
458    /// model.add_element_resource_variable("variable", object_type, false, 0).unwrap();
459    /// let state = model.target.clone();
460    ///
461    /// assert_eq!(state.get_number_of_element_resource_variables(), 1);
462    /// ```
463    #[inline]
464    fn get_number_of_element_resource_variables(&self) -> usize {
465        self.resource_variables.element_variables.len()
466    }
467
468    /// Returns the value of an element resource variable.
469    ///
470    /// # Panics
471    ///
472    /// Panics if no variable has the id of `i`.
473    ///
474    /// # Examples
475    ///
476    /// ```
477    /// use dypdl::prelude::*;
478    ///
479    /// let mut model = Model::default();
480    /// let object_type = model.add_object_type("object", 4).unwrap();
481    /// let variable = model.add_element_resource_variable("variable", object_type, false, 0).unwrap();
482    /// let state = model.target.clone();
483    ///
484    /// assert_eq!(state.get_element_resource_variable(variable.id()), 0);
485    /// ```
486    #[inline]
487    fn get_element_resource_variable(&self, i: usize) -> Element {
488        self.resource_variables.element_variables[i]
489    }
490
491    /// Returns the number of integer resource variables;
492    ///
493    /// # Examples
494    ///
495    /// ```
496    /// use dypdl::prelude::*;
497    ///
498    /// let mut model = Model::default();
499    /// model.add_integer_resource_variable("variable", false, 0).unwrap();
500    /// let state = model.target.clone();
501    ///
502    /// assert_eq!(state.get_number_of_integer_resource_variables(), 1);
503    /// ```
504    #[inline]
505    fn get_number_of_integer_resource_variables(&self) -> usize {
506        self.resource_variables.integer_variables.len()
507    }
508
509    /// Returns the value of an integer resource variable.
510    ///
511    /// # Panics
512    ///
513    /// Panics if no variable has the id of `i`.
514    ///
515    /// # Examples
516    ///
517    /// ```
518    /// use dypdl::prelude::*;
519    ///
520    /// let mut model = Model::default();
521    /// let variable = model.add_integer_resource_variable("variable", false, 0).unwrap();
522    /// let state = model.target.clone();
523    ///
524    /// assert_eq!(state.get_integer_resource_variable(variable.id()), 0);
525    /// ```
526    #[inline]
527    fn get_integer_resource_variable(&self, i: usize) -> Integer {
528        self.resource_variables.integer_variables[i]
529    }
530
531    /// Returns the number of continuous resource variables;
532    ///
533    /// # Examples
534    ///
535    /// ```
536    /// use dypdl::prelude::*;
537    ///
538    /// let mut model = Model::default();
539    /// model.add_continuous_resource_variable("variable", false, 0.5).unwrap();
540    /// let state = model.target.clone();
541    ///
542    /// assert_eq!(state.get_number_of_continuous_resource_variables(), 1);
543    /// ```
544    #[inline]
545    fn get_number_of_continuous_resource_variables(&self) -> usize {
546        self.resource_variables.continuous_variables.len()
547    }
548
549    /// Returns the value of a continuous resource variable.
550    ///
551    /// # Panics
552    ///
553    /// Panics if no variable has the id of `i`.
554    ///
555    /// # Examples
556    ///
557    /// ```
558    /// use approx::assert_relative_eq;
559    /// use dypdl::prelude::*;
560    ///
561    /// let mut model = Model::default();
562    /// let variable = model.add_continuous_resource_variable("variable", false, 0.5).unwrap();
563    /// let state = model.target.clone();
564    ///
565    /// assert_relative_eq!(state.get_continuous_resource_variable(variable.id()), 0.5);
566    /// ```
567    #[inline]
568    fn get_continuous_resource_variable(&self, i: usize) -> Continuous {
569        self.resource_variables.continuous_variables[i]
570    }
571}
572
573impl State {
574    /// Returns if the given state is equal to the current state.
575    ///
576    /// # Panics
577    ///
578    /// Panics if the state metadata is wrong.
579    pub fn is_satisfied<U: StateInterface>(&self, state: &U, metadata: &StateMetadata) -> bool {
580        for i in 0..metadata.number_of_element_variables() {
581            if self.get_element_variable(i) != state.get_element_variable(i) {
582                return false;
583            }
584        }
585        for i in 0..metadata.number_of_element_resource_variables() {
586            if self.get_element_resource_variable(i) != state.get_element_resource_variable(i) {
587                return false;
588            }
589        }
590        for i in 0..metadata.number_of_integer_variables() {
591            if self.get_integer_variable(i) != state.get_integer_variable(i) {
592                return false;
593            }
594        }
595        for i in 0..metadata.number_of_integer_resource_variables() {
596            if self.get_integer_resource_variable(i) != state.get_integer_resource_variable(i) {
597                return false;
598            }
599        }
600        for i in 0..metadata.number_of_continuous_variables() {
601            if (self.get_continuous_variable(i) - state.get_continuous_variable(i)).abs()
602                > Continuous::EPSILON
603            {
604                return false;
605            }
606        }
607        for i in 0..metadata.number_of_continuous_resource_variables() {
608            if (self.get_continuous_resource_variable(i)
609                - state.get_continuous_resource_variable(i))
610            .abs()
611                > Continuous::EPSILON
612            {
613                return false;
614            }
615        }
616        for i in 0..metadata.number_of_set_variables() {
617            if self.get_set_variable(i) != state.get_set_variable(i) {
618                return false;
619            }
620        }
621        for i in 0..metadata.number_of_vector_variables() {
622            if self.get_vector_variable(i) != state.get_vector_variable(i) {
623                return false;
624            }
625        }
626        true
627    }
628}
629
630macro_rules! define_handle {
631    ($x:ident) => {
632        /// A struct wrapping an id.
633        #[derive(Debug, Clone, Copy, PartialEq, Eq)]
634        pub struct $x(usize);
635
636        impl $x {
637            /// Returns the id.
638            #[inline]
639            pub fn id(&self) -> usize {
640                self.0
641            }
642        }
643    };
644}
645
646define_handle!(ObjectType);
647define_handle!(ElementVariable);
648define_handle!(ElementResourceVariable);
649define_handle!(SetVariable);
650define_handle!(VectorVariable);
651define_handle!(IntegerVariable);
652define_handle!(IntegerResourceVariable);
653define_handle!(ContinuousVariable);
654define_handle!(ContinuousResourceVariable);
655
656/// Information about state variables.
657#[derive(Debug, PartialEq, Clone, Default)]
658pub struct StateMetadata {
659    /// Map from an object type id to the name.
660    pub object_type_names: Vec<String>,
661    /// Map from a name to its object type id.
662    pub name_to_object_type: FxHashMap<String, usize>,
663    /// Map from an object type id to the number of objects.
664    pub object_numbers: Vec<usize>,
665
666    /// Map from a set variable id to the name.
667    pub set_variable_names: Vec<String>,
668    /// Map from a name to the set variable id.
669    pub name_to_set_variable: FxHashMap<String, usize>,
670    /// Map from a set variable id to its object type id.
671    pub set_variable_to_object: Vec<usize>,
672
673    /// Map from a vector variable id to the name.
674    pub vector_variable_names: Vec<String>,
675    /// Map from a name to a set variable id.
676    pub name_to_vector_variable: FxHashMap<String, usize>,
677    /// Map from a vector variable id to its object type id.
678    pub vector_variable_to_object: Vec<usize>,
679
680    /// Map from an element variable id to the name.
681    pub element_variable_names: Vec<String>,
682    /// Map from a name to an element variable id.
683    pub name_to_element_variable: FxHashMap<String, usize>,
684    /// Map from an element variable id to its object type id.
685    pub element_variable_to_object: Vec<usize>,
686
687    /// Map from an integer variable id to the name.
688    pub integer_variable_names: Vec<String>,
689    /// Map from a name to an integer variable id.
690    pub name_to_integer_variable: FxHashMap<String, usize>,
691
692    /// Map from a continuous variable id to the name.
693    pub continuous_variable_names: Vec<String>,
694    /// Map from a name to a continuous variable id.
695    pub name_to_continuous_variable: FxHashMap<String, usize>,
696
697    /// Map from an element resource variable id to the name.
698    pub element_resource_variable_names: Vec<String>,
699    /// Map from a name to an element resource variable id.
700    pub name_to_element_resource_variable: FxHashMap<String, usize>,
701    /// Map from an element resource variable id to its object type id.
702    pub element_resource_variable_to_object: Vec<usize>,
703    /// Map from an element resource variable id to its preference.
704    pub element_less_is_better: Vec<bool>,
705
706    /// Map from an integer resource variable id to the name.
707    pub integer_resource_variable_names: Vec<String>,
708    /// Map from a name to an integer resource variable id.
709    pub name_to_integer_resource_variable: FxHashMap<String, usize>,
710    /// Map from an integer resource variable id to its preference.
711    pub integer_less_is_better: Vec<bool>,
712
713    /// Map from a continuous resource variable id to the name.
714    pub continuous_resource_variable_names: Vec<String>,
715    /// Map from a name to a continuous resource variable id.
716    pub name_to_continuous_resource_variable: FxHashMap<String, usize>,
717    /// Map from a continuous resource variable id to its preference.
718    pub continuous_less_is_better: Vec<bool>,
719}
720
721impl StateMetadata {
722    /// Returns the number of object types.
723    ///
724    /// # Examples
725    ///
726    /// ```
727    /// use dypdl::prelude::*;
728    ///
729    /// let mut model = Model::default();
730    /// model.add_object_type("object", 4).unwrap();
731    ///
732    /// assert_eq!(model.state_metadata.number_of_object_types(), 1);
733    /// ```
734    #[inline]
735    pub fn number_of_object_types(&self) -> usize {
736        self.object_type_names.len()
737    }
738
739    /// Returns the number of set variables.
740    ///
741    /// # Examples
742    ///
743    /// ```
744    /// use dypdl::prelude::*;
745    ///
746    /// let mut model = Model::default();
747    /// let object_type = model.add_object_type("object", 4).unwrap();
748    /// let set = model.create_set(object_type, &[0, 1, 2, 3]).unwrap();
749    /// model.add_set_variable("variable", object_type, set).unwrap();
750    ///
751    /// assert_eq!(model.state_metadata.number_of_set_variables(), 1);
752    /// ```
753    #[inline]
754    pub fn number_of_set_variables(&self) -> usize {
755        self.set_variable_names.len()
756    }
757
758    /// Returns the number of vector variables.
759    ///
760    /// # Examples
761    ///
762    /// ```
763    /// use dypdl::prelude::*;
764    ///
765    /// let mut model = Model::default();
766    /// let object_type = model.add_object_type("object", 4).unwrap();
767    /// model.add_vector_variable("variable", object_type, vec![0, 1, 2, 3]).unwrap();
768    ///
769    /// assert_eq!(model.state_metadata.number_of_vector_variables(), 1);
770    /// ```
771    #[inline]
772    pub fn number_of_vector_variables(&self) -> usize {
773        self.vector_variable_names.len()
774    }
775
776    /// Returns the number of element variables.
777    ///
778    /// # Examples
779    ///
780    /// ```
781    /// use dypdl::prelude::*;
782    ///
783    /// let mut model = Model::default();
784    /// let object_type = model.add_object_type("object", 4).unwrap();
785    /// model.add_element_variable("variable", object_type, 0).unwrap();
786    ///
787    /// assert_eq!(model.state_metadata.number_of_element_variables(), 1);
788    /// ```
789    #[inline]
790    pub fn number_of_element_variables(&self) -> usize {
791        self.element_variable_names.len()
792    }
793
794    /// Returns the number of integer variables.
795    ///
796    /// # Examples
797    ///
798    /// ```
799    /// use dypdl::prelude::*;
800    ///
801    /// let mut model = Model::default();
802    /// model.add_integer_variable("variable", 0).unwrap();
803    ///
804    /// assert_eq!(model.state_metadata.number_of_integer_variables(), 1);
805    /// ```
806    #[inline]
807    pub fn number_of_integer_variables(&self) -> usize {
808        self.integer_variable_names.len()
809    }
810
811    /// Returns the number of continuous variables.
812    ///
813    /// # Examples
814    ///
815    /// ```
816    /// use dypdl::prelude::*;
817    ///
818    /// let mut model = Model::default();
819    /// model.add_continuous_variable("variable", 0.5).unwrap();
820    ///
821    /// assert_eq!(model.state_metadata.number_of_continuous_variables(), 1);
822    /// ```
823    #[inline]
824    pub fn number_of_continuous_variables(&self) -> usize {
825        self.continuous_variable_names.len()
826    }
827
828    /// Returns the number of element resource variables.
829    ///
830    /// # Examples
831    ///
832    /// ```
833    /// use dypdl::prelude::*;
834    ///
835    /// let mut model = Model::default();
836    /// let object_type = model.add_object_type("object", 4).unwrap();
837    /// model.add_element_resource_variable("variable", object_type, false, 0).unwrap();
838    ///
839    /// assert_eq!(model.state_metadata.number_of_element_resource_variables(), 1);
840    /// ```
841    #[inline]
842    pub fn number_of_element_resource_variables(&self) -> usize {
843        self.element_resource_variable_names.len()
844    }
845
846    /// Returns the number of integer resource variables.
847    ///
848    /// # Examples
849    ///
850    /// ```
851    /// use dypdl::prelude::*;
852    ///
853    /// let mut model = Model::default();
854    /// model.add_integer_resource_variable("variable", false, 0).unwrap();
855    ///
856    /// assert_eq!(model.state_metadata.number_of_integer_resource_variables(), 1);
857    /// ```
858    #[inline]
859    pub fn number_of_integer_resource_variables(&self) -> usize {
860        self.integer_resource_variable_names.len()
861    }
862
863    /// Returns the number of continuous resource variables.
864    ///
865    /// ```
866    /// use dypdl::prelude::*;
867    ///
868    /// let mut model = Model::default();
869    /// model.add_continuous_resource_variable("variable", false, 0.5).unwrap();
870    ///
871    /// assert_eq!(model.state_metadata.number_of_continuous_resource_variables(), 1);
872    /// ```
873    #[inline]
874    pub fn number_of_continuous_resource_variables(&self) -> usize {
875        self.continuous_resource_variable_names.len()
876    }
877
878    /// Returns true if there is a resource variable and false otherwise.
879    pub fn has_resource_variables(&self) -> bool {
880        self.number_of_element_resource_variables() > 0
881            || self.number_of_integer_resource_variables() > 0
882            || self.number_of_continuous_resource_variables() > 0
883    }
884
885    /// Returns the set of names used by object types and variables.
886    pub fn get_name_set(&self) -> FxHashSet<String> {
887        let mut name_set = FxHashSet::default();
888        for name in &self.object_type_names {
889            name_set.insert(name.clone());
890        }
891        for name in &self.set_variable_names {
892            name_set.insert(name.clone());
893        }
894        for name in &self.vector_variable_names {
895            name_set.insert(name.clone());
896        }
897        for name in &self.element_variable_names {
898            name_set.insert(name.clone());
899        }
900        for name in &self.integer_variable_names {
901            name_set.insert(name.clone());
902        }
903        for name in &self.continuous_variable_names {
904            name_set.insert(name.clone());
905        }
906        for name in &self.element_resource_variable_names {
907            name_set.insert(name.clone());
908        }
909        for name in &self.integer_resource_variable_names {
910            name_set.insert(name.clone());
911        }
912        for name in &self.continuous_resource_variable_names {
913            name_set.insert(name.clone());
914        }
915        name_set
916    }
917
918    /// Returns the dominance relation between two states.
919    ///
920    /// # Panics
921    ///
922    /// Panics the metadata is wrong.
923    ///
924    /// # Examples
925    ///
926    /// ```
927    /// use dypdl::prelude::*;
928    /// use std::cmp::Ordering;
929    ///
930    /// let mut model = Model::default();
931    /// let v1 = model.add_integer_resource_variable("v1", false, 1).unwrap();
932    /// let v2 = model.add_continuous_resource_variable("v2", true, 1.5).unwrap();
933    /// let a = model.target.clone();
934    ///
935    /// model.set_target(v1, 0).unwrap();
936    /// model.set_target(v2, 2.5).unwrap();
937    /// let b = model.target.clone();
938    /// assert_eq!(model.state_metadata.dominance(&a, &b), Some(Ordering::Greater));
939    ///
940    /// model.set_target(v1, 1).unwrap();
941    /// model.set_target(v2, 0.5).unwrap();
942    /// let b = model.target.clone();
943    /// assert_eq!(model.state_metadata.dominance(&a, &b), Some(Ordering::Less));
944    ///
945    /// model.set_target(v1, 0).unwrap();
946    /// model.set_target(v2, 0.5).unwrap();
947    /// let b = model.target.clone();
948    /// assert_eq!(model.state_metadata.dominance(&a, &b), None);
949    /// ```
950    pub fn dominance<U: StateInterface, V: StateInterface>(
951        &self,
952        a: &U,
953        b: &V,
954    ) -> Option<Ordering> {
955        let status = Some(Ordering::Equal);
956        let x = |i| a.get_element_resource_variable(i);
957        let y = |i| b.get_element_resource_variable(i);
958        let status = Self::compare_resource_variables(&x, &y, &self.element_less_is_better, status);
959        status?;
960        let x = |i| a.get_integer_resource_variable(i);
961        let y = |i| b.get_integer_resource_variable(i);
962        let status = Self::compare_resource_variables(&x, &y, &self.integer_less_is_better, status);
963        status?;
964        let x = |i| a.get_continuous_resource_variable(i);
965        let y = |i| b.get_continuous_resource_variable(i);
966        Self::compare_resource_variables(&x, &y, &self.continuous_less_is_better, status)
967    }
968
969    fn compare_resource_variables<T: PartialOrd, F, G>(
970        x: &F,
971        y: &G,
972        less_is_better: &[bool],
973        mut status: Option<Ordering>,
974    ) -> Option<Ordering>
975    where
976        F: Fn(usize) -> T,
977        G: Fn(usize) -> T,
978    {
979        for (i, less_is_better) in less_is_better.iter().enumerate() {
980            let v1 = x(i);
981            let v2 = y(i);
982            match status {
983                Some(Ordering::Equal) => {
984                    if v1 < v2 {
985                        if *less_is_better {
986                            status = Some(Ordering::Greater);
987                        } else {
988                            status = Some(Ordering::Less);
989                        }
990                    }
991                    if v1 > v2 {
992                        if *less_is_better {
993                            status = Some(Ordering::Less);
994                        } else {
995                            status = Some(Ordering::Greater);
996                        }
997                    }
998                }
999                Some(Ordering::Less) => {
1000                    if v1 < v2 {
1001                        if *less_is_better {
1002                            return None;
1003                        }
1004                    } else if v1 > v2 && !less_is_better {
1005                        return None;
1006                    }
1007                }
1008                Some(Ordering::Greater) => {
1009                    if v1 > v2 {
1010                        if *less_is_better {
1011                            return None;
1012                        }
1013                    } else if v1 < v2 && !less_is_better {
1014                        return None;
1015                    }
1016                }
1017                None => {}
1018            }
1019        }
1020        status
1021    }
1022
1023    /// Check if a state is valid.
1024    ///
1025    /// # Errors
1026    ///
1027    /// If a state is invalid, e.g., it contains variables not existing in this model.
1028    pub fn check_state<'a, T: StateInterface>(&self, state: &'a T) -> Result<(), ModelErr>
1029    where
1030        &'a T: panic::UnwindSafe,
1031    {
1032        let n = self.number_of_element_variables();
1033        for i in 0..n {
1034            let v = panic::catch_unwind(|| state.get_element_variable(i));
1035            if v.is_err() {
1036                return Err(ModelErr::new(format!(
1037                    "{i} th element variable does not exists",
1038                )));
1039            }
1040            let v = v.unwrap();
1041            let m = self.object_numbers[self.element_variable_to_object[i]];
1042            if v >= m {
1043                return Err(ModelErr::new(format!(
1044                    "value {i} for an element variable >= #objects ({m})",
1045                )));
1046            }
1047        }
1048        let n = self.number_of_element_resource_variables();
1049        for i in 0..n {
1050            let v = panic::catch_unwind(|| state.get_element_resource_variable(i));
1051            if v.is_err() {
1052                return Err(ModelErr::new(format!(
1053                    "{i} th element resource variable does not exist",
1054                )));
1055            }
1056            let v = v.unwrap();
1057            let m = self.object_numbers[self.element_resource_variable_to_object[i]];
1058            if v >= m {
1059                return Err(ModelErr::new(format!(
1060                    "value {i} for an element resource variable >= #objects ({m})",
1061                )));
1062            }
1063        }
1064        let n = self.number_of_set_variables();
1065        for i in 0..n {
1066            let v = panic::catch_unwind(|| state.get_set_variable(i));
1067            if v.is_err() {
1068                return Err(ModelErr::new(format!(
1069                    "{i} th set variable does not exists",
1070                )));
1071            }
1072            let v = v.unwrap();
1073            let m = self.object_numbers[self.set_variable_to_object[i]];
1074            if v.len() > m {
1075                return Err(ModelErr::new(format!(
1076                    "set size {} for {i} th set variable > #objects ({m})",
1077                    v.len(),
1078                )));
1079            }
1080        }
1081        let n = self.number_of_vector_variables();
1082        for i in 0..n {
1083            let v = panic::catch_unwind(|| state.get_vector_variable(i));
1084            if v.is_err() {
1085                return Err(ModelErr::new(format!(
1086                    "{i} th vector variable does not exists",
1087                )));
1088            }
1089            let v = v.unwrap();
1090            let m = self.object_numbers[self.vector_variable_to_object[i]];
1091            if v.iter().any(|v| *v >= m) {
1092                return Err(ModelErr::new(format!(
1093                    "vector for {i} th vector variable contains a value >= #objects ({m})",
1094                )));
1095            }
1096        }
1097        let n = self.number_of_integer_variables();
1098        for i in 0..n {
1099            let v = panic::catch_unwind(|| state.get_integer_variable(i));
1100            if v.is_err() {
1101                return Err(ModelErr::new(format!(
1102                    "{i} th integer variable does not exist",
1103                )));
1104            }
1105        }
1106        let n = self.number_of_integer_resource_variables();
1107        for i in 0..n {
1108            let v = panic::catch_unwind(|| state.get_integer_resource_variable(i));
1109            if v.is_err() {
1110                return Err(ModelErr::new(format!(
1111                    "{i} th integer resource variable does not exist",
1112                )));
1113            }
1114        }
1115        let n = self.number_of_continuous_variables();
1116        for i in 0..n {
1117            let v = panic::catch_unwind(|| state.get_continuous_variable(i));
1118            if v.is_err() {
1119                return Err(ModelErr::new(format!(
1120                    "{i} th continuous variable does not exist",
1121                )));
1122            }
1123        }
1124        let n = self.number_of_continuous_resource_variables();
1125        for i in 0..n {
1126            let v = panic::catch_unwind(|| state.get_continuous_resource_variable(i));
1127            if v.is_err() {
1128                return Err(ModelErr::new(format!(
1129                    "{i} th continuous resource variable does not exist",
1130                )));
1131            }
1132        }
1133        Ok(())
1134    }
1135
1136    /// Returns object type given a name.
1137    ///
1138    /// # Errors
1139    ///
1140    /// If no object type with the name.
1141    pub fn get_object_type(&self, name: &str) -> Result<ObjectType, ModelErr> {
1142        if let Some(id) = self.name_to_object_type.get(name) {
1143            Ok(ObjectType(*id))
1144        } else {
1145            Err(ModelErr::new(format!("no such object `{name}`")))
1146        }
1147    }
1148
1149    /// Adds an object type and returns it.
1150    ///
1151    /// # Errors
1152    ///
1153    /// If the name is already used.
1154    pub fn add_object_type<T>(&mut self, name: T, number: usize) -> Result<ObjectType, ModelErr>
1155    where
1156        String: From<T>,
1157    {
1158        let name = String::from(name);
1159        match self.name_to_object_type.entry(name) {
1160            Entry::Vacant(e) => {
1161                let id = self.object_type_names.len();
1162                self.object_type_names.push(e.key().clone());
1163                self.object_numbers.push(number);
1164                e.insert(id);
1165                Ok(ObjectType(id))
1166            }
1167            Entry::Occupied(e) => Err(ModelErr::new(format!(
1168                "object `{key}` already exists",
1169                key = e.key()
1170            ))),
1171        }
1172    }
1173
1174    /// Returns the number of objects associated with the type.
1175    ///
1176    /// # Errors
1177    ///
1178    /// If the object type is not in the model.
1179    pub fn get_number_of_objects(&self, ob: ObjectType) -> Result<usize, ModelErr> {
1180        self.check_object(ob)?;
1181        Ok(self.object_numbers[ob.id()])
1182    }
1183
1184    // Disabled because it is inconsistent with the other modeling interfaces.
1185    // /// Change the number of objects.
1186    // ///
1187    // /// # Errors
1188    // ///
1189    // /// If the object type is not in the model.
1190    // pub fn set_number_of_object(&mut self, ob: ObjectType, number: usize) -> Result<(), ModelErr> {
1191    //     self.check_object(ob)?;
1192    //     self.object_numbers[ob.id()] = number;
1193    //     Ok(())
1194    // }
1195
1196    /// Create a set of objects associated with the type.
1197    ///
1198    /// # Errors
1199    ///
1200    /// If the object type is not in the model or an input value is greater than or equal to the number of the objects.
1201    pub fn create_set(&self, ob: ObjectType, array: &[Element]) -> Result<Set, ModelErr> {
1202        let n = self.get_number_of_objects(ob)?;
1203        let mut set = Set::with_capacity(n);
1204        for v in array {
1205            if *v >= n {
1206                return Err(ModelErr::new(format!(
1207                    "index {v} for object >= #objects ({n})",
1208                )));
1209            }
1210            set.insert(*v);
1211        }
1212        Ok(set)
1213    }
1214
1215    /// Returns an element variable given a name.
1216    ///
1217    /// # Errors
1218    ///
1219    /// If no such variable.
1220    #[inline]
1221    pub fn get_element_variable(&self, name: &str) -> Result<ElementVariable, ModelErr> {
1222        let id = util::get_id(name, &self.name_to_element_variable)?;
1223        Ok(ElementVariable(id))
1224    }
1225
1226    /// Adds and returns an element variable.
1227    ///
1228    /// The value in the target state must be specified.
1229    ///
1230    /// # Errors
1231    ///
1232    /// If the name is already used or the object type is not in the model.
1233    pub fn add_element_variable<T>(
1234        &mut self,
1235        name: T,
1236        ob: ObjectType,
1237    ) -> Result<ElementVariable, ModelErr>
1238    where
1239        String: From<T>,
1240    {
1241        self.check_object(ob)?;
1242        let id = util::add_name(
1243            name,
1244            &mut self.element_variable_names,
1245            &mut self.name_to_element_variable,
1246        )?;
1247        self.element_variable_to_object.push(ob.id());
1248        Ok(ElementVariable(id))
1249    }
1250
1251    /// Returns an element resource variable given a name.
1252    ///
1253    /// # Errors
1254    ///
1255    /// If no such variable.
1256    #[inline]
1257    pub fn get_element_resource_variable(
1258        &self,
1259        name: &str,
1260    ) -> Result<ElementResourceVariable, ModelErr> {
1261        let id = util::get_id(name, &self.name_to_element_resource_variable)?;
1262        Ok(ElementResourceVariable(id))
1263    }
1264
1265    /// Adds and returns an element resource variable.
1266    ///
1267    /// The value in the target state must be specified.
1268    ///
1269    /// # Errors
1270    ///
1271    /// If the name is already used or the object type is not in the model.
1272    pub fn add_element_resource_variable<T>(
1273        &mut self,
1274        name: T,
1275        ob: ObjectType,
1276        less_is_better: bool,
1277    ) -> Result<ElementResourceVariable, ModelErr>
1278    where
1279        String: From<T>,
1280    {
1281        self.check_object(ob)?;
1282        let id = util::add_name(
1283            name,
1284            &mut self.element_resource_variable_names,
1285            &mut self.name_to_element_resource_variable,
1286        )?;
1287        self.element_resource_variable_to_object.push(ob.id());
1288        self.element_less_is_better.push(less_is_better);
1289        Ok(ElementResourceVariable(id))
1290    }
1291
1292    /// Returns a set variable given a name.
1293    ///
1294    /// # Errors
1295    ///
1296    /// If no such variable.
1297    #[inline]
1298    pub fn get_set_variable(&self, name: &str) -> Result<SetVariable, ModelErr> {
1299        let id = util::get_id(name, &self.name_to_set_variable)?;
1300        Ok(SetVariable(id))
1301    }
1302
1303    /// Adds and returns a set variable.
1304    ///
1305    /// The value in the target state must be specified.
1306    ///
1307    /// # Errors
1308    ///
1309    /// If the name is already used or the object type is not in the model.
1310    pub fn add_set_variable<T>(&mut self, name: T, ob: ObjectType) -> Result<SetVariable, ModelErr>
1311    where
1312        String: From<T>,
1313    {
1314        self.check_object(ob)?;
1315        let id = util::add_name(
1316            name,
1317            &mut self.set_variable_names,
1318            &mut self.name_to_set_variable,
1319        )?;
1320        self.set_variable_to_object.push(ob.id());
1321        Ok(SetVariable(id))
1322    }
1323
1324    /// Returns a vector variable given a name.
1325    ///
1326    /// # Errors
1327    ///
1328    /// If no such variable.
1329    #[inline]
1330    pub fn get_vector_variable(&self, name: &str) -> Result<VectorVariable, ModelErr> {
1331        let id = util::get_id(name, &self.name_to_vector_variable)?;
1332        Ok(VectorVariable(id))
1333    }
1334
1335    /// Adds and returns a vector variable.
1336    ///
1337    /// The value in the target state must be specified.
1338    ///
1339    /// # Errors
1340    ///
1341    /// If the name is already used or the object type is not in the model.
1342    pub fn add_vector_variable<T>(
1343        &mut self,
1344        name: T,
1345        ob: ObjectType,
1346    ) -> Result<VectorVariable, ModelErr>
1347    where
1348        String: From<T>,
1349    {
1350        self.check_object(ob)?;
1351        let id = util::add_name(
1352            name,
1353            &mut self.vector_variable_names,
1354            &mut self.name_to_vector_variable,
1355        )?;
1356        self.vector_variable_to_object.push(ob.id());
1357        Ok(VectorVariable(id))
1358    }
1359
1360    /// Returns an integer variable given a name.
1361    ///
1362    /// # Errors
1363    ///
1364    /// If no such variable.
1365    #[inline]
1366    pub fn get_integer_variable(&self, name: &str) -> Result<IntegerVariable, ModelErr> {
1367        let id = util::get_id(name, &self.name_to_integer_variable)?;
1368        Ok(IntegerVariable(id))
1369    }
1370
1371    /// Adds and returns an integer variable.
1372    ///
1373    /// The value in the target state must be specified.
1374    ///
1375    /// # Errors
1376    ///
1377    /// If the name is already used.
1378    pub fn add_integer_variable<T>(&mut self, name: T) -> Result<IntegerVariable, ModelErr>
1379    where
1380        String: From<T>,
1381    {
1382        let id = util::add_name(
1383            name,
1384            &mut self.integer_variable_names,
1385            &mut self.name_to_integer_variable,
1386        )?;
1387        Ok(IntegerVariable(id))
1388    }
1389
1390    /// Returns an integer resource variable given a name.
1391    ///
1392    /// # Errors
1393    ///
1394    /// If no such variable.
1395    #[inline]
1396    pub fn get_integer_resource_variable(
1397        &self,
1398        name: &str,
1399    ) -> Result<IntegerResourceVariable, ModelErr> {
1400        let id = util::get_id(name, &self.name_to_integer_resource_variable)?;
1401        Ok(IntegerResourceVariable(id))
1402    }
1403
1404    /// Adds and returns an integer resource variable.
1405    ///
1406    /// The value in the target state must be specified.
1407    ///
1408    /// # Errors
1409    ///
1410    /// If the name is already used.
1411    pub fn add_integer_resource_variable<T>(
1412        &mut self,
1413        name: T,
1414        less_is_better: bool,
1415    ) -> Result<IntegerResourceVariable, ModelErr>
1416    where
1417        String: From<T>,
1418    {
1419        let id = util::add_name(
1420            name,
1421            &mut self.integer_resource_variable_names,
1422            &mut self.name_to_integer_resource_variable,
1423        )?;
1424        self.integer_less_is_better.push(less_is_better);
1425        Ok(IntegerResourceVariable(id))
1426    }
1427
1428    /// Returns a continuous variable given a name.
1429    ///
1430    /// # Errors
1431    ///
1432    /// If no such variable.
1433    #[inline]
1434    pub fn get_continuous_variable(&self, name: &str) -> Result<ContinuousVariable, ModelErr> {
1435        let id = util::get_id(name, &self.name_to_continuous_variable)?;
1436        Ok(ContinuousVariable(id))
1437    }
1438
1439    /// Adds and returns a continuous variable.
1440    ///
1441    /// The value in the target state must be specified.
1442    ///
1443    /// # Errors
1444    ///
1445    /// If the name is already used.
1446    pub fn add_continuous_variable<T>(&mut self, name: T) -> Result<ContinuousVariable, ModelErr>
1447    where
1448        String: From<T>,
1449    {
1450        let id = util::add_name(
1451            name,
1452            &mut self.continuous_variable_names,
1453            &mut self.name_to_continuous_variable,
1454        )?;
1455        Ok(ContinuousVariable(id))
1456    }
1457
1458    /// Returns a continuous resource variable given a name.
1459    ///
1460    /// # Errors
1461    ///
1462    /// If no such variable.
1463    #[inline]
1464    pub fn get_continuous_resource_variable(
1465        &self,
1466        name: &str,
1467    ) -> Result<ContinuousResourceVariable, ModelErr> {
1468        let id = util::get_id(name, &self.name_to_continuous_resource_variable)?;
1469        Ok(ContinuousResourceVariable(id))
1470    }
1471
1472    /// Adds and returns a continuous resource variable.
1473    ///
1474    /// The value in the target state must be specified.
1475    ///
1476    /// # Errors
1477    ///
1478    /// If the name is already used.
1479    pub fn add_continuous_resource_variable<T>(
1480        &mut self,
1481        name: T,
1482        less_is_better: bool,
1483    ) -> Result<ContinuousResourceVariable, ModelErr>
1484    where
1485        String: From<T>,
1486    {
1487        let id = util::add_name(
1488            name,
1489            &mut self.continuous_resource_variable_names,
1490            &mut self.name_to_continuous_resource_variable,
1491        )?;
1492        self.continuous_less_is_better.push(less_is_better);
1493        Ok(ContinuousResourceVariable(id))
1494    }
1495
1496    fn check_object(&self, ob: ObjectType) -> Result<(), ModelErr> {
1497        if ob.id() >= self.number_of_object_types() {
1498            Err(ModelErr::new(format!(
1499                "object id {id} >= #object types ({len})",
1500                id = ob.id(),
1501                len = self.object_numbers.len()
1502            )))
1503        } else {
1504            Ok(())
1505        }
1506    }
1507}
1508
1509/// Trait for checking if a variable is defined.
1510pub trait CheckVariable<T> {
1511    /// Check if the variable is defined.
1512    ///
1513    /// # Errors
1514    /// If the variable is not defined.
1515    fn check_variable(&self, v: T) -> Result<(), ModelErr>;
1516}
1517
1518macro_rules! impl_check_variable {
1519    ($T:ty,$x:ident) => {
1520        impl CheckVariable<$T> for StateMetadata {
1521            fn check_variable(&self, v: $T) -> Result<(), ModelErr> {
1522                let id = v.id();
1523                let n = self.$x.len();
1524                if id >= n {
1525                    Err(ModelErr::new(format!(
1526                        "variable id {id} >= #variables ({n})",
1527                    )))
1528                } else {
1529                    Ok(())
1530                }
1531            }
1532        }
1533    };
1534}
1535
1536impl_check_variable!(ElementVariable, element_variable_names);
1537impl_check_variable!(ElementResourceVariable, element_resource_variable_names);
1538impl_check_variable!(SetVariable, set_variable_names);
1539impl_check_variable!(VectorVariable, vector_variable_names);
1540impl_check_variable!(IntegerVariable, integer_variable_names);
1541impl_check_variable!(IntegerResourceVariable, integer_resource_variable_names);
1542impl_check_variable!(ContinuousVariable, continuous_variable_names);
1543impl_check_variable!(
1544    ContinuousResourceVariable,
1545    continuous_resource_variable_names
1546);
1547
1548/// Trait for getting the object type.
1549///
1550/// # Examples
1551///
1552/// ```
1553/// use dypdl::prelude::*;
1554///
1555/// let mut model = Model::default();
1556/// let object_type = model.add_object_type("object", 4).unwrap();
1557/// let variable = model.add_element_variable("variable", object_type, 0).unwrap();
1558///
1559/// assert!(model.get_object_type_of(variable).is_ok())
1560/// ```
1561pub trait GetObjectTypeOf<T> {
1562    /// Returns the object type of the variable.
1563    ///
1564    /// # Errors
1565    ///
1566    /// If the variable is not included in the model.
1567    fn get_object_type_of(&self, v: T) -> Result<ObjectType, ModelErr>;
1568}
1569
1570macro_rules! impl_get_object_type_of {
1571    ($T:ty,$x:ident) => {
1572        impl GetObjectTypeOf<$T> for StateMetadata {
1573            fn get_object_type_of(&self, v: $T) -> Result<ObjectType, ModelErr> {
1574                self.check_variable(v)?;
1575                Ok(ObjectType(self.$x[v.id()]))
1576            }
1577        }
1578    };
1579}
1580
1581impl_get_object_type_of!(ElementVariable, element_variable_to_object);
1582impl_get_object_type_of!(ElementResourceVariable, element_resource_variable_to_object);
1583impl_get_object_type_of!(SetVariable, set_variable_to_object);
1584impl_get_object_type_of!(VectorVariable, vector_variable_to_object);
1585
1586/// Trait for accessing preference of resource variables.
1587///
1588/// # Examples
1589///
1590/// ```
1591/// use dypdl::prelude::*;
1592///
1593/// let mut model = Model::default();
1594/// let variable = model.add_integer_resource_variable("variable", true, 0).unwrap();
1595///
1596/// assert!(model.get_preference(variable).unwrap());
1597/// assert!(model.set_preference(variable, false).is_ok());
1598/// assert!(!model.get_preference(variable).unwrap());
1599/// ```
1600pub trait AccessPreference<T> {
1601    /// Returns the preference of a resource variable.
1602    ///
1603    /// # Errors
1604    ///
1605    /// If the variable is not included in the model.
1606    fn get_preference(&self, v: T) -> Result<bool, ModelErr>;
1607    /// Sets the preference of a resource variable.
1608    ///
1609    /// # Errors
1610    ///
1611    /// If the variable is not included in the model.
1612    fn set_preference(&mut self, v: T, less_is_better: bool) -> Result<(), ModelErr>;
1613}
1614
1615macro_rules! impl_access_preference {
1616    ($T:ty,$x:ident) => {
1617        impl AccessPreference<$T> for StateMetadata {
1618            fn get_preference(&self, v: $T) -> Result<bool, ModelErr> {
1619                self.check_variable(v)?;
1620                Ok(self.$x[v.id()])
1621            }
1622
1623            fn set_preference(&mut self, v: $T, less_is_better: bool) -> Result<(), ModelErr> {
1624                self.check_variable(v)?;
1625                self.$x[v.id()] = less_is_better;
1626                Ok(())
1627            }
1628        }
1629    };
1630}
1631
1632impl_access_preference!(ElementResourceVariable, element_less_is_better);
1633impl_access_preference!(IntegerResourceVariable, integer_less_is_better);
1634impl_access_preference!(ContinuousResourceVariable, continuous_less_is_better);
1635
1636#[cfg(test)]
1637mod tests {
1638    use super::super::expression::*;
1639    use super::*;
1640
1641    fn generate_metadata() -> StateMetadata {
1642        let object_names = vec![String::from("object"), String::from("small")];
1643        let object_numbers = vec![10, 2];
1644        let mut name_to_object = FxHashMap::default();
1645        name_to_object.insert(String::from("object"), 0);
1646        name_to_object.insert(String::from("small"), 1);
1647
1648        let set_variable_names = vec![
1649            String::from("s0"),
1650            String::from("s1"),
1651            String::from("s2"),
1652            String::from("s3"),
1653        ];
1654        let mut name_to_set_variable = FxHashMap::default();
1655        name_to_set_variable.insert(String::from("s0"), 0);
1656        name_to_set_variable.insert(String::from("s1"), 1);
1657        name_to_set_variable.insert(String::from("s2"), 2);
1658        name_to_set_variable.insert(String::from("s3"), 3);
1659        let set_variable_to_object = vec![0, 0, 0, 1];
1660
1661        let vector_variable_names = vec![
1662            String::from("p0"),
1663            String::from("p1"),
1664            String::from("p2"),
1665            String::from("p3"),
1666        ];
1667        let mut name_to_vector_variable = FxHashMap::default();
1668        name_to_vector_variable.insert(String::from("p0"), 0);
1669        name_to_vector_variable.insert(String::from("p1"), 1);
1670        name_to_vector_variable.insert(String::from("p2"), 2);
1671        name_to_vector_variable.insert(String::from("p3"), 3);
1672        let vector_variable_to_object = vec![0, 0, 0, 1];
1673
1674        let element_variable_names = vec![
1675            String::from("e0"),
1676            String::from("e1"),
1677            String::from("e2"),
1678            String::from("e3"),
1679        ];
1680        let mut name_to_element_variable = FxHashMap::default();
1681        name_to_element_variable.insert(String::from("e0"), 0);
1682        name_to_element_variable.insert(String::from("e1"), 1);
1683        name_to_element_variable.insert(String::from("e2"), 2);
1684        name_to_element_variable.insert(String::from("e3"), 3);
1685        let element_variable_to_object = vec![0, 0, 0, 1];
1686
1687        let integer_variable_names = vec![
1688            String::from("i0"),
1689            String::from("i1"),
1690            String::from("i2"),
1691            String::from("i3"),
1692        ];
1693        let mut name_to_integer_variable = FxHashMap::default();
1694        name_to_integer_variable.insert(String::from("i0"), 0);
1695        name_to_integer_variable.insert(String::from("i1"), 1);
1696        name_to_integer_variable.insert(String::from("i2"), 2);
1697        name_to_integer_variable.insert(String::from("i3"), 3);
1698
1699        let continuous_variable_names = vec![
1700            String::from("c0"),
1701            String::from("c1"),
1702            String::from("c2"),
1703            String::from("c3"),
1704        ];
1705        let mut name_to_continuous_variable = FxHashMap::default();
1706        name_to_continuous_variable.insert(String::from("c0"), 0);
1707        name_to_continuous_variable.insert(String::from("c1"), 1);
1708        name_to_continuous_variable.insert(String::from("c2"), 2);
1709        name_to_continuous_variable.insert(String::from("c3"), 3);
1710
1711        let element_resource_variable_names = vec![
1712            String::from("er0"),
1713            String::from("er1"),
1714            String::from("er2"),
1715            String::from("er3"),
1716        ];
1717        let mut name_to_element_resource_variable = FxHashMap::default();
1718        name_to_element_resource_variable.insert(String::from("er0"), 0);
1719        name_to_element_resource_variable.insert(String::from("er1"), 1);
1720        name_to_element_resource_variable.insert(String::from("er2"), 2);
1721        name_to_element_resource_variable.insert(String::from("er3"), 3);
1722        let element_resource_variable_to_object = vec![0, 0, 0, 1];
1723
1724        let integer_resource_variable_names = vec![
1725            String::from("ir0"),
1726            String::from("ir1"),
1727            String::from("ir2"),
1728            String::from("ir3"),
1729        ];
1730        let mut name_to_integer_resource_variable = FxHashMap::default();
1731        name_to_integer_resource_variable.insert(String::from("ir0"), 0);
1732        name_to_integer_resource_variable.insert(String::from("ir1"), 1);
1733        name_to_integer_resource_variable.insert(String::from("ir2"), 2);
1734        name_to_integer_resource_variable.insert(String::from("ir3"), 3);
1735
1736        let continuous_resource_variable_names = vec![
1737            String::from("cr0"),
1738            String::from("cr1"),
1739            String::from("cr2"),
1740            String::from("cr3"),
1741        ];
1742        let mut name_to_continuous_resource_variable = FxHashMap::default();
1743        name_to_continuous_resource_variable.insert(String::from("cr0"), 0);
1744        name_to_continuous_resource_variable.insert(String::from("cr1"), 1);
1745        name_to_continuous_resource_variable.insert(String::from("cr2"), 2);
1746        name_to_continuous_resource_variable.insert(String::from("cr3"), 3);
1747
1748        StateMetadata {
1749            object_type_names: object_names,
1750            name_to_object_type: name_to_object,
1751            object_numbers,
1752            set_variable_names,
1753            name_to_set_variable,
1754            set_variable_to_object,
1755            vector_variable_names,
1756            name_to_vector_variable,
1757            vector_variable_to_object,
1758            element_variable_names,
1759            name_to_element_variable,
1760            element_variable_to_object,
1761            integer_variable_names,
1762            name_to_integer_variable,
1763            continuous_variable_names,
1764            name_to_continuous_variable,
1765            element_resource_variable_names,
1766            name_to_element_resource_variable,
1767            element_resource_variable_to_object,
1768            element_less_is_better: vec![false, false, true, false],
1769            integer_resource_variable_names,
1770            name_to_integer_resource_variable,
1771            integer_less_is_better: vec![false, false, true, false],
1772            continuous_resource_variable_names,
1773            name_to_continuous_resource_variable,
1774            continuous_less_is_better: vec![false, false, true, false],
1775        }
1776    }
1777
1778    #[test]
1779    fn state_get_number_of_set_variables() {
1780        let state = State {
1781            signature_variables: SignatureVariables {
1782                set_variables: vec![Set::default()],
1783                ..Default::default()
1784            },
1785            ..Default::default()
1786        };
1787        assert_eq!(state.get_number_of_set_variables(), 1);
1788    }
1789
1790    #[test]
1791    fn state_get_set_variable() {
1792        let mut set = Set::with_capacity(2);
1793        set.insert(1);
1794        let state = State {
1795            signature_variables: SignatureVariables {
1796                set_variables: vec![Set::with_capacity(2), set.clone()],
1797                ..Default::default()
1798            },
1799            ..Default::default()
1800        };
1801        assert_eq!(state.get_set_variable(0), &Set::with_capacity(2));
1802        assert_eq!(state.get_set_variable(1), &set);
1803    }
1804
1805    #[test]
1806    #[should_panic]
1807    fn state_get_set_variable_panic() {
1808        let state = State {
1809            signature_variables: SignatureVariables {
1810                set_variables: vec![Set::default()],
1811                ..Default::default()
1812            },
1813            ..Default::default()
1814        };
1815        state.get_set_variable(1);
1816    }
1817
1818    #[test]
1819    fn state_get_number_of_vector_variables() {
1820        let state = State {
1821            signature_variables: SignatureVariables {
1822                vector_variables: vec![Vector::default()],
1823                ..Default::default()
1824            },
1825            ..Default::default()
1826        };
1827        assert_eq!(state.get_number_of_vector_variables(), 1);
1828    }
1829
1830    #[test]
1831    fn state_get_vector_variable() {
1832        let state = State {
1833            signature_variables: SignatureVariables {
1834                vector_variables: vec![Vector::default(), vec![1]],
1835                ..Default::default()
1836            },
1837            ..Default::default()
1838        };
1839        assert_eq!(state.get_vector_variable(0), &Vector::default());
1840        assert_eq!(state.get_vector_variable(1), &vec![1]);
1841    }
1842
1843    #[test]
1844    #[should_panic]
1845    fn state_get_vector_variable_panic() {
1846        let state = State {
1847            signature_variables: SignatureVariables {
1848                vector_variables: vec![Vector::default()],
1849                ..Default::default()
1850            },
1851            ..Default::default()
1852        };
1853        state.get_vector_variable(1);
1854    }
1855
1856    #[test]
1857    fn state_get_number_of_element_variables() {
1858        let state = State {
1859            signature_variables: SignatureVariables {
1860                element_variables: vec![0],
1861                ..Default::default()
1862            },
1863            ..Default::default()
1864        };
1865        assert_eq!(state.get_number_of_element_variables(), 1);
1866    }
1867
1868    #[test]
1869    fn state_get_element_variable() {
1870        let state = State {
1871            signature_variables: SignatureVariables {
1872                element_variables: vec![0, 1],
1873                ..Default::default()
1874            },
1875            ..Default::default()
1876        };
1877        assert_eq!(state.get_element_variable(0), 0);
1878        assert_eq!(state.get_element_variable(1), 1);
1879    }
1880
1881    #[test]
1882    #[should_panic]
1883    fn state_get_element_variable_panic() {
1884        let state = State {
1885            signature_variables: SignatureVariables {
1886                element_variables: vec![0],
1887                ..Default::default()
1888            },
1889            ..Default::default()
1890        };
1891        state.get_element_variable(1);
1892    }
1893
1894    #[test]
1895    fn state_get_number_of_integer_variables() {
1896        let state = State {
1897            signature_variables: SignatureVariables {
1898                integer_variables: vec![0],
1899                ..Default::default()
1900            },
1901            ..Default::default()
1902        };
1903        assert_eq!(state.get_number_of_integer_variables(), 1);
1904    }
1905
1906    #[test]
1907    fn state_get_integer_variable() {
1908        let state = State {
1909            signature_variables: SignatureVariables {
1910                integer_variables: vec![0, 1],
1911                ..Default::default()
1912            },
1913            ..Default::default()
1914        };
1915        assert_eq!(state.get_integer_variable(0), 0);
1916        assert_eq!(state.get_integer_variable(1), 1);
1917    }
1918
1919    #[test]
1920    #[should_panic]
1921    fn state_get_integer_variable_panic() {
1922        let state = State {
1923            signature_variables: SignatureVariables {
1924                integer_variables: vec![0],
1925                ..Default::default()
1926            },
1927            ..Default::default()
1928        };
1929        state.get_integer_variable(1);
1930    }
1931
1932    #[test]
1933    fn state_get_number_of_continuous_variables() {
1934        let state = State {
1935            signature_variables: SignatureVariables {
1936                continuous_variables: vec![0.0],
1937                ..Default::default()
1938            },
1939            ..Default::default()
1940        };
1941        assert_eq!(state.get_number_of_continuous_variables(), 1);
1942    }
1943
1944    #[test]
1945    fn state_get_continuous_variable() {
1946        let state = State {
1947            signature_variables: SignatureVariables {
1948                continuous_variables: vec![0.0, 1.0],
1949                ..Default::default()
1950            },
1951            ..Default::default()
1952        };
1953        assert_eq!(state.get_continuous_variable(0), 0.0);
1954        assert_eq!(state.get_continuous_variable(1), 1.0);
1955    }
1956
1957    #[test]
1958    #[should_panic]
1959    fn state_get_continuous_variable_panic() {
1960        let state = State {
1961            signature_variables: SignatureVariables {
1962                continuous_variables: vec![0.0],
1963                ..Default::default()
1964            },
1965            ..Default::default()
1966        };
1967        state.get_continuous_variable(1);
1968    }
1969
1970    #[test]
1971    fn state_get_number_of_element_resource_variables() {
1972        let state = State {
1973            resource_variables: ResourceVariables {
1974                element_variables: vec![0],
1975                ..Default::default()
1976            },
1977            ..Default::default()
1978        };
1979        assert_eq!(state.get_number_of_element_resource_variables(), 1);
1980    }
1981
1982    #[test]
1983    fn state_get_element_resource_variable() {
1984        let state = State {
1985            resource_variables: ResourceVariables {
1986                element_variables: vec![0, 1],
1987                ..Default::default()
1988            },
1989            ..Default::default()
1990        };
1991        assert_eq!(state.get_element_resource_variable(0), 0);
1992        assert_eq!(state.get_element_resource_variable(1), 1);
1993    }
1994
1995    #[test]
1996    #[should_panic]
1997    fn state_get_element_resource_variable_panic() {
1998        let state = State {
1999            resource_variables: ResourceVariables {
2000                element_variables: vec![0],
2001                ..Default::default()
2002            },
2003            ..Default::default()
2004        };
2005        state.get_element_resource_variable(1);
2006    }
2007
2008    #[test]
2009    fn state_get_number_of_integer_resource_variables() {
2010        let state = State {
2011            resource_variables: ResourceVariables {
2012                integer_variables: vec![0],
2013                ..Default::default()
2014            },
2015            ..Default::default()
2016        };
2017        assert_eq!(state.get_number_of_integer_resource_variables(), 1);
2018    }
2019
2020    #[test]
2021    fn state_get_integer_resource_variable() {
2022        let state = State {
2023            resource_variables: ResourceVariables {
2024                integer_variables: vec![0, 1],
2025                ..Default::default()
2026            },
2027            ..Default::default()
2028        };
2029        assert_eq!(state.get_integer_resource_variable(0), 0);
2030        assert_eq!(state.get_integer_resource_variable(1), 1);
2031    }
2032
2033    #[test]
2034    #[should_panic]
2035    fn state_get_integer_resource_variable_panic() {
2036        let state = State {
2037            resource_variables: ResourceVariables {
2038                integer_variables: vec![0],
2039                ..Default::default()
2040            },
2041            ..Default::default()
2042        };
2043        state.get_integer_resource_variable(1);
2044    }
2045
2046    #[test]
2047    fn state_get_number_of_continuous_resource_variables() {
2048        let state = State {
2049            resource_variables: ResourceVariables {
2050                continuous_variables: vec![0.0],
2051                ..Default::default()
2052            },
2053            ..Default::default()
2054        };
2055        assert_eq!(state.get_number_of_continuous_resource_variables(), 1);
2056    }
2057
2058    #[test]
2059    fn state_get_continuous_resource_variable() {
2060        let state = State {
2061            resource_variables: ResourceVariables {
2062                continuous_variables: vec![0.0, 1.0],
2063                ..Default::default()
2064            },
2065            ..Default::default()
2066        };
2067        assert_eq!(state.get_continuous_resource_variable(0), 0.0);
2068        assert_eq!(state.get_continuous_resource_variable(1), 1.0);
2069    }
2070
2071    #[test]
2072    #[should_panic]
2073    fn state_get_continuous_resource_variable_panic() {
2074        let state = State {
2075            resource_variables: ResourceVariables {
2076                continuous_variables: vec![0.0],
2077                ..Default::default()
2078            },
2079            ..Default::default()
2080        };
2081        state.get_continuous_resource_variable(1);
2082    }
2083
2084    #[test]
2085    fn apply_effect() {
2086        let state_functions = StateFunctions::default();
2087        let mut function_cache = StateFunctionCache::new(&state_functions);
2088
2089        let mut set1 = Set::with_capacity(3);
2090        set1.insert(0);
2091        set1.insert(2);
2092        let mut set2 = Set::with_capacity(3);
2093        set2.insert(0);
2094        set2.insert(1);
2095        let state = State {
2096            signature_variables: SignatureVariables {
2097                set_variables: vec![set1, set2],
2098                vector_variables: vec![vec![0, 2], vec![1, 2]],
2099                element_variables: vec![1, 2],
2100                integer_variables: vec![1, 2, 3],
2101                continuous_variables: vec![1.0, 2.0, 3.0],
2102            },
2103            resource_variables: ResourceVariables {
2104                element_variables: vec![],
2105                integer_variables: vec![4, 5, 6],
2106                continuous_variables: vec![4.0, 5.0, 6.0],
2107            },
2108        };
2109        let registry = table_registry::TableRegistry::default();
2110        let set_effect1 = SetExpression::SetElementOperation(
2111            SetElementOperator::Add,
2112            ElementExpression::Constant(1),
2113            Box::new(SetExpression::Reference(ReferenceExpression::Variable(0))),
2114        );
2115        let set_effect2 = SetExpression::SetElementOperation(
2116            SetElementOperator::Remove,
2117            ElementExpression::Constant(0),
2118            Box::new(SetExpression::Reference(ReferenceExpression::Variable(1))),
2119        );
2120        let vector_effect1 = VectorExpression::Push(
2121            ElementExpression::Constant(1),
2122            Box::new(VectorExpression::Reference(ReferenceExpression::Variable(
2123                0,
2124            ))),
2125        );
2126        let vector_effect2 = VectorExpression::Push(
2127            ElementExpression::Constant(0),
2128            Box::new(VectorExpression::Reference(ReferenceExpression::Variable(
2129                1,
2130            ))),
2131        );
2132        let element_effect1 = ElementExpression::Constant(2);
2133        let element_effect2 = ElementExpression::Constant(1);
2134        let integer_effect1 = IntegerExpression::BinaryOperation(
2135            BinaryOperator::Sub,
2136            Box::new(IntegerExpression::Variable(0)),
2137            Box::new(IntegerExpression::Constant(1)),
2138        );
2139        let integer_effect2 = IntegerExpression::BinaryOperation(
2140            BinaryOperator::Mul,
2141            Box::new(IntegerExpression::Variable(1)),
2142            Box::new(IntegerExpression::Constant(2)),
2143        );
2144        let continuous_effect1 = ContinuousExpression::BinaryOperation(
2145            BinaryOperator::Sub,
2146            Box::new(ContinuousExpression::Variable(0)),
2147            Box::new(ContinuousExpression::Constant(1.0)),
2148        );
2149        let continuous_effect2 = ContinuousExpression::BinaryOperation(
2150            BinaryOperator::Mul,
2151            Box::new(ContinuousExpression::Variable(1)),
2152            Box::new(ContinuousExpression::Constant(2.0)),
2153        );
2154        let integer_resource_effect1 = IntegerExpression::BinaryOperation(
2155            BinaryOperator::Add,
2156            Box::new(IntegerExpression::ResourceVariable(0)),
2157            Box::new(IntegerExpression::Constant(1)),
2158        );
2159        let integer_resource_effect2 = IntegerExpression::BinaryOperation(
2160            BinaryOperator::Div,
2161            Box::new(IntegerExpression::ResourceVariable(1)),
2162            Box::new(IntegerExpression::Constant(2)),
2163        );
2164        let continuous_resource_effect1 = ContinuousExpression::BinaryOperation(
2165            BinaryOperator::Add,
2166            Box::new(ContinuousExpression::ResourceVariable(0)),
2167            Box::new(ContinuousExpression::Constant(1.0)),
2168        );
2169        let continuous_resource_effect2 = ContinuousExpression::BinaryOperation(
2170            BinaryOperator::Div,
2171            Box::new(ContinuousExpression::ResourceVariable(1)),
2172            Box::new(ContinuousExpression::Constant(2.0)),
2173        );
2174        let effect = effect::Effect {
2175            set_effects: vec![(0, set_effect1), (1, set_effect2)],
2176            vector_effects: vec![(0, vector_effect1), (1, vector_effect2)],
2177            element_effects: vec![(0, element_effect1), (1, element_effect2)],
2178            integer_effects: vec![(0, integer_effect1), (1, integer_effect2)],
2179            continuous_effects: vec![(0, continuous_effect1), (1, continuous_effect2)],
2180            element_resource_effects: vec![],
2181            integer_resource_effects: vec![
2182                (0, integer_resource_effect1),
2183                (1, integer_resource_effect2),
2184            ],
2185            continuous_resource_effects: vec![
2186                (0, continuous_resource_effect1),
2187                (1, continuous_resource_effect2),
2188            ],
2189        };
2190
2191        let mut set1 = Set::with_capacity(3);
2192        set1.insert(0);
2193        set1.insert(1);
2194        set1.insert(2);
2195        let mut set2 = Set::with_capacity(3);
2196        set2.insert(1);
2197        let expected = State {
2198            signature_variables: SignatureVariables {
2199                set_variables: vec![set1, set2],
2200                vector_variables: vec![vec![0, 2, 1], vec![1, 2, 0]],
2201                element_variables: vec![2, 1],
2202                integer_variables: vec![0, 4, 3],
2203                continuous_variables: vec![0.0, 4.0, 3.0],
2204            },
2205            resource_variables: ResourceVariables {
2206                element_variables: vec![],
2207                integer_variables: vec![5, 2, 6],
2208                continuous_variables: vec![5.0, 2.5, 6.0],
2209            },
2210        };
2211        let successor: State =
2212            state.apply_effect(&effect, &mut function_cache, &state_functions, &registry);
2213        assert_eq!(successor, expected);
2214    }
2215
2216    #[test]
2217    fn is_satisfied() {
2218        let state = State {
2219            signature_variables: SignatureVariables {
2220                integer_variables: vec![1],
2221                ..Default::default()
2222            },
2223            ..Default::default()
2224        };
2225        let mut name_to_integer_variable = FxHashMap::default();
2226        name_to_integer_variable.insert(String::from("i0"), 0);
2227        let metadata = StateMetadata {
2228            integer_variable_names: vec![String::from("i0")],
2229            name_to_integer_variable,
2230            ..Default::default()
2231        };
2232
2233        let base_state = State {
2234            signature_variables: SignatureVariables {
2235                integer_variables: vec![1],
2236                ..Default::default()
2237            },
2238            ..Default::default()
2239        };
2240        assert!(base_state.is_satisfied(&state, &metadata));
2241
2242        let base_state = State {
2243            signature_variables: SignatureVariables {
2244                integer_variables: vec![2],
2245                ..Default::default()
2246            },
2247            ..Default::default()
2248        };
2249        assert!(!base_state.is_satisfied(&state, &metadata));
2250    }
2251
2252    #[test]
2253    fn number_of_objects() {
2254        let metadata = generate_metadata();
2255        assert_eq!(metadata.number_of_object_types(), 2);
2256    }
2257
2258    #[test]
2259    fn number_of_set_variables() {
2260        let metadata = generate_metadata();
2261        assert_eq!(metadata.number_of_set_variables(), 4);
2262    }
2263
2264    #[test]
2265    fn number_of_vector_variables() {
2266        let metadata = generate_metadata();
2267        assert_eq!(metadata.number_of_vector_variables(), 4);
2268    }
2269
2270    #[test]
2271    fn number_of_element_variables() {
2272        let metadata = generate_metadata();
2273        assert_eq!(metadata.number_of_element_variables(), 4);
2274    }
2275
2276    #[test]
2277    fn number_of_integer_variables() {
2278        let metadata = generate_metadata();
2279        assert_eq!(metadata.number_of_integer_variables(), 4);
2280    }
2281
2282    #[test]
2283    fn number_of_continuous_variables() {
2284        let metadata = generate_metadata();
2285        assert_eq!(metadata.number_of_continuous_variables(), 4);
2286    }
2287
2288    #[test]
2289    fn number_of_integer_resource_variables() {
2290        let metadata = generate_metadata();
2291        assert_eq!(metadata.number_of_integer_resource_variables(), 4);
2292    }
2293
2294    #[test]
2295    fn number_of_continuous_resource_variables() {
2296        let metadata = generate_metadata();
2297        assert_eq!(metadata.number_of_continuous_resource_variables(), 4);
2298    }
2299
2300    #[test]
2301    fn has_resource_variable() {
2302        let metadata = StateMetadata {
2303            element_variable_names: vec![String::from("v")],
2304            element_variable_to_object: vec![0],
2305            integer_variable_names: vec![String::from("v")],
2306            continuous_variable_names: vec![String::from("v")],
2307            set_variable_names: vec![String::from("v")],
2308            set_variable_to_object: vec![0],
2309            vector_variable_names: vec![String::from("v")],
2310            vector_variable_to_object: vec![0],
2311            ..Default::default()
2312        };
2313        assert!(!metadata.has_resource_variables());
2314        let metadata = StateMetadata {
2315            element_resource_variable_names: vec![String::from("v")],
2316            element_resource_variable_to_object: vec![0],
2317            element_less_is_better: vec![true],
2318            ..Default::default()
2319        };
2320        assert!(metadata.has_resource_variables());
2321        let metadata = StateMetadata {
2322            integer_resource_variable_names: vec![String::from("v")],
2323            integer_less_is_better: vec![true],
2324            ..Default::default()
2325        };
2326        assert!(metadata.has_resource_variables());
2327        let metadata = StateMetadata {
2328            continuous_resource_variable_names: vec![String::from("v")],
2329            continuous_less_is_better: vec![true],
2330            ..Default::default()
2331        };
2332        assert!(metadata.has_resource_variables());
2333    }
2334
2335    #[test]
2336    fn get_name_set() {
2337        let metadata = generate_metadata();
2338        let mut expected = FxHashSet::default();
2339        expected.insert(String::from("object"));
2340        expected.insert(String::from("small"));
2341        expected.insert(String::from("s0"));
2342        expected.insert(String::from("s1"));
2343        expected.insert(String::from("s2"));
2344        expected.insert(String::from("s3"));
2345        expected.insert(String::from("p0"));
2346        expected.insert(String::from("p1"));
2347        expected.insert(String::from("p2"));
2348        expected.insert(String::from("p3"));
2349        expected.insert(String::from("e0"));
2350        expected.insert(String::from("e1"));
2351        expected.insert(String::from("e2"));
2352        expected.insert(String::from("e3"));
2353        expected.insert(String::from("er0"));
2354        expected.insert(String::from("er1"));
2355        expected.insert(String::from("er2"));
2356        expected.insert(String::from("er3"));
2357        expected.insert(String::from("i0"));
2358        expected.insert(String::from("i1"));
2359        expected.insert(String::from("i2"));
2360        expected.insert(String::from("i3"));
2361        expected.insert(String::from("c0"));
2362        expected.insert(String::from("c1"));
2363        expected.insert(String::from("c2"));
2364        expected.insert(String::from("c3"));
2365        expected.insert(String::from("ir0"));
2366        expected.insert(String::from("ir1"));
2367        expected.insert(String::from("ir2"));
2368        expected.insert(String::from("ir3"));
2369        expected.insert(String::from("cr0"));
2370        expected.insert(String::from("cr1"));
2371        expected.insert(String::from("cr2"));
2372        expected.insert(String::from("cr3"));
2373        assert_eq!(metadata.get_name_set(), expected);
2374    }
2375
2376    #[test]
2377    fn dominance() {
2378        let metadata = generate_metadata();
2379
2380        let a = State {
2381            resource_variables: ResourceVariables {
2382                element_variables: vec![0, 1, 2, 0],
2383                integer_variables: vec![1, 2, 2, 0],
2384                continuous_variables: vec![0.0, 0.0, 0.0, 0.0],
2385            },
2386            ..Default::default()
2387        };
2388        let b = State {
2389            resource_variables: ResourceVariables {
2390                element_variables: vec![0, 1, 2, 0],
2391                integer_variables: vec![1, 2, 2, 0],
2392                continuous_variables: vec![0.0, 0.0, 0.0, 0.0],
2393            },
2394            ..Default::default()
2395        };
2396        assert_eq!(metadata.dominance(&a, &b), Some(Ordering::Equal));
2397
2398        let b = State {
2399            resource_variables: ResourceVariables {
2400                element_variables: vec![0, 0, 3, 0],
2401                integer_variables: vec![1, 2, 2, 0],
2402                continuous_variables: vec![0.0, 0.0, 0.0, 0.0],
2403            },
2404            ..Default::default()
2405        };
2406        assert_eq!(metadata.dominance(&a, &b), Some(Ordering::Greater));
2407        assert_eq!(metadata.dominance(&b, &a), Some(Ordering::Less));
2408
2409        let b = State {
2410            resource_variables: ResourceVariables {
2411                element_variables: vec![0, 1, 2, 0],
2412                integer_variables: vec![1, 1, 3, 0],
2413                continuous_variables: vec![0.0, 0.0, 0.0, 0.0],
2414            },
2415            ..Default::default()
2416        };
2417        assert_eq!(metadata.dominance(&a, &b), Some(Ordering::Greater));
2418        assert_eq!(metadata.dominance(&b, &a), Some(Ordering::Less));
2419
2420        let b = State {
2421            resource_variables: ResourceVariables {
2422                element_variables: vec![0, 1, 2, 0],
2423                integer_variables: vec![1, 3, 3, 0],
2424                continuous_variables: vec![0.0, 0.0, 0.0, 0.0],
2425            },
2426            ..Default::default()
2427        };
2428        assert!(metadata.dominance(&b, &a).is_none());
2429
2430        let a = State {
2431            resource_variables: ResourceVariables {
2432                element_variables: vec![0, 1, 2, 0],
2433                integer_variables: vec![1, 2, 2, 0],
2434                continuous_variables: vec![1.0, 2.0, 2.0, 0.0],
2435            },
2436            ..Default::default()
2437        };
2438        let b = State {
2439            resource_variables: ResourceVariables {
2440                element_variables: vec![0, 1, 2, 0],
2441                integer_variables: vec![1, 2, 2, 0],
2442                continuous_variables: vec![1.0, 1.0, 3.0, 0.0],
2443            },
2444            ..Default::default()
2445        };
2446        assert_eq!(metadata.dominance(&a, &b), Some(Ordering::Greater));
2447        assert_eq!(metadata.dominance(&b, &a), Some(Ordering::Less));
2448
2449        let b = State {
2450            resource_variables: ResourceVariables {
2451                element_variables: vec![0, 1, 2, 0],
2452                integer_variables: vec![1, 2, 2, 0],
2453                continuous_variables: vec![1.0, 3.0, 4.0, 0.0],
2454            },
2455            ..Default::default()
2456        };
2457        assert!(metadata.dominance(&a, &b).is_none());
2458    }
2459
2460    #[test]
2461    #[should_panic]
2462    fn dominance_element_length_panic() {
2463        let metadata = generate_metadata();
2464        let a = State {
2465            resource_variables: ResourceVariables {
2466                element_variables: vec![1, 2, 3],
2467                integer_variables: vec![1, 2, 2, 2],
2468                continuous_variables: vec![],
2469            },
2470            ..Default::default()
2471        };
2472        let b = State {
2473            resource_variables: ResourceVariables {
2474                element_variables: vec![1, 2, 3, 0],
2475                integer_variables: vec![1, 2, 2, 2],
2476                continuous_variables: vec![],
2477            },
2478            ..Default::default()
2479        };
2480        metadata.dominance(&b, &a);
2481    }
2482
2483    #[test]
2484    #[should_panic]
2485    fn dominance_integer_length_panic() {
2486        let metadata = generate_metadata();
2487        let a = State {
2488            resource_variables: ResourceVariables {
2489                element_variables: vec![],
2490                integer_variables: vec![1, 2, 2],
2491                continuous_variables: vec![],
2492            },
2493            ..Default::default()
2494        };
2495        let b = State {
2496            resource_variables: ResourceVariables {
2497                element_variables: vec![],
2498                integer_variables: vec![1, 2, 2, 0],
2499                continuous_variables: vec![],
2500            },
2501            ..Default::default()
2502        };
2503        metadata.dominance(&b, &a);
2504    }
2505
2506    #[test]
2507    #[should_panic]
2508    fn dominance_continuous_length_panic() {
2509        let metadata = generate_metadata();
2510        let a = State {
2511            resource_variables: ResourceVariables {
2512                element_variables: vec![],
2513                integer_variables: vec![1, 2, 2, 0],
2514                continuous_variables: vec![1.0, 2.0, 2.0, 0.0],
2515            },
2516            ..Default::default()
2517        };
2518        let b = State {
2519            resource_variables: ResourceVariables {
2520                element_variables: vec![],
2521                integer_variables: vec![1, 2, 2, 0],
2522                continuous_variables: vec![1.0, 1.0, 3.0],
2523            },
2524            ..Default::default()
2525        };
2526        metadata.dominance(&b, &a);
2527    }
2528
2529    #[test]
2530    fn check_state_ok() {
2531        let metadata = generate_metadata();
2532        let state = State {
2533            signature_variables: SignatureVariables {
2534                element_variables: vec![4, 8, 9, 1],
2535                vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
2536                set_variables: vec![
2537                    Set::with_capacity(10),
2538                    Set::with_capacity(10),
2539                    Set::with_capacity(10),
2540                    Set::with_capacity(2),
2541                ],
2542                integer_variables: vec![-1, 2, 4, 5],
2543                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2544            },
2545            resource_variables: ResourceVariables {
2546                element_variables: vec![4, 8, 9, 1],
2547                integer_variables: vec![-1, 2, 4, 5],
2548                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2549            },
2550        };
2551        assert!(metadata.check_state(&state).is_ok())
2552    }
2553
2554    #[test]
2555    fn chech_state_err() {
2556        let metadata = generate_metadata();
2557        let state = State {
2558            signature_variables: SignatureVariables {
2559                element_variables: vec![4, 8, 9],
2560                vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
2561                set_variables: vec![
2562                    Set::with_capacity(10),
2563                    Set::with_capacity(10),
2564                    Set::with_capacity(10),
2565                    Set::with_capacity(2),
2566                ],
2567                integer_variables: vec![-1, 2, 4, 5],
2568                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2569            },
2570            resource_variables: ResourceVariables {
2571                element_variables: vec![4, 8, 9, 1],
2572                integer_variables: vec![-1, 2, 4, 5],
2573                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2574            },
2575        };
2576        assert!(metadata.check_state(&state).is_err());
2577        let state = State {
2578            signature_variables: SignatureVariables {
2579                element_variables: vec![4, 8, 9, 1],
2580                vector_variables: vec![vec![4], vec![8], vec![9]],
2581                set_variables: vec![
2582                    Set::with_capacity(10),
2583                    Set::with_capacity(10),
2584                    Set::with_capacity(10),
2585                    Set::with_capacity(2),
2586                ],
2587                integer_variables: vec![-1, 2, 4, 5],
2588                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2589            },
2590            resource_variables: ResourceVariables {
2591                element_variables: vec![4, 8, 9, 1],
2592                integer_variables: vec![-1, 2, 4, 5],
2593                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2594            },
2595        };
2596        assert!(metadata.check_state(&state).is_err());
2597        let state = State {
2598            signature_variables: SignatureVariables {
2599                element_variables: vec![4, 8, 9, 1],
2600                vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
2601                set_variables: vec![
2602                    Set::with_capacity(10),
2603                    Set::with_capacity(10),
2604                    Set::with_capacity(10),
2605                ],
2606                integer_variables: vec![-1, 2, 4, 5],
2607                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2608            },
2609            resource_variables: ResourceVariables {
2610                element_variables: vec![4, 8, 9, 1],
2611                integer_variables: vec![-1, 2, 4, 5],
2612                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2613            },
2614        };
2615        assert!(metadata.check_state(&state).is_err());
2616        let state = State {
2617            signature_variables: SignatureVariables {
2618                element_variables: vec![4, 8, 9, 1],
2619                vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
2620                set_variables: vec![
2621                    Set::with_capacity(10),
2622                    Set::with_capacity(10),
2623                    Set::with_capacity(10),
2624                    Set::with_capacity(2),
2625                ],
2626                integer_variables: vec![-1, 2, 4],
2627                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2628            },
2629            resource_variables: ResourceVariables {
2630                element_variables: vec![4, 8, 9, 1],
2631                integer_variables: vec![-1, 2, 4, 5],
2632                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2633            },
2634        };
2635        assert!(metadata.check_state(&state).is_err());
2636        let state = State {
2637            signature_variables: SignatureVariables {
2638                element_variables: vec![4, 8, 9, 1],
2639                vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
2640                set_variables: vec![
2641                    Set::with_capacity(10),
2642                    Set::with_capacity(10),
2643                    Set::with_capacity(10),
2644                    Set::with_capacity(2),
2645                ],
2646                integer_variables: vec![-1, 2, 4, 5],
2647                continuous_variables: vec![-1.0, 2.0, 4.0],
2648            },
2649            resource_variables: ResourceVariables {
2650                element_variables: vec![4, 8, 9, 1],
2651                integer_variables: vec![-1, 2, 4, 5],
2652                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2653            },
2654        };
2655        assert!(metadata.check_state(&state).is_err());
2656        let state = State {
2657            signature_variables: SignatureVariables {
2658                element_variables: vec![4, 8, 9, 1],
2659                vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
2660                set_variables: vec![
2661                    Set::with_capacity(10),
2662                    Set::with_capacity(10),
2663                    Set::with_capacity(10),
2664                    Set::with_capacity(2),
2665                ],
2666                integer_variables: vec![-1, 2, 4, 5],
2667                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2668            },
2669            resource_variables: ResourceVariables {
2670                element_variables: vec![4, 8, 9],
2671                integer_variables: vec![-1, 2, 4, 5],
2672                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2673            },
2674        };
2675        assert!(metadata.check_state(&state).is_err());
2676        let state = State {
2677            signature_variables: SignatureVariables {
2678                element_variables: vec![4, 8, 9, 1],
2679                vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
2680                set_variables: vec![
2681                    Set::with_capacity(10),
2682                    Set::with_capacity(10),
2683                    Set::with_capacity(10),
2684                    Set::with_capacity(2),
2685                ],
2686                integer_variables: vec![-1, 2, 4, 5],
2687                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2688            },
2689            resource_variables: ResourceVariables {
2690                element_variables: vec![4, 8, 9, 1],
2691                integer_variables: vec![-1, 2, 4],
2692                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2693            },
2694        };
2695        assert!(metadata.check_state(&state).is_err());
2696        let state = State {
2697            signature_variables: SignatureVariables {
2698                element_variables: vec![4, 8, 9, 1],
2699                vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
2700                set_variables: vec![
2701                    Set::with_capacity(10),
2702                    Set::with_capacity(10),
2703                    Set::with_capacity(10),
2704                    Set::with_capacity(2),
2705                ],
2706                integer_variables: vec![-1, 2, 4, 5],
2707                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2708            },
2709            resource_variables: ResourceVariables {
2710                element_variables: vec![4, 8, 9, 1],
2711                integer_variables: vec![-1, 2, 4, 5],
2712                continuous_variables: vec![-1.0, 2.0, 4.0],
2713            },
2714        };
2715        assert!(metadata.check_state(&state).is_err());
2716        let state = State {
2717            signature_variables: SignatureVariables {
2718                element_variables: vec![4, 8, 10, 1],
2719                vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
2720                set_variables: vec![
2721                    Set::with_capacity(10),
2722                    Set::with_capacity(10),
2723                    Set::with_capacity(10),
2724                    Set::with_capacity(2),
2725                ],
2726                integer_variables: vec![-1, 2, 4, 5],
2727                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2728            },
2729            resource_variables: ResourceVariables {
2730                element_variables: vec![4, 8, 9, 1],
2731                integer_variables: vec![-1, 2, 4, 5],
2732                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2733            },
2734        };
2735        assert!(metadata.check_state(&state).is_err());
2736        let state = State {
2737            signature_variables: SignatureVariables {
2738                element_variables: vec![4, 8, 9, 1],
2739                vector_variables: vec![vec![4], vec![8], vec![10], vec![1]],
2740                set_variables: vec![
2741                    Set::with_capacity(10),
2742                    Set::with_capacity(10),
2743                    Set::with_capacity(10),
2744                    Set::with_capacity(2),
2745                ],
2746                integer_variables: vec![-1, 2, 4, 5],
2747                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2748            },
2749            resource_variables: ResourceVariables {
2750                element_variables: vec![4, 8, 9, 1],
2751                integer_variables: vec![-1, 2, 4, 5],
2752                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2753            },
2754        };
2755        assert!(metadata.check_state(&state).is_err());
2756        let state = State {
2757            signature_variables: SignatureVariables {
2758                element_variables: vec![4, 8, 9, 1],
2759                vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
2760                set_variables: vec![
2761                    Set::with_capacity(10),
2762                    Set::with_capacity(10),
2763                    Set::with_capacity(11),
2764                    Set::with_capacity(2),
2765                ],
2766                integer_variables: vec![-1, 2, 4, 5],
2767                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2768            },
2769            resource_variables: ResourceVariables {
2770                element_variables: vec![4, 8, 9, 1],
2771                integer_variables: vec![-1, 2, 4, 5],
2772                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2773            },
2774        };
2775        assert!(metadata.check_state(&state).is_err());
2776        let state = State {
2777            signature_variables: SignatureVariables {
2778                element_variables: vec![4, 8, 9, 1],
2779                vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
2780                set_variables: vec![
2781                    Set::with_capacity(10),
2782                    Set::with_capacity(10),
2783                    Set::with_capacity(10),
2784                    Set::with_capacity(2),
2785                ],
2786                integer_variables: vec![-1, 2, 4, 5],
2787                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2788            },
2789            resource_variables: ResourceVariables {
2790                element_variables: vec![4, 8, 10, 1],
2791                integer_variables: vec![-1, 2, 4, 5],
2792                continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
2793            },
2794        };
2795        assert!(metadata.check_state(&state).is_err());
2796    }
2797
2798    #[test]
2799    fn add_object_ok() {
2800        let mut metadata = StateMetadata::default();
2801        let ob = metadata.add_object_type(String::from("something"), 10);
2802        assert!(ob.is_ok());
2803        let ob = ob.unwrap();
2804        assert_eq!(ob, ObjectType(0));
2805        assert_eq!(ob.id(), 0);
2806        assert_eq!(metadata.object_type_names, vec![String::from("something")]);
2807        assert_eq!(metadata.object_numbers, vec![10]);
2808        let mut name_to_object = FxHashMap::default();
2809        name_to_object.insert(String::from("something"), 0);
2810        assert_eq!(metadata.name_to_object_type, name_to_object);
2811        let ob = metadata.add_object_type(String::from("other"), 5);
2812        assert!(ob.is_ok());
2813        let ob = ob.unwrap();
2814        assert_eq!(ob, ObjectType(1));
2815        assert_eq!(ob.id(), 1);
2816        assert_eq!(
2817            metadata.object_type_names,
2818            vec![String::from("something"), String::from("other")]
2819        );
2820        assert_eq!(metadata.object_numbers, vec![10, 5]);
2821        name_to_object.insert(String::from("other"), 1);
2822        assert_eq!(metadata.name_to_object_type, name_to_object);
2823    }
2824
2825    #[test]
2826    fn add_object_err() {
2827        let mut metadata = StateMetadata::default();
2828        let ob = metadata.add_object_type(String::from("something"), 10);
2829        assert!(ob.is_ok());
2830        let ob = metadata.add_object_type(String::from("something"), 10);
2831        assert!(ob.is_err());
2832        assert_eq!(metadata.object_type_names, vec![String::from("something")]);
2833        assert_eq!(metadata.object_numbers, vec![10]);
2834        let mut name_to_object = FxHashMap::default();
2835        name_to_object.insert(String::from("something"), 0);
2836        assert_eq!(metadata.name_to_object_type, name_to_object);
2837    }
2838
2839    #[test]
2840    fn number_of_object_ok() {
2841        let mut metadata = StateMetadata::default();
2842        let ob = metadata.add_object_type(String::from("something"), 10);
2843        assert!(ob.is_ok());
2844        let ob = ob.unwrap();
2845        let result = metadata.get_number_of_objects(ob);
2846        assert!(result.is_ok());
2847        assert_eq!(result.unwrap(), 10);
2848        // let result = metadata.set_number_of_object(ob, 5);
2849        // assert!(result.is_ok());
2850        // assert_eq!(metadata.object_numbers, vec![5]);
2851        // let result = metadata.get_number_of_objects(ob);
2852        // assert!(result.is_ok());
2853        // assert_eq!(result.unwrap(), 5);
2854    }
2855
2856    #[test]
2857    fn number_of_object_err() {
2858        let mut metadata1 = StateMetadata::default();
2859        let ob = metadata1.add_object_type(String::from("something"), 10);
2860        assert!(ob.is_ok());
2861
2862        let mut metadata2 = StateMetadata::default();
2863        let ob = metadata2.add_object_type(String::from("something"), 10);
2864        assert!(ob.is_ok());
2865        let ob = metadata2.add_object_type(String::from("other"), 10);
2866        assert!(ob.is_ok());
2867        // let ob = ob.unwrap();
2868
2869        // let result = metadata1.set_number_of_object(ob, 5);
2870        // assert!(result.is_err());
2871        // let result = metadata1.get_number_of_objects(ob);
2872        // assert!(result.is_err());
2873
2874        assert_eq!(metadata1.object_type_names, vec![String::from("something")]);
2875        assert_eq!(metadata1.object_numbers, vec![10]);
2876        let mut name_to_object = FxHashMap::default();
2877        name_to_object.insert(String::from("something"), 0);
2878        assert_eq!(metadata1.name_to_object_type, name_to_object);
2879    }
2880
2881    #[test]
2882    fn create_set_ok() {
2883        let mut metadata1 = StateMetadata::default();
2884        let ob = metadata1.add_object_type(String::from("something"), 10);
2885        assert!(ob.is_ok());
2886        let ob = ob.unwrap();
2887        let result = metadata1.create_set(ob, &[0, 1, 9]);
2888        assert!(result.is_ok());
2889        let mut set = Set::with_capacity(10);
2890        set.insert(0);
2891        set.insert(1);
2892        set.insert(9);
2893        assert_eq!(result.unwrap(), set);
2894    }
2895
2896    #[test]
2897    fn create_set_err() {
2898        let mut metadata1 = StateMetadata::default();
2899        let ob = metadata1.add_object_type(String::from("something"), 10);
2900        assert!(ob.is_ok());
2901        let ob = ob.unwrap();
2902        let result = metadata1.create_set(ob, &[0, 1, 10]);
2903        assert!(result.is_err());
2904
2905        let mut metadata2 = StateMetadata::default();
2906        let ob = metadata2.add_object_type(String::from("something"), 10);
2907        assert!(ob.is_ok());
2908        let ob = metadata2.add_object_type(String::from("other"), 10);
2909        assert!(ob.is_ok());
2910        let ob = ob.unwrap();
2911
2912        let result = metadata1.create_set(ob, &[0, 1, 9]);
2913        assert!(result.is_err());
2914    }
2915
2916    #[test]
2917    fn add_element_variable_ok() {
2918        let mut metadata = StateMetadata::default();
2919        let ob = metadata.add_object_type(String::from("something"), 10);
2920        assert!(ob.is_ok());
2921        let ob = ob.unwrap();
2922        let v = metadata.add_element_variable(String::from("v"), ob);
2923        assert!(v.is_ok());
2924        let v = v.unwrap();
2925        assert_eq!(v, ElementVariable(0));
2926        assert_eq!(v.id(), 0);
2927        assert_eq!(metadata.element_variable_names, vec![String::from("v")]);
2928        assert_eq!(metadata.element_variable_to_object, vec![0]);
2929        let mut name_to_variable = FxHashMap::default();
2930        name_to_variable.insert(String::from("v"), 0);
2931        assert_eq!(metadata.name_to_element_variable, name_to_variable);
2932        let v = metadata.add_element_variable(String::from("u"), ob);
2933        assert!(v.is_ok());
2934        let v = v.unwrap();
2935        assert_eq!(v, ElementVariable(1));
2936        assert_eq!(v.id(), 1);
2937        assert_eq!(
2938            metadata.element_variable_names,
2939            vec![String::from("v"), String::from("u")]
2940        );
2941        assert_eq!(metadata.element_variable_to_object, vec![0, 0]);
2942        name_to_variable.insert(String::from("u"), 1);
2943        assert_eq!(metadata.name_to_element_variable, name_to_variable);
2944    }
2945
2946    #[test]
2947    fn add_element_variable_err() {
2948        let mut metadata = StateMetadata::default();
2949        let ob = metadata.add_object_type(String::from("something"), 10);
2950        assert!(ob.is_ok());
2951        let ob = ob.unwrap();
2952        let v = metadata.add_element_variable(String::from("v"), ob);
2953        assert!(v.is_ok());
2954        let v = metadata.add_element_variable(String::from("v"), ob);
2955        assert!(v.is_err());
2956        assert_eq!(metadata.element_variable_names, vec![String::from("v")]);
2957        assert_eq!(metadata.element_variable_to_object, vec![0]);
2958        let mut name_to_variable = FxHashMap::default();
2959        name_to_variable.insert(String::from("v"), 0);
2960        assert_eq!(metadata.name_to_element_variable, name_to_variable);
2961
2962        let mut metadata2 = StateMetadata::default();
2963        let ob = metadata2.add_object_type(String::from("something"), 10);
2964        assert!(ob.is_ok());
2965        let ob = metadata2.add_object_type(String::from("other"), 10);
2966        assert!(ob.is_ok());
2967        let ob = ob.unwrap();
2968        let v = metadata.add_element_variable(String::from("u"), ob);
2969        assert!(v.is_err());
2970        assert_eq!(metadata.element_variable_names, vec![String::from("v")]);
2971        assert_eq!(metadata.element_variable_to_object, vec![0]);
2972        let mut name_to_variable = FxHashMap::default();
2973        name_to_variable.insert(String::from("v"), 0);
2974        assert_eq!(metadata.name_to_element_variable, name_to_variable);
2975    }
2976
2977    #[test]
2978    fn get_object_type_of_element_variable_ok() {
2979        let mut metadata = StateMetadata::default();
2980        let ob = metadata.add_object_type(String::from("something"), 10);
2981        assert!(ob.is_ok());
2982        let ob = ob.unwrap();
2983        let v = metadata.add_element_variable(String::from("v"), ob);
2984        assert!(v.is_ok());
2985        let v = v.unwrap();
2986        let ob1 = metadata.get_object_type_of(v);
2987        assert!(ob1.is_ok());
2988        assert_eq!(ob1.unwrap(), ob);
2989    }
2990
2991    #[test]
2992    fn get_object_type_of_element_variable_err() {
2993        let mut metadata = StateMetadata::default();
2994        let ob = metadata.add_object_type(String::from("something"), 10);
2995        assert!(ob.is_ok());
2996        let ob = ob.unwrap();
2997        let v = metadata.add_element_variable(String::from("v"), ob);
2998        assert!(v.is_ok());
2999
3000        let mut metadata2 = StateMetadata::default();
3001        let ob = metadata2.add_object_type(String::from("something"), 10);
3002        assert!(ob.is_ok());
3003        let ob = ob.unwrap();
3004        let v = metadata2.add_element_variable(String::from("v"), ob);
3005        assert!(v.is_ok());
3006        let v = metadata2.add_element_variable(String::from("u"), ob);
3007        assert!(v.is_ok());
3008        let v = v.unwrap();
3009
3010        let ob = metadata.get_object_type_of(v);
3011        assert!(ob.is_err());
3012    }
3013
3014    #[test]
3015    fn add_element_resource_variable_ok() {
3016        let mut metadata = StateMetadata::default();
3017        let ob = metadata.add_object_type(String::from("something"), 10);
3018        assert!(ob.is_ok());
3019        let ob = ob.unwrap();
3020        let v = metadata.add_element_resource_variable(String::from("v"), ob, true);
3021        assert!(v.is_ok());
3022        let v = v.unwrap();
3023        assert_eq!(v, ElementResourceVariable(0));
3024        assert_eq!(v.id(), 0);
3025        assert_eq!(
3026            metadata.element_resource_variable_names,
3027            vec![String::from("v")]
3028        );
3029        assert_eq!(metadata.element_resource_variable_to_object, vec![0]);
3030        assert_eq!(metadata.element_less_is_better, vec![true]);
3031        let mut name_to_variable = FxHashMap::default();
3032        name_to_variable.insert(String::from("v"), 0);
3033        assert_eq!(metadata.name_to_element_resource_variable, name_to_variable);
3034        let v = metadata.add_element_resource_variable(String::from("u"), ob, false);
3035        assert!(v.is_ok());
3036        let v = v.unwrap();
3037        assert_eq!(v, ElementResourceVariable(1));
3038        assert_eq!(v.id(), 1);
3039        assert_eq!(
3040            metadata.element_resource_variable_names,
3041            vec![String::from("v"), String::from("u")]
3042        );
3043        assert_eq!(metadata.element_resource_variable_to_object, vec![0, 0]);
3044        name_to_variable.insert(String::from("u"), 1);
3045        assert_eq!(metadata.name_to_element_resource_variable, name_to_variable);
3046        assert_eq!(metadata.element_less_is_better, vec![true, false]);
3047    }
3048
3049    #[test]
3050    fn add_element_resource_variable_err() {
3051        let mut metadata = StateMetadata::default();
3052        let ob = metadata.add_object_type(String::from("something"), 10);
3053        assert!(ob.is_ok());
3054        let ob = ob.unwrap();
3055        let v = metadata.add_element_resource_variable(String::from("v"), ob, true);
3056        assert!(v.is_ok());
3057        let v = metadata.add_element_resource_variable(String::from("v"), ob, false);
3058        assert!(v.is_err());
3059        assert_eq!(
3060            metadata.element_resource_variable_names,
3061            vec![String::from("v")]
3062        );
3063        assert_eq!(metadata.element_resource_variable_to_object, vec![0]);
3064        assert_eq!(metadata.element_less_is_better, vec![true]);
3065        let mut name_to_variable = FxHashMap::default();
3066        name_to_variable.insert(String::from("v"), 0);
3067        assert_eq!(metadata.name_to_element_resource_variable, name_to_variable);
3068
3069        let mut metadata2 = StateMetadata::default();
3070        let ob = metadata2.add_object_type(String::from("something"), 10);
3071        assert!(ob.is_ok());
3072        let ob = metadata2.add_object_type(String::from("other"), 10);
3073        assert!(ob.is_ok());
3074        let ob = ob.unwrap();
3075        let v = metadata.add_element_resource_variable(String::from("u"), ob, true);
3076        assert!(v.is_err());
3077        assert_eq!(
3078            metadata.element_resource_variable_names,
3079            vec![String::from("v")]
3080        );
3081        assert_eq!(metadata.element_resource_variable_to_object, vec![0]);
3082        assert_eq!(metadata.element_less_is_better, vec![true]);
3083        let mut name_to_variable = FxHashMap::default();
3084        name_to_variable.insert(String::from("v"), 0);
3085        assert_eq!(metadata.name_to_element_resource_variable, name_to_variable);
3086    }
3087
3088    #[test]
3089    fn get_object_type_of_element_resource_variable_ok() {
3090        let mut metadata = StateMetadata::default();
3091        let ob = metadata.add_object_type(String::from("something"), 10);
3092        assert!(ob.is_ok());
3093        let ob = ob.unwrap();
3094        let v = metadata.add_element_resource_variable(String::from("v"), ob, true);
3095        assert!(v.is_ok());
3096        let v = v.unwrap();
3097        let ob1 = metadata.get_object_type_of(v);
3098        assert!(ob1.is_ok());
3099        assert_eq!(ob1.unwrap(), ob);
3100    }
3101
3102    #[test]
3103    fn get_object_type_of_element_resource_variable_err() {
3104        let mut metadata = StateMetadata::default();
3105        let ob = metadata.add_object_type(String::from("something"), 10);
3106        assert!(ob.is_ok());
3107        let ob = ob.unwrap();
3108        let v = metadata.add_element_resource_variable(String::from("v"), ob, true);
3109        assert!(v.is_ok());
3110
3111        let mut metadata2 = StateMetadata::default();
3112        let ob = metadata2.add_object_type(String::from("something"), 10);
3113        assert!(ob.is_ok());
3114        let ob = ob.unwrap();
3115        let v = metadata2.add_element_resource_variable(String::from("v"), ob, false);
3116        assert!(v.is_ok());
3117        let v = metadata2.add_element_resource_variable(String::from("u"), ob, true);
3118        assert!(v.is_ok());
3119        let v = v.unwrap();
3120
3121        let ob = metadata.get_object_type_of(v);
3122        assert!(ob.is_err());
3123    }
3124
3125    #[test]
3126    fn element_resource_variable_preference_ok() {
3127        let mut metadata = StateMetadata::default();
3128        let ob = metadata.add_object_type(String::from("something"), 10);
3129        assert!(ob.is_ok());
3130        let ob = ob.unwrap();
3131        let v = metadata.add_element_resource_variable(String::from("v"), ob, true);
3132        assert!(v.is_ok());
3133        let v = v.unwrap();
3134        let result = metadata.get_preference(v);
3135        assert!(result.is_ok());
3136        assert!(result.unwrap());
3137        let result = metadata.set_preference(v, false);
3138        assert!(result.is_ok());
3139        assert_eq!(metadata.element_less_is_better, vec![false]);
3140        let result = metadata.get_preference(v);
3141        assert!(result.is_ok());
3142        assert!(!result.unwrap());
3143    }
3144
3145    #[test]
3146    fn element_resource_variable_preference_err() {
3147        let mut metadata = StateMetadata::default();
3148        let ob = metadata.add_object_type(String::from("something"), 10);
3149        assert!(ob.is_ok());
3150        let ob = ob.unwrap();
3151        let v = metadata.add_element_resource_variable(String::from("v"), ob, true);
3152        assert!(v.is_ok());
3153
3154        let mut metadata2 = StateMetadata::default();
3155        let ob = metadata2.add_object_type(String::from("something"), 10);
3156        assert!(ob.is_ok());
3157        let ob = ob.unwrap();
3158        let v = metadata2.add_element_resource_variable(String::from("v"), ob, true);
3159        assert!(v.is_ok());
3160        let v = metadata2.add_element_resource_variable(String::from("u"), ob, true);
3161        assert!(v.is_ok());
3162        let v = v.unwrap();
3163        let result = metadata.get_preference(v);
3164        assert!(result.is_err());
3165        let result = metadata.set_preference(v, false);
3166        assert!(result.is_err());
3167        assert_eq!(metadata.element_less_is_better, vec![true]);
3168    }
3169
3170    #[test]
3171    fn add_set_variable_ok() {
3172        let mut metadata = StateMetadata::default();
3173        let ob = metadata.add_object_type(String::from("something"), 10);
3174        assert!(ob.is_ok());
3175        let ob = ob.unwrap();
3176        let v = metadata.add_set_variable(String::from("v"), ob);
3177        assert!(v.is_ok());
3178        let v = v.unwrap();
3179        assert_eq!(v, SetVariable(0));
3180        assert_eq!(v.id(), 0);
3181        assert_eq!(metadata.set_variable_names, vec![String::from("v")]);
3182        assert_eq!(metadata.set_variable_to_object, vec![0]);
3183        let mut name_to_variable = FxHashMap::default();
3184        name_to_variable.insert(String::from("v"), 0);
3185        assert_eq!(metadata.name_to_set_variable, name_to_variable);
3186        let v = metadata.add_set_variable(String::from("u"), ob);
3187        assert!(v.is_ok());
3188        let v = v.unwrap();
3189        assert_eq!(v, SetVariable(1));
3190        assert_eq!(v.id(), 1);
3191        assert_eq!(
3192            metadata.set_variable_names,
3193            vec![String::from("v"), String::from("u")]
3194        );
3195        assert_eq!(metadata.set_variable_to_object, vec![0, 0]);
3196        name_to_variable.insert(String::from("u"), 1);
3197        assert_eq!(metadata.name_to_set_variable, name_to_variable);
3198    }
3199
3200    #[test]
3201    fn add_set_variable_err() {
3202        let mut metadata = StateMetadata::default();
3203        let ob = metadata.add_object_type(String::from("something"), 10);
3204        assert!(ob.is_ok());
3205        let ob = ob.unwrap();
3206        let v = metadata.add_set_variable(String::from("v"), ob);
3207        assert!(v.is_ok());
3208        let v = metadata.add_set_variable(String::from("v"), ob);
3209        assert!(v.is_err());
3210        assert_eq!(metadata.set_variable_names, vec![String::from("v")]);
3211        assert_eq!(metadata.set_variable_to_object, vec![0]);
3212        let mut name_to_variable = FxHashMap::default();
3213        name_to_variable.insert(String::from("v"), 0);
3214        assert_eq!(metadata.name_to_set_variable, name_to_variable);
3215
3216        let mut metadata2 = StateMetadata::default();
3217        let ob = metadata2.add_object_type(String::from("something"), 10);
3218        assert!(ob.is_ok());
3219        let ob = metadata2.add_object_type(String::from("other"), 10);
3220        assert!(ob.is_ok());
3221        let ob = ob.unwrap();
3222        let v = metadata.add_set_variable(String::from("u"), ob);
3223        assert!(v.is_err());
3224        assert_eq!(metadata.set_variable_names, vec![String::from("v")]);
3225        assert_eq!(metadata.set_variable_to_object, vec![0]);
3226        let mut name_to_variable = FxHashMap::default();
3227        name_to_variable.insert(String::from("v"), 0);
3228        assert_eq!(metadata.name_to_set_variable, name_to_variable);
3229    }
3230
3231    #[test]
3232    fn get_object_type_of_set_variable_ok() {
3233        let mut metadata = StateMetadata::default();
3234        let ob = metadata.add_object_type(String::from("something"), 10);
3235        assert!(ob.is_ok());
3236        let ob = ob.unwrap();
3237        let v = metadata.add_set_variable(String::from("v"), ob);
3238        assert!(v.is_ok());
3239        let v = v.unwrap();
3240        let ob1 = metadata.get_object_type_of(v);
3241        assert!(ob1.is_ok());
3242        assert_eq!(ob1.unwrap(), ob);
3243    }
3244
3245    #[test]
3246    fn get_object_type_of_set_variable_err() {
3247        let mut metadata = StateMetadata::default();
3248        let ob = metadata.add_object_type(String::from("something"), 10);
3249        assert!(ob.is_ok());
3250        let ob = ob.unwrap();
3251        let v = metadata.add_set_variable(String::from("v"), ob);
3252        assert!(v.is_ok());
3253
3254        let mut metadata2 = StateMetadata::default();
3255        let ob = metadata2.add_object_type(String::from("something"), 10);
3256        assert!(ob.is_ok());
3257        let ob = ob.unwrap();
3258        let v = metadata2.add_set_variable(String::from("v"), ob);
3259        assert!(v.is_ok());
3260        let v = metadata2.add_set_variable(String::from("u"), ob);
3261        assert!(v.is_ok());
3262        let v = v.unwrap();
3263
3264        let ob = metadata.get_object_type_of(v);
3265        assert!(ob.is_err());
3266    }
3267
3268    #[test]
3269    fn add_vector_variable_ok() {
3270        let mut metadata = StateMetadata::default();
3271        let ob = metadata.add_object_type(String::from("something"), 10);
3272        assert!(ob.is_ok());
3273        let ob = ob.unwrap();
3274        let v = metadata.add_vector_variable(String::from("v"), ob);
3275        assert!(v.is_ok());
3276        let v = v.unwrap();
3277        assert_eq!(v, VectorVariable(0));
3278        assert_eq!(v.id(), 0);
3279        assert_eq!(metadata.vector_variable_names, vec![String::from("v")]);
3280        assert_eq!(metadata.vector_variable_to_object, vec![0]);
3281        let mut name_to_variable = FxHashMap::default();
3282        name_to_variable.insert(String::from("v"), 0);
3283        assert_eq!(metadata.name_to_vector_variable, name_to_variable);
3284        let v = metadata.add_vector_variable(String::from("u"), ob);
3285        assert!(v.is_ok());
3286        let v = v.unwrap();
3287        assert_eq!(v, VectorVariable(1));
3288        assert_eq!(v.id(), 1);
3289        assert_eq!(
3290            metadata.vector_variable_names,
3291            vec![String::from("v"), String::from("u")]
3292        );
3293        assert_eq!(metadata.vector_variable_to_object, vec![0, 0]);
3294        name_to_variable.insert(String::from("u"), 1);
3295        assert_eq!(metadata.name_to_vector_variable, name_to_variable);
3296    }
3297
3298    #[test]
3299    fn add_vector_variable_err() {
3300        let mut metadata = StateMetadata::default();
3301        let ob = metadata.add_object_type(String::from("something"), 10);
3302        assert!(ob.is_ok());
3303        let ob = ob.unwrap();
3304        let v = metadata.add_vector_variable(String::from("v"), ob);
3305        assert!(v.is_ok());
3306        let v = metadata.add_vector_variable(String::from("v"), ob);
3307        assert!(v.is_err());
3308        assert_eq!(metadata.vector_variable_names, vec![String::from("v")]);
3309        assert_eq!(metadata.vector_variable_to_object, vec![0]);
3310        let mut name_to_variable = FxHashMap::default();
3311        name_to_variable.insert(String::from("v"), 0);
3312        assert_eq!(metadata.name_to_vector_variable, name_to_variable);
3313
3314        let mut metadata2 = StateMetadata::default();
3315        let ob = metadata2.add_object_type(String::from("something"), 10);
3316        assert!(ob.is_ok());
3317        let ob = metadata2.add_object_type(String::from("other"), 10);
3318        assert!(ob.is_ok());
3319        let ob = ob.unwrap();
3320        let v = metadata.add_vector_variable(String::from("u"), ob);
3321        assert!(v.is_err());
3322        assert_eq!(metadata.vector_variable_names, vec![String::from("v")]);
3323        assert_eq!(metadata.vector_variable_to_object, vec![0]);
3324        let mut name_to_variable = FxHashMap::default();
3325        name_to_variable.insert(String::from("v"), 0);
3326        assert_eq!(metadata.name_to_vector_variable, name_to_variable);
3327    }
3328
3329    #[test]
3330    fn get_object_type_of_vector_variable_ok() {
3331        let mut metadata = StateMetadata::default();
3332        let ob = metadata.add_object_type(String::from("something"), 10);
3333        assert!(ob.is_ok());
3334        let ob = ob.unwrap();
3335        let v = metadata.add_vector_variable(String::from("v"), ob);
3336        assert!(v.is_ok());
3337        let v = v.unwrap();
3338        let ob1 = metadata.get_object_type_of(v);
3339        assert!(ob1.is_ok());
3340        assert_eq!(ob1.unwrap(), ob);
3341    }
3342
3343    #[test]
3344    fn get_object_type_of_vector_variable_err() {
3345        let mut metadata = StateMetadata::default();
3346        let ob = metadata.add_object_type(String::from("something"), 10);
3347        assert!(ob.is_ok());
3348        let ob = ob.unwrap();
3349        let v = metadata.add_vector_variable(String::from("v"), ob);
3350        assert!(v.is_ok());
3351
3352        let mut metadata2 = StateMetadata::default();
3353        let ob = metadata2.add_object_type(String::from("something"), 10);
3354        assert!(ob.is_ok());
3355        let ob = ob.unwrap();
3356        let v = metadata2.add_vector_variable(String::from("v"), ob);
3357        assert!(v.is_ok());
3358        let v = metadata2.add_vector_variable(String::from("u"), ob);
3359        assert!(v.is_ok());
3360        let v = v.unwrap();
3361
3362        let ob = metadata.get_object_type_of(v);
3363        assert!(ob.is_err());
3364    }
3365
3366    #[test]
3367    fn add_integer_variable_ok() {
3368        let mut metadata = StateMetadata::default();
3369        let v = metadata.add_integer_variable(String::from("v"));
3370        assert!(v.is_ok());
3371        let v = v.unwrap();
3372        assert_eq!(v, IntegerVariable(0));
3373        assert_eq!(v.id(), 0);
3374        assert_eq!(metadata.integer_variable_names, vec![String::from("v")]);
3375        let mut name_to_variable = FxHashMap::default();
3376        name_to_variable.insert(String::from("v"), 0);
3377        assert_eq!(metadata.name_to_integer_variable, name_to_variable);
3378        let v = metadata.add_integer_variable(String::from("u"));
3379        assert!(v.is_ok());
3380        let v = v.unwrap();
3381        assert_eq!(v, IntegerVariable(1));
3382        assert_eq!(v.id(), 1);
3383        assert_eq!(
3384            metadata.integer_variable_names,
3385            vec![String::from("v"), String::from("u")]
3386        );
3387        name_to_variable.insert(String::from("u"), 1);
3388        assert_eq!(metadata.name_to_integer_variable, name_to_variable);
3389    }
3390
3391    #[test]
3392    fn add_integer_variable_err() {
3393        let mut metadata = StateMetadata::default();
3394        let v = metadata.add_integer_variable(String::from("v"));
3395        assert!(v.is_ok());
3396        let v = metadata.add_integer_variable(String::from("v"));
3397        assert!(v.is_err());
3398        assert_eq!(metadata.integer_variable_names, vec![String::from("v")]);
3399        let mut name_to_variable = FxHashMap::default();
3400        name_to_variable.insert(String::from("v"), 0);
3401        assert_eq!(metadata.name_to_integer_variable, name_to_variable);
3402    }
3403
3404    #[test]
3405    fn add_integer_resource_variable_ok() {
3406        let mut metadata = StateMetadata::default();
3407        let v = metadata.add_integer_resource_variable(String::from("v"), true);
3408        assert!(v.is_ok());
3409        let v = v.unwrap();
3410        assert_eq!(v, IntegerResourceVariable(0));
3411        assert_eq!(v.id(), 0);
3412        assert_eq!(
3413            metadata.integer_resource_variable_names,
3414            vec![String::from("v")]
3415        );
3416        let mut name_to_variable = FxHashMap::default();
3417        name_to_variable.insert(String::from("v"), 0);
3418        assert_eq!(metadata.name_to_integer_resource_variable, name_to_variable);
3419        assert_eq!(metadata.integer_less_is_better, vec![true]);
3420        let v = metadata.add_integer_resource_variable(String::from("u"), false);
3421        assert!(v.is_ok());
3422        let v = v.unwrap();
3423        assert_eq!(v, IntegerResourceVariable(1));
3424        assert_eq!(v.id(), 1);
3425        assert_eq!(
3426            metadata.integer_resource_variable_names,
3427            vec![String::from("v"), String::from("u")]
3428        );
3429        name_to_variable.insert(String::from("u"), 1);
3430        assert_eq!(metadata.name_to_integer_resource_variable, name_to_variable);
3431        assert_eq!(metadata.integer_less_is_better, vec![true, false]);
3432    }
3433
3434    #[test]
3435    fn add_integer_resource_variable_err() {
3436        let mut metadata = StateMetadata::default();
3437        let v = metadata.add_integer_resource_variable(String::from("v"), true);
3438        assert!(v.is_ok());
3439        let v = metadata.add_integer_resource_variable(String::from("v"), false);
3440        assert!(v.is_err());
3441        assert_eq!(
3442            metadata.integer_resource_variable_names,
3443            vec![String::from("v")]
3444        );
3445        let mut name_to_variable = FxHashMap::default();
3446        name_to_variable.insert(String::from("v"), 0);
3447        assert_eq!(metadata.name_to_integer_resource_variable, name_to_variable);
3448        assert_eq!(metadata.integer_less_is_better, vec![true]);
3449    }
3450
3451    #[test]
3452    fn integer_resource_variable_preference_ok() {
3453        let mut metadata = StateMetadata::default();
3454        let v = metadata.add_integer_resource_variable(String::from("v"), true);
3455        assert!(v.is_ok());
3456        let v = v.unwrap();
3457        let result = metadata.get_preference(v);
3458        assert!(result.is_ok());
3459        assert!(result.unwrap());
3460        let result = metadata.set_preference(v, false);
3461        assert!(result.is_ok());
3462        assert_eq!(metadata.integer_less_is_better, vec![false]);
3463        let result = metadata.get_preference(v);
3464        assert!(result.is_ok());
3465        assert!(!result.unwrap());
3466    }
3467
3468    #[test]
3469    fn integer_resource_variable_preference_err() {
3470        let mut metadata = StateMetadata::default();
3471        let v = metadata.add_integer_resource_variable(String::from("v"), true);
3472        assert!(v.is_ok());
3473
3474        let mut metadata2 = StateMetadata::default();
3475        let v = metadata2.add_integer_resource_variable(String::from("v"), true);
3476        assert!(v.is_ok());
3477        let v = metadata2.add_integer_resource_variable(String::from("u"), true);
3478        assert!(v.is_ok());
3479        let v = v.unwrap();
3480        let result = metadata.get_preference(v);
3481        assert!(result.is_err());
3482        let result = metadata.set_preference(v, false);
3483        assert!(result.is_err());
3484        assert_eq!(metadata.integer_less_is_better, vec![true]);
3485    }
3486
3487    #[test]
3488    fn add_continuous_variable_ok() {
3489        let mut metadata = StateMetadata::default();
3490        let v = metadata.add_continuous_variable(String::from("v"));
3491        assert!(v.is_ok());
3492        let v = v.unwrap();
3493        assert_eq!(v, ContinuousVariable(0));
3494        assert_eq!(v.id(), 0);
3495        assert_eq!(metadata.continuous_variable_names, vec![String::from("v")]);
3496        let mut name_to_variable = FxHashMap::default();
3497        name_to_variable.insert(String::from("v"), 0);
3498        assert_eq!(metadata.name_to_continuous_variable, name_to_variable);
3499        let v = metadata.add_continuous_variable(String::from("u"));
3500        assert!(v.is_ok());
3501        let v = v.unwrap();
3502        assert_eq!(v, ContinuousVariable(1));
3503        assert_eq!(v.id(), 1);
3504        assert_eq!(
3505            metadata.continuous_variable_names,
3506            vec![String::from("v"), String::from("u")]
3507        );
3508        name_to_variable.insert(String::from("u"), 1);
3509        assert_eq!(metadata.name_to_continuous_variable, name_to_variable);
3510    }
3511
3512    #[test]
3513    fn add_continuous_variable_err() {
3514        let mut metadata = StateMetadata::default();
3515        let v = metadata.add_continuous_variable(String::from("v"));
3516        assert!(v.is_ok());
3517        let v = metadata.add_continuous_variable(String::from("v"));
3518        assert!(v.is_err());
3519        assert_eq!(metadata.continuous_variable_names, vec![String::from("v")]);
3520        let mut name_to_variable = FxHashMap::default();
3521        name_to_variable.insert(String::from("v"), 0);
3522        assert_eq!(metadata.name_to_continuous_variable, name_to_variable);
3523    }
3524
3525    #[test]
3526    fn add_continuous_resource_variable_ok() {
3527        let mut metadata = StateMetadata::default();
3528        let v = metadata.add_continuous_resource_variable(String::from("v"), true);
3529        assert!(v.is_ok());
3530        let v = v.unwrap();
3531        assert_eq!(v, ContinuousResourceVariable(0));
3532        assert_eq!(v.id(), 0);
3533        assert_eq!(
3534            metadata.continuous_resource_variable_names,
3535            vec![String::from("v")]
3536        );
3537        let mut name_to_variable = FxHashMap::default();
3538        name_to_variable.insert(String::from("v"), 0);
3539        assert_eq!(
3540            metadata.name_to_continuous_resource_variable,
3541            name_to_variable
3542        );
3543        assert_eq!(metadata.continuous_less_is_better, vec![true]);
3544        let v = metadata.add_continuous_resource_variable(String::from("u"), false);
3545        assert!(v.is_ok());
3546        let v = v.unwrap();
3547        assert_eq!(v, ContinuousResourceVariable(1));
3548        assert_eq!(v.id(), 1);
3549        assert_eq!(
3550            metadata.continuous_resource_variable_names,
3551            vec![String::from("v"), String::from("u")]
3552        );
3553        name_to_variable.insert(String::from("u"), 1);
3554        assert_eq!(
3555            metadata.name_to_continuous_resource_variable,
3556            name_to_variable
3557        );
3558        assert_eq!(metadata.continuous_less_is_better, vec![true, false]);
3559    }
3560
3561    #[test]
3562    fn add_continuous_resource_variable_err() {
3563        let mut metadata = StateMetadata::default();
3564        let v = metadata.add_continuous_resource_variable(String::from("v"), true);
3565        assert!(v.is_ok());
3566        let v = metadata.add_continuous_resource_variable(String::from("v"), false);
3567        assert!(v.is_err());
3568        assert_eq!(
3569            metadata.continuous_resource_variable_names,
3570            vec![String::from("v")]
3571        );
3572        let mut name_to_variable = FxHashMap::default();
3573        name_to_variable.insert(String::from("v"), 0);
3574        assert_eq!(
3575            metadata.name_to_continuous_resource_variable,
3576            name_to_variable
3577        );
3578        assert_eq!(metadata.continuous_less_is_better, vec![true]);
3579    }
3580
3581    #[test]
3582    fn continuous_resource_variable_preference_ok() {
3583        let mut metadata = StateMetadata::default();
3584        let v = metadata.add_continuous_resource_variable(String::from("v"), true);
3585        assert!(v.is_ok());
3586        let v = v.unwrap();
3587        let result = metadata.get_preference(v);
3588        assert!(result.is_ok());
3589        assert!(result.unwrap());
3590        let result = metadata.set_preference(v, false);
3591        assert!(result.is_ok());
3592        assert_eq!(metadata.continuous_less_is_better, vec![false]);
3593        let result = metadata.get_preference(v);
3594        assert!(result.is_ok());
3595        assert!(!result.unwrap());
3596    }
3597
3598    #[test]
3599    fn continuous_resource_variable_preference_err() {
3600        let mut metadata = StateMetadata::default();
3601        let v = metadata.add_continuous_resource_variable(String::from("v"), true);
3602        assert!(v.is_ok());
3603
3604        let mut metadata2 = StateMetadata::default();
3605        let v = metadata2.add_continuous_resource_variable(String::from("v"), true);
3606        assert!(v.is_ok());
3607        let v = metadata2.add_continuous_resource_variable(String::from("u"), true);
3608        assert!(v.is_ok());
3609        let v = v.unwrap();
3610        let result = metadata.get_preference(v);
3611        assert!(result.is_err());
3612        let result = metadata.set_preference(v, false);
3613        assert!(result.is_err());
3614        assert_eq!(metadata.continuous_less_is_better, vec![true]);
3615    }
3616}