use crate::effect;
use crate::state_functions::{StateFunctionCache, StateFunctions};
use crate::table_registry;
use crate::util::{self, ModelErr};
use crate::variable_type::{Continuous, Element, Integer, Set, Vector};
use rustc_hash::{FxHashMap, FxHashSet};
use std::cmp::Ordering;
use std::collections::hash_map::Entry;
use std::panic;
pub trait StateInterface: Sized {
fn get_number_of_set_variables(&self) -> usize;
fn get_set_variable(&self, i: usize) -> &Set;
fn get_number_of_vector_variables(&self) -> usize;
fn get_vector_variable(&self, i: usize) -> &Vector;
fn get_number_of_element_variables(&self) -> usize;
fn get_element_variable(&self, i: usize) -> Element;
fn get_number_of_integer_variables(&self) -> usize;
fn get_integer_variable(&self, i: usize) -> Integer;
fn get_number_of_continuous_variables(&self) -> usize;
fn get_continuous_variable(&self, i: usize) -> Continuous;
fn get_number_of_element_resource_variables(&self) -> usize;
fn get_element_resource_variable(&self, i: usize) -> Element;
fn get_number_of_integer_resource_variables(&self) -> usize;
fn get_integer_resource_variable(&self, i: usize) -> Integer;
fn get_number_of_continuous_resource_variables(&self) -> usize;
fn get_continuous_resource_variable(&self, i: usize) -> Continuous;
fn apply_effect<T: From<State>>(
&self,
effect: &effect::Effect,
function_cache: &mut StateFunctionCache,
state_functions: &StateFunctions,
registry: &table_registry::TableRegistry,
) -> T {
let len = self.get_number_of_set_variables();
let mut set_variables = Vec::with_capacity(len);
let mut i = 0;
for e in &effect.set_effects {
while i < e.0 {
set_variables.push(self.get_set_variable(i).clone());
i += 1;
}
set_variables.push(e.1.eval(self, function_cache, state_functions, registry));
i += 1;
}
while i < len {
set_variables.push(self.get_set_variable(i).clone());
i += 1;
}
let len = self.get_number_of_vector_variables();
let mut vector_variables = Vec::with_capacity(len);
let mut i = 0;
for e in &effect.vector_effects {
while i < e.0 {
vector_variables.push(self.get_vector_variable(i).clone());
i += 1;
}
vector_variables.push(e.1.eval(self, function_cache, state_functions, registry));
i += 1;
}
while i < len {
vector_variables.push(self.get_vector_variable(i).clone());
i += 1;
}
let mut element_variables: Vec<usize> = (0..self.get_number_of_element_variables())
.map(|i| self.get_element_variable(i))
.collect();
for e in &effect.element_effects {
element_variables[e.0] = e.1.eval(self, function_cache, state_functions, registry);
}
let mut integer_variables: Vec<Integer> = (0..self.get_number_of_integer_variables())
.map(|i| self.get_integer_variable(i))
.collect();
for e in &effect.integer_effects {
integer_variables[e.0] = e.1.eval(self, function_cache, state_functions, registry);
}
let mut continuous_variables: Vec<Continuous> = (0..self
.get_number_of_continuous_variables())
.map(|i| self.get_continuous_variable(i))
.collect();
for e in &effect.continuous_effects {
continuous_variables[e.0] = e.1.eval(self, function_cache, state_functions, registry);
}
let mut element_resource_variables: Vec<usize> = (0..self
.get_number_of_element_resource_variables())
.map(|i| self.get_element_resource_variable(i))
.collect();
for e in &effect.element_resource_effects {
element_resource_variables[e.0] =
e.1.eval(self, function_cache, state_functions, registry);
}
let mut integer_resource_variables: Vec<Integer> = (0..self
.get_number_of_integer_resource_variables())
.map(|i| self.get_integer_resource_variable(i))
.collect();
for e in &effect.integer_resource_effects {
integer_resource_variables[e.0] =
e.1.eval(self, function_cache, state_functions, registry);
}
let mut continuous_resource_variables: Vec<Continuous> = (0..self
.get_number_of_continuous_resource_variables())
.map(|i| self.get_continuous_resource_variable(i))
.collect();
for e in &effect.continuous_resource_effects {
continuous_resource_variables[e.0] =
e.1.eval(self, function_cache, state_functions, registry);
}
T::from(State {
signature_variables: SignatureVariables {
set_variables,
vector_variables,
element_variables,
integer_variables,
continuous_variables,
},
resource_variables: ResourceVariables {
element_variables: element_resource_variables,
integer_variables: integer_resource_variables,
continuous_variables: continuous_resource_variables,
},
})
}
}
#[derive(Debug, PartialEq, Clone, Default)]
pub struct SignatureVariables {
pub set_variables: Vec<Set>,
pub vector_variables: Vec<Vector>,
pub element_variables: Vec<Element>,
pub integer_variables: Vec<Integer>,
pub continuous_variables: Vec<Continuous>,
}
#[derive(Debug, PartialEq, Clone, Default)]
pub struct ResourceVariables {
pub element_variables: Vec<Element>,
pub integer_variables: Vec<Integer>,
pub continuous_variables: Vec<Continuous>,
}
#[derive(Debug, PartialEq, Clone, Default)]
pub struct State {
pub signature_variables: SignatureVariables,
pub resource_variables: ResourceVariables,
}
impl StateInterface for State {
#[inline]
fn get_number_of_set_variables(&self) -> usize {
self.signature_variables.set_variables.len()
}
#[inline]
fn get_set_variable(&self, i: usize) -> &Set {
&self.signature_variables.set_variables[i]
}
#[inline]
fn get_number_of_vector_variables(&self) -> usize {
self.signature_variables.vector_variables.len()
}
#[inline]
fn get_vector_variable(&self, i: usize) -> &Vector {
&self.signature_variables.vector_variables[i]
}
#[inline]
fn get_number_of_element_variables(&self) -> usize {
self.signature_variables.element_variables.len()
}
#[inline]
fn get_element_variable(&self, i: usize) -> Element {
self.signature_variables.element_variables[i]
}
#[inline]
fn get_number_of_integer_variables(&self) -> usize {
self.signature_variables.integer_variables.len()
}
#[inline]
fn get_integer_variable(&self, i: usize) -> Integer {
self.signature_variables.integer_variables[i]
}
#[inline]
fn get_number_of_continuous_variables(&self) -> usize {
self.signature_variables.continuous_variables.len()
}
#[inline]
fn get_continuous_variable(&self, i: usize) -> Continuous {
self.signature_variables.continuous_variables[i]
}
#[inline]
fn get_number_of_element_resource_variables(&self) -> usize {
self.resource_variables.element_variables.len()
}
#[inline]
fn get_element_resource_variable(&self, i: usize) -> Element {
self.resource_variables.element_variables[i]
}
#[inline]
fn get_number_of_integer_resource_variables(&self) -> usize {
self.resource_variables.integer_variables.len()
}
#[inline]
fn get_integer_resource_variable(&self, i: usize) -> Integer {
self.resource_variables.integer_variables[i]
}
#[inline]
fn get_number_of_continuous_resource_variables(&self) -> usize {
self.resource_variables.continuous_variables.len()
}
#[inline]
fn get_continuous_resource_variable(&self, i: usize) -> Continuous {
self.resource_variables.continuous_variables[i]
}
}
impl State {
pub fn is_satisfied<U: StateInterface>(&self, state: &U, metadata: &StateMetadata) -> bool {
for i in 0..metadata.number_of_element_variables() {
if self.get_element_variable(i) != state.get_element_variable(i) {
return false;
}
}
for i in 0..metadata.number_of_element_resource_variables() {
if self.get_element_resource_variable(i) != state.get_element_resource_variable(i) {
return false;
}
}
for i in 0..metadata.number_of_integer_variables() {
if self.get_integer_variable(i) != state.get_integer_variable(i) {
return false;
}
}
for i in 0..metadata.number_of_integer_resource_variables() {
if self.get_integer_resource_variable(i) != state.get_integer_resource_variable(i) {
return false;
}
}
for i in 0..metadata.number_of_continuous_variables() {
if (self.get_continuous_variable(i) - state.get_continuous_variable(i)).abs()
> Continuous::EPSILON
{
return false;
}
}
for i in 0..metadata.number_of_continuous_resource_variables() {
if (self.get_continuous_resource_variable(i)
- state.get_continuous_resource_variable(i))
.abs()
> Continuous::EPSILON
{
return false;
}
}
for i in 0..metadata.number_of_set_variables() {
if self.get_set_variable(i) != state.get_set_variable(i) {
return false;
}
}
for i in 0..metadata.number_of_vector_variables() {
if self.get_vector_variable(i) != state.get_vector_variable(i) {
return false;
}
}
true
}
}
macro_rules! define_handle {
($x:ident) => {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct $x(usize);
impl $x {
#[inline]
pub fn id(&self) -> usize {
self.0
}
}
};
}
define_handle!(ObjectType);
define_handle!(ElementVariable);
define_handle!(ElementResourceVariable);
define_handle!(SetVariable);
define_handle!(VectorVariable);
define_handle!(IntegerVariable);
define_handle!(IntegerResourceVariable);
define_handle!(ContinuousVariable);
define_handle!(ContinuousResourceVariable);
#[derive(Debug, PartialEq, Clone, Default)]
pub struct StateMetadata {
pub object_type_names: Vec<String>,
pub name_to_object_type: FxHashMap<String, usize>,
pub object_numbers: Vec<usize>,
pub set_variable_names: Vec<String>,
pub name_to_set_variable: FxHashMap<String, usize>,
pub set_variable_to_object: Vec<usize>,
pub vector_variable_names: Vec<String>,
pub name_to_vector_variable: FxHashMap<String, usize>,
pub vector_variable_to_object: Vec<usize>,
pub element_variable_names: Vec<String>,
pub name_to_element_variable: FxHashMap<String, usize>,
pub element_variable_to_object: Vec<usize>,
pub integer_variable_names: Vec<String>,
pub name_to_integer_variable: FxHashMap<String, usize>,
pub continuous_variable_names: Vec<String>,
pub name_to_continuous_variable: FxHashMap<String, usize>,
pub element_resource_variable_names: Vec<String>,
pub name_to_element_resource_variable: FxHashMap<String, usize>,
pub element_resource_variable_to_object: Vec<usize>,
pub element_less_is_better: Vec<bool>,
pub integer_resource_variable_names: Vec<String>,
pub name_to_integer_resource_variable: FxHashMap<String, usize>,
pub integer_less_is_better: Vec<bool>,
pub continuous_resource_variable_names: Vec<String>,
pub name_to_continuous_resource_variable: FxHashMap<String, usize>,
pub continuous_less_is_better: Vec<bool>,
}
impl StateMetadata {
#[inline]
pub fn number_of_object_types(&self) -> usize {
self.object_type_names.len()
}
#[inline]
pub fn number_of_set_variables(&self) -> usize {
self.set_variable_names.len()
}
#[inline]
pub fn number_of_vector_variables(&self) -> usize {
self.vector_variable_names.len()
}
#[inline]
pub fn number_of_element_variables(&self) -> usize {
self.element_variable_names.len()
}
#[inline]
pub fn number_of_integer_variables(&self) -> usize {
self.integer_variable_names.len()
}
#[inline]
pub fn number_of_continuous_variables(&self) -> usize {
self.continuous_variable_names.len()
}
#[inline]
pub fn number_of_element_resource_variables(&self) -> usize {
self.element_resource_variable_names.len()
}
#[inline]
pub fn number_of_integer_resource_variables(&self) -> usize {
self.integer_resource_variable_names.len()
}
#[inline]
pub fn number_of_continuous_resource_variables(&self) -> usize {
self.continuous_resource_variable_names.len()
}
pub fn has_resource_variables(&self) -> bool {
self.number_of_element_resource_variables() > 0
|| self.number_of_integer_resource_variables() > 0
|| self.number_of_continuous_resource_variables() > 0
}
pub fn get_name_set(&self) -> FxHashSet<String> {
let mut name_set = FxHashSet::default();
for name in &self.object_type_names {
name_set.insert(name.clone());
}
for name in &self.set_variable_names {
name_set.insert(name.clone());
}
for name in &self.vector_variable_names {
name_set.insert(name.clone());
}
for name in &self.element_variable_names {
name_set.insert(name.clone());
}
for name in &self.integer_variable_names {
name_set.insert(name.clone());
}
for name in &self.continuous_variable_names {
name_set.insert(name.clone());
}
for name in &self.element_resource_variable_names {
name_set.insert(name.clone());
}
for name in &self.integer_resource_variable_names {
name_set.insert(name.clone());
}
for name in &self.continuous_resource_variable_names {
name_set.insert(name.clone());
}
name_set
}
pub fn dominance<U: StateInterface, V: StateInterface>(
&self,
a: &U,
b: &V,
) -> Option<Ordering> {
let status = Some(Ordering::Equal);
let x = |i| a.get_element_resource_variable(i);
let y = |i| b.get_element_resource_variable(i);
let status = Self::compare_resource_variables(&x, &y, &self.element_less_is_better, status);
status?;
let x = |i| a.get_integer_resource_variable(i);
let y = |i| b.get_integer_resource_variable(i);
let status = Self::compare_resource_variables(&x, &y, &self.integer_less_is_better, status);
status?;
let x = |i| a.get_continuous_resource_variable(i);
let y = |i| b.get_continuous_resource_variable(i);
Self::compare_resource_variables(&x, &y, &self.continuous_less_is_better, status)
}
fn compare_resource_variables<T: PartialOrd, F, G>(
x: &F,
y: &G,
less_is_better: &[bool],
mut status: Option<Ordering>,
) -> Option<Ordering>
where
F: Fn(usize) -> T,
G: Fn(usize) -> T,
{
for (i, less_is_better) in less_is_better.iter().enumerate() {
let v1 = x(i);
let v2 = y(i);
match status {
Some(Ordering::Equal) => {
if v1 < v2 {
if *less_is_better {
status = Some(Ordering::Greater);
} else {
status = Some(Ordering::Less);
}
}
if v1 > v2 {
if *less_is_better {
status = Some(Ordering::Less);
} else {
status = Some(Ordering::Greater);
}
}
}
Some(Ordering::Less) => {
if v1 < v2 {
if *less_is_better {
return None;
}
} else if v1 > v2 && !less_is_better {
return None;
}
}
Some(Ordering::Greater) => {
if v1 > v2 {
if *less_is_better {
return None;
}
} else if v1 < v2 && !less_is_better {
return None;
}
}
None => {}
}
}
status
}
pub fn check_state<'a, T: StateInterface>(&self, state: &'a T) -> Result<(), ModelErr>
where
&'a T: panic::UnwindSafe,
{
let n = self.number_of_element_variables();
for i in 0..n {
let v = panic::catch_unwind(|| state.get_element_variable(i));
if v.is_err() {
return Err(ModelErr::new(format!(
"{i} th element variable does not exists",
)));
}
let v = v.unwrap();
let m = self.object_numbers[self.element_variable_to_object[i]];
if v >= m {
return Err(ModelErr::new(format!(
"value {i} for an element variable >= #objects ({m})",
)));
}
}
let n = self.number_of_element_resource_variables();
for i in 0..n {
let v = panic::catch_unwind(|| state.get_element_resource_variable(i));
if v.is_err() {
return Err(ModelErr::new(format!(
"{i} th element resource variable does not exist",
)));
}
let v = v.unwrap();
let m = self.object_numbers[self.element_resource_variable_to_object[i]];
if v >= m {
return Err(ModelErr::new(format!(
"value {i} for an element resource variable >= #objects ({m})",
)));
}
}
let n = self.number_of_set_variables();
for i in 0..n {
let v = panic::catch_unwind(|| state.get_set_variable(i));
if v.is_err() {
return Err(ModelErr::new(format!(
"{i} th set variable does not exists",
)));
}
let v = v.unwrap();
let m = self.object_numbers[self.set_variable_to_object[i]];
if v.len() > m {
return Err(ModelErr::new(format!(
"set size {} for {i} th set variable > #objects ({m})",
v.len(),
)));
}
}
let n = self.number_of_vector_variables();
for i in 0..n {
let v = panic::catch_unwind(|| state.get_vector_variable(i));
if v.is_err() {
return Err(ModelErr::new(format!(
"{i} th vector variable does not exists",
)));
}
let v = v.unwrap();
let m = self.object_numbers[self.vector_variable_to_object[i]];
if v.iter().any(|v| *v >= m) {
return Err(ModelErr::new(format!(
"vector for {i} th vector variable contains a value >= #objects ({m})",
)));
}
}
let n = self.number_of_integer_variables();
for i in 0..n {
let v = panic::catch_unwind(|| state.get_integer_variable(i));
if v.is_err() {
return Err(ModelErr::new(format!(
"{i} th integer variable does not exist",
)));
}
}
let n = self.number_of_integer_resource_variables();
for i in 0..n {
let v = panic::catch_unwind(|| state.get_integer_resource_variable(i));
if v.is_err() {
return Err(ModelErr::new(format!(
"{i} th integer resource variable does not exist",
)));
}
}
let n = self.number_of_continuous_variables();
for i in 0..n {
let v = panic::catch_unwind(|| state.get_continuous_variable(i));
if v.is_err() {
return Err(ModelErr::new(format!(
"{i} th continuous variable does not exist",
)));
}
}
let n = self.number_of_continuous_resource_variables();
for i in 0..n {
let v = panic::catch_unwind(|| state.get_continuous_resource_variable(i));
if v.is_err() {
return Err(ModelErr::new(format!(
"{i} th continuous resource variable does not exist",
)));
}
}
Ok(())
}
pub fn get_object_type(&self, name: &str) -> Result<ObjectType, ModelErr> {
if let Some(id) = self.name_to_object_type.get(name) {
Ok(ObjectType(*id))
} else {
Err(ModelErr::new(format!("no such object `{name}`")))
}
}
pub fn add_object_type<T>(&mut self, name: T, number: usize) -> Result<ObjectType, ModelErr>
where
String: From<T>,
{
let name = String::from(name);
match self.name_to_object_type.entry(name) {
Entry::Vacant(e) => {
let id = self.object_type_names.len();
self.object_type_names.push(e.key().clone());
self.object_numbers.push(number);
e.insert(id);
Ok(ObjectType(id))
}
Entry::Occupied(e) => Err(ModelErr::new(format!(
"object `{key}` already exists",
key = e.key()
))),
}
}
pub fn get_number_of_objects(&self, ob: ObjectType) -> Result<usize, ModelErr> {
self.check_object(ob)?;
Ok(self.object_numbers[ob.id()])
}
pub fn create_set(&self, ob: ObjectType, array: &[Element]) -> Result<Set, ModelErr> {
let n = self.get_number_of_objects(ob)?;
let mut set = Set::with_capacity(n);
for v in array {
if *v >= n {
return Err(ModelErr::new(format!(
"index {v} for object >= #objects ({n})",
)));
}
set.insert(*v);
}
Ok(set)
}
#[inline]
pub fn get_element_variable(&self, name: &str) -> Result<ElementVariable, ModelErr> {
let id = util::get_id(name, &self.name_to_element_variable)?;
Ok(ElementVariable(id))
}
pub fn add_element_variable<T>(
&mut self,
name: T,
ob: ObjectType,
) -> Result<ElementVariable, ModelErr>
where
String: From<T>,
{
self.check_object(ob)?;
let id = util::add_name(
name,
&mut self.element_variable_names,
&mut self.name_to_element_variable,
)?;
self.element_variable_to_object.push(ob.id());
Ok(ElementVariable(id))
}
#[inline]
pub fn get_element_resource_variable(
&self,
name: &str,
) -> Result<ElementResourceVariable, ModelErr> {
let id = util::get_id(name, &self.name_to_element_resource_variable)?;
Ok(ElementResourceVariable(id))
}
pub fn add_element_resource_variable<T>(
&mut self,
name: T,
ob: ObjectType,
less_is_better: bool,
) -> Result<ElementResourceVariable, ModelErr>
where
String: From<T>,
{
self.check_object(ob)?;
let id = util::add_name(
name,
&mut self.element_resource_variable_names,
&mut self.name_to_element_resource_variable,
)?;
self.element_resource_variable_to_object.push(ob.id());
self.element_less_is_better.push(less_is_better);
Ok(ElementResourceVariable(id))
}
#[inline]
pub fn get_set_variable(&self, name: &str) -> Result<SetVariable, ModelErr> {
let id = util::get_id(name, &self.name_to_set_variable)?;
Ok(SetVariable(id))
}
pub fn add_set_variable<T>(&mut self, name: T, ob: ObjectType) -> Result<SetVariable, ModelErr>
where
String: From<T>,
{
self.check_object(ob)?;
let id = util::add_name(
name,
&mut self.set_variable_names,
&mut self.name_to_set_variable,
)?;
self.set_variable_to_object.push(ob.id());
Ok(SetVariable(id))
}
#[inline]
pub fn get_vector_variable(&self, name: &str) -> Result<VectorVariable, ModelErr> {
let id = util::get_id(name, &self.name_to_vector_variable)?;
Ok(VectorVariable(id))
}
pub fn add_vector_variable<T>(
&mut self,
name: T,
ob: ObjectType,
) -> Result<VectorVariable, ModelErr>
where
String: From<T>,
{
self.check_object(ob)?;
let id = util::add_name(
name,
&mut self.vector_variable_names,
&mut self.name_to_vector_variable,
)?;
self.vector_variable_to_object.push(ob.id());
Ok(VectorVariable(id))
}
#[inline]
pub fn get_integer_variable(&self, name: &str) -> Result<IntegerVariable, ModelErr> {
let id = util::get_id(name, &self.name_to_integer_variable)?;
Ok(IntegerVariable(id))
}
pub fn add_integer_variable<T>(&mut self, name: T) -> Result<IntegerVariable, ModelErr>
where
String: From<T>,
{
let id = util::add_name(
name,
&mut self.integer_variable_names,
&mut self.name_to_integer_variable,
)?;
Ok(IntegerVariable(id))
}
#[inline]
pub fn get_integer_resource_variable(
&self,
name: &str,
) -> Result<IntegerResourceVariable, ModelErr> {
let id = util::get_id(name, &self.name_to_integer_resource_variable)?;
Ok(IntegerResourceVariable(id))
}
pub fn add_integer_resource_variable<T>(
&mut self,
name: T,
less_is_better: bool,
) -> Result<IntegerResourceVariable, ModelErr>
where
String: From<T>,
{
let id = util::add_name(
name,
&mut self.integer_resource_variable_names,
&mut self.name_to_integer_resource_variable,
)?;
self.integer_less_is_better.push(less_is_better);
Ok(IntegerResourceVariable(id))
}
#[inline]
pub fn get_continuous_variable(&self, name: &str) -> Result<ContinuousVariable, ModelErr> {
let id = util::get_id(name, &self.name_to_continuous_variable)?;
Ok(ContinuousVariable(id))
}
pub fn add_continuous_variable<T>(&mut self, name: T) -> Result<ContinuousVariable, ModelErr>
where
String: From<T>,
{
let id = util::add_name(
name,
&mut self.continuous_variable_names,
&mut self.name_to_continuous_variable,
)?;
Ok(ContinuousVariable(id))
}
#[inline]
pub fn get_continuous_resource_variable(
&self,
name: &str,
) -> Result<ContinuousResourceVariable, ModelErr> {
let id = util::get_id(name, &self.name_to_continuous_resource_variable)?;
Ok(ContinuousResourceVariable(id))
}
pub fn add_continuous_resource_variable<T>(
&mut self,
name: T,
less_is_better: bool,
) -> Result<ContinuousResourceVariable, ModelErr>
where
String: From<T>,
{
let id = util::add_name(
name,
&mut self.continuous_resource_variable_names,
&mut self.name_to_continuous_resource_variable,
)?;
self.continuous_less_is_better.push(less_is_better);
Ok(ContinuousResourceVariable(id))
}
fn check_object(&self, ob: ObjectType) -> Result<(), ModelErr> {
if ob.id() >= self.number_of_object_types() {
Err(ModelErr::new(format!(
"object id {id} >= #object types ({len})",
id = ob.id(),
len = self.object_numbers.len()
)))
} else {
Ok(())
}
}
}
pub trait CheckVariable<T> {
fn check_variable(&self, v: T) -> Result<(), ModelErr>;
}
macro_rules! impl_check_variable {
($T:ty,$x:ident) => {
impl CheckVariable<$T> for StateMetadata {
fn check_variable(&self, v: $T) -> Result<(), ModelErr> {
let id = v.id();
let n = self.$x.len();
if id >= n {
Err(ModelErr::new(format!(
"variable id {id} >= #variables ({n})",
)))
} else {
Ok(())
}
}
}
};
}
impl_check_variable!(ElementVariable, element_variable_names);
impl_check_variable!(ElementResourceVariable, element_resource_variable_names);
impl_check_variable!(SetVariable, set_variable_names);
impl_check_variable!(VectorVariable, vector_variable_names);
impl_check_variable!(IntegerVariable, integer_variable_names);
impl_check_variable!(IntegerResourceVariable, integer_resource_variable_names);
impl_check_variable!(ContinuousVariable, continuous_variable_names);
impl_check_variable!(
ContinuousResourceVariable,
continuous_resource_variable_names
);
pub trait GetObjectTypeOf<T> {
fn get_object_type_of(&self, v: T) -> Result<ObjectType, ModelErr>;
}
macro_rules! impl_get_object_type_of {
($T:ty,$x:ident) => {
impl GetObjectTypeOf<$T> for StateMetadata {
fn get_object_type_of(&self, v: $T) -> Result<ObjectType, ModelErr> {
self.check_variable(v)?;
Ok(ObjectType(self.$x[v.id()]))
}
}
};
}
impl_get_object_type_of!(ElementVariable, element_variable_to_object);
impl_get_object_type_of!(ElementResourceVariable, element_resource_variable_to_object);
impl_get_object_type_of!(SetVariable, set_variable_to_object);
impl_get_object_type_of!(VectorVariable, vector_variable_to_object);
pub trait AccessPreference<T> {
fn get_preference(&self, v: T) -> Result<bool, ModelErr>;
fn set_preference(&mut self, v: T, less_is_better: bool) -> Result<(), ModelErr>;
}
macro_rules! impl_access_preference {
($T:ty,$x:ident) => {
impl AccessPreference<$T> for StateMetadata {
fn get_preference(&self, v: $T) -> Result<bool, ModelErr> {
self.check_variable(v)?;
Ok(self.$x[v.id()])
}
fn set_preference(&mut self, v: $T, less_is_better: bool) -> Result<(), ModelErr> {
self.check_variable(v)?;
self.$x[v.id()] = less_is_better;
Ok(())
}
}
};
}
impl_access_preference!(ElementResourceVariable, element_less_is_better);
impl_access_preference!(IntegerResourceVariable, integer_less_is_better);
impl_access_preference!(ContinuousResourceVariable, continuous_less_is_better);
#[cfg(test)]
mod tests {
use super::super::expression::*;
use super::*;
fn generate_metadata() -> StateMetadata {
let object_names = vec![String::from("object"), String::from("small")];
let object_numbers = vec![10, 2];
let mut name_to_object = FxHashMap::default();
name_to_object.insert(String::from("object"), 0);
name_to_object.insert(String::from("small"), 1);
let set_variable_names = vec![
String::from("s0"),
String::from("s1"),
String::from("s2"),
String::from("s3"),
];
let mut name_to_set_variable = FxHashMap::default();
name_to_set_variable.insert(String::from("s0"), 0);
name_to_set_variable.insert(String::from("s1"), 1);
name_to_set_variable.insert(String::from("s2"), 2);
name_to_set_variable.insert(String::from("s3"), 3);
let set_variable_to_object = vec![0, 0, 0, 1];
let vector_variable_names = vec![
String::from("p0"),
String::from("p1"),
String::from("p2"),
String::from("p3"),
];
let mut name_to_vector_variable = FxHashMap::default();
name_to_vector_variable.insert(String::from("p0"), 0);
name_to_vector_variable.insert(String::from("p1"), 1);
name_to_vector_variable.insert(String::from("p2"), 2);
name_to_vector_variable.insert(String::from("p3"), 3);
let vector_variable_to_object = vec![0, 0, 0, 1];
let element_variable_names = vec![
String::from("e0"),
String::from("e1"),
String::from("e2"),
String::from("e3"),
];
let mut name_to_element_variable = FxHashMap::default();
name_to_element_variable.insert(String::from("e0"), 0);
name_to_element_variable.insert(String::from("e1"), 1);
name_to_element_variable.insert(String::from("e2"), 2);
name_to_element_variable.insert(String::from("e3"), 3);
let element_variable_to_object = vec![0, 0, 0, 1];
let integer_variable_names = vec![
String::from("i0"),
String::from("i1"),
String::from("i2"),
String::from("i3"),
];
let mut name_to_integer_variable = FxHashMap::default();
name_to_integer_variable.insert(String::from("i0"), 0);
name_to_integer_variable.insert(String::from("i1"), 1);
name_to_integer_variable.insert(String::from("i2"), 2);
name_to_integer_variable.insert(String::from("i3"), 3);
let continuous_variable_names = vec![
String::from("c0"),
String::from("c1"),
String::from("c2"),
String::from("c3"),
];
let mut name_to_continuous_variable = FxHashMap::default();
name_to_continuous_variable.insert(String::from("c0"), 0);
name_to_continuous_variable.insert(String::from("c1"), 1);
name_to_continuous_variable.insert(String::from("c2"), 2);
name_to_continuous_variable.insert(String::from("c3"), 3);
let element_resource_variable_names = vec![
String::from("er0"),
String::from("er1"),
String::from("er2"),
String::from("er3"),
];
let mut name_to_element_resource_variable = FxHashMap::default();
name_to_element_resource_variable.insert(String::from("er0"), 0);
name_to_element_resource_variable.insert(String::from("er1"), 1);
name_to_element_resource_variable.insert(String::from("er2"), 2);
name_to_element_resource_variable.insert(String::from("er3"), 3);
let element_resource_variable_to_object = vec![0, 0, 0, 1];
let integer_resource_variable_names = vec![
String::from("ir0"),
String::from("ir1"),
String::from("ir2"),
String::from("ir3"),
];
let mut name_to_integer_resource_variable = FxHashMap::default();
name_to_integer_resource_variable.insert(String::from("ir0"), 0);
name_to_integer_resource_variable.insert(String::from("ir1"), 1);
name_to_integer_resource_variable.insert(String::from("ir2"), 2);
name_to_integer_resource_variable.insert(String::from("ir3"), 3);
let continuous_resource_variable_names = vec![
String::from("cr0"),
String::from("cr1"),
String::from("cr2"),
String::from("cr3"),
];
let mut name_to_continuous_resource_variable = FxHashMap::default();
name_to_continuous_resource_variable.insert(String::from("cr0"), 0);
name_to_continuous_resource_variable.insert(String::from("cr1"), 1);
name_to_continuous_resource_variable.insert(String::from("cr2"), 2);
name_to_continuous_resource_variable.insert(String::from("cr3"), 3);
StateMetadata {
object_type_names: object_names,
name_to_object_type: name_to_object,
object_numbers,
set_variable_names,
name_to_set_variable,
set_variable_to_object,
vector_variable_names,
name_to_vector_variable,
vector_variable_to_object,
element_variable_names,
name_to_element_variable,
element_variable_to_object,
integer_variable_names,
name_to_integer_variable,
continuous_variable_names,
name_to_continuous_variable,
element_resource_variable_names,
name_to_element_resource_variable,
element_resource_variable_to_object,
element_less_is_better: vec![false, false, true, false],
integer_resource_variable_names,
name_to_integer_resource_variable,
integer_less_is_better: vec![false, false, true, false],
continuous_resource_variable_names,
name_to_continuous_resource_variable,
continuous_less_is_better: vec![false, false, true, false],
}
}
#[test]
fn state_get_number_of_set_variables() {
let state = State {
signature_variables: SignatureVariables {
set_variables: vec![Set::default()],
..Default::default()
},
..Default::default()
};
assert_eq!(state.get_number_of_set_variables(), 1);
}
#[test]
fn state_get_set_variable() {
let mut set = Set::with_capacity(2);
set.insert(1);
let state = State {
signature_variables: SignatureVariables {
set_variables: vec![Set::with_capacity(2), set.clone()],
..Default::default()
},
..Default::default()
};
assert_eq!(state.get_set_variable(0), &Set::with_capacity(2));
assert_eq!(state.get_set_variable(1), &set);
}
#[test]
#[should_panic]
fn state_get_set_variable_panic() {
let state = State {
signature_variables: SignatureVariables {
set_variables: vec![Set::default()],
..Default::default()
},
..Default::default()
};
state.get_set_variable(1);
}
#[test]
fn state_get_number_of_vector_variables() {
let state = State {
signature_variables: SignatureVariables {
vector_variables: vec![Vector::default()],
..Default::default()
},
..Default::default()
};
assert_eq!(state.get_number_of_vector_variables(), 1);
}
#[test]
fn state_get_vector_variable() {
let state = State {
signature_variables: SignatureVariables {
vector_variables: vec![Vector::default(), vec![1]],
..Default::default()
},
..Default::default()
};
assert_eq!(state.get_vector_variable(0), &Vector::default());
assert_eq!(state.get_vector_variable(1), &vec![1]);
}
#[test]
#[should_panic]
fn state_get_vector_variable_panic() {
let state = State {
signature_variables: SignatureVariables {
vector_variables: vec![Vector::default()],
..Default::default()
},
..Default::default()
};
state.get_vector_variable(1);
}
#[test]
fn state_get_number_of_element_variables() {
let state = State {
signature_variables: SignatureVariables {
element_variables: vec![0],
..Default::default()
},
..Default::default()
};
assert_eq!(state.get_number_of_element_variables(), 1);
}
#[test]
fn state_get_element_variable() {
let state = State {
signature_variables: SignatureVariables {
element_variables: vec![0, 1],
..Default::default()
},
..Default::default()
};
assert_eq!(state.get_element_variable(0), 0);
assert_eq!(state.get_element_variable(1), 1);
}
#[test]
#[should_panic]
fn state_get_element_variable_panic() {
let state = State {
signature_variables: SignatureVariables {
element_variables: vec![0],
..Default::default()
},
..Default::default()
};
state.get_element_variable(1);
}
#[test]
fn state_get_number_of_integer_variables() {
let state = State {
signature_variables: SignatureVariables {
integer_variables: vec![0],
..Default::default()
},
..Default::default()
};
assert_eq!(state.get_number_of_integer_variables(), 1);
}
#[test]
fn state_get_integer_variable() {
let state = State {
signature_variables: SignatureVariables {
integer_variables: vec![0, 1],
..Default::default()
},
..Default::default()
};
assert_eq!(state.get_integer_variable(0), 0);
assert_eq!(state.get_integer_variable(1), 1);
}
#[test]
#[should_panic]
fn state_get_integer_variable_panic() {
let state = State {
signature_variables: SignatureVariables {
integer_variables: vec![0],
..Default::default()
},
..Default::default()
};
state.get_integer_variable(1);
}
#[test]
fn state_get_number_of_continuous_variables() {
let state = State {
signature_variables: SignatureVariables {
continuous_variables: vec![0.0],
..Default::default()
},
..Default::default()
};
assert_eq!(state.get_number_of_continuous_variables(), 1);
}
#[test]
fn state_get_continuous_variable() {
let state = State {
signature_variables: SignatureVariables {
continuous_variables: vec![0.0, 1.0],
..Default::default()
},
..Default::default()
};
assert_eq!(state.get_continuous_variable(0), 0.0);
assert_eq!(state.get_continuous_variable(1), 1.0);
}
#[test]
#[should_panic]
fn state_get_continuous_variable_panic() {
let state = State {
signature_variables: SignatureVariables {
continuous_variables: vec![0.0],
..Default::default()
},
..Default::default()
};
state.get_continuous_variable(1);
}
#[test]
fn state_get_number_of_element_resource_variables() {
let state = State {
resource_variables: ResourceVariables {
element_variables: vec![0],
..Default::default()
},
..Default::default()
};
assert_eq!(state.get_number_of_element_resource_variables(), 1);
}
#[test]
fn state_get_element_resource_variable() {
let state = State {
resource_variables: ResourceVariables {
element_variables: vec![0, 1],
..Default::default()
},
..Default::default()
};
assert_eq!(state.get_element_resource_variable(0), 0);
assert_eq!(state.get_element_resource_variable(1), 1);
}
#[test]
#[should_panic]
fn state_get_element_resource_variable_panic() {
let state = State {
resource_variables: ResourceVariables {
element_variables: vec![0],
..Default::default()
},
..Default::default()
};
state.get_element_resource_variable(1);
}
#[test]
fn state_get_number_of_integer_resource_variables() {
let state = State {
resource_variables: ResourceVariables {
integer_variables: vec![0],
..Default::default()
},
..Default::default()
};
assert_eq!(state.get_number_of_integer_resource_variables(), 1);
}
#[test]
fn state_get_integer_resource_variable() {
let state = State {
resource_variables: ResourceVariables {
integer_variables: vec![0, 1],
..Default::default()
},
..Default::default()
};
assert_eq!(state.get_integer_resource_variable(0), 0);
assert_eq!(state.get_integer_resource_variable(1), 1);
}
#[test]
#[should_panic]
fn state_get_integer_resource_variable_panic() {
let state = State {
resource_variables: ResourceVariables {
integer_variables: vec![0],
..Default::default()
},
..Default::default()
};
state.get_integer_resource_variable(1);
}
#[test]
fn state_get_number_of_continuous_resource_variables() {
let state = State {
resource_variables: ResourceVariables {
continuous_variables: vec![0.0],
..Default::default()
},
..Default::default()
};
assert_eq!(state.get_number_of_continuous_resource_variables(), 1);
}
#[test]
fn state_get_continuous_resource_variable() {
let state = State {
resource_variables: ResourceVariables {
continuous_variables: vec![0.0, 1.0],
..Default::default()
},
..Default::default()
};
assert_eq!(state.get_continuous_resource_variable(0), 0.0);
assert_eq!(state.get_continuous_resource_variable(1), 1.0);
}
#[test]
#[should_panic]
fn state_get_continuous_resource_variable_panic() {
let state = State {
resource_variables: ResourceVariables {
continuous_variables: vec![0.0],
..Default::default()
},
..Default::default()
};
state.get_continuous_resource_variable(1);
}
#[test]
fn apply_effect() {
let state_functions = StateFunctions::default();
let mut function_cache = StateFunctionCache::new(&state_functions);
let mut set1 = Set::with_capacity(3);
set1.insert(0);
set1.insert(2);
let mut set2 = Set::with_capacity(3);
set2.insert(0);
set2.insert(1);
let state = State {
signature_variables: SignatureVariables {
set_variables: vec![set1, set2],
vector_variables: vec![vec![0, 2], vec![1, 2]],
element_variables: vec![1, 2],
integer_variables: vec![1, 2, 3],
continuous_variables: vec![1.0, 2.0, 3.0],
},
resource_variables: ResourceVariables {
element_variables: vec![],
integer_variables: vec![4, 5, 6],
continuous_variables: vec![4.0, 5.0, 6.0],
},
};
let registry = table_registry::TableRegistry::default();
let set_effect1 = SetExpression::SetElementOperation(
SetElementOperator::Add,
ElementExpression::Constant(1),
Box::new(SetExpression::Reference(ReferenceExpression::Variable(0))),
);
let set_effect2 = SetExpression::SetElementOperation(
SetElementOperator::Remove,
ElementExpression::Constant(0),
Box::new(SetExpression::Reference(ReferenceExpression::Variable(1))),
);
let vector_effect1 = VectorExpression::Push(
ElementExpression::Constant(1),
Box::new(VectorExpression::Reference(ReferenceExpression::Variable(
0,
))),
);
let vector_effect2 = VectorExpression::Push(
ElementExpression::Constant(0),
Box::new(VectorExpression::Reference(ReferenceExpression::Variable(
1,
))),
);
let element_effect1 = ElementExpression::Constant(2);
let element_effect2 = ElementExpression::Constant(1);
let integer_effect1 = IntegerExpression::BinaryOperation(
BinaryOperator::Sub,
Box::new(IntegerExpression::Variable(0)),
Box::new(IntegerExpression::Constant(1)),
);
let integer_effect2 = IntegerExpression::BinaryOperation(
BinaryOperator::Mul,
Box::new(IntegerExpression::Variable(1)),
Box::new(IntegerExpression::Constant(2)),
);
let continuous_effect1 = ContinuousExpression::BinaryOperation(
BinaryOperator::Sub,
Box::new(ContinuousExpression::Variable(0)),
Box::new(ContinuousExpression::Constant(1.0)),
);
let continuous_effect2 = ContinuousExpression::BinaryOperation(
BinaryOperator::Mul,
Box::new(ContinuousExpression::Variable(1)),
Box::new(ContinuousExpression::Constant(2.0)),
);
let integer_resource_effect1 = IntegerExpression::BinaryOperation(
BinaryOperator::Add,
Box::new(IntegerExpression::ResourceVariable(0)),
Box::new(IntegerExpression::Constant(1)),
);
let integer_resource_effect2 = IntegerExpression::BinaryOperation(
BinaryOperator::Div,
Box::new(IntegerExpression::ResourceVariable(1)),
Box::new(IntegerExpression::Constant(2)),
);
let continuous_resource_effect1 = ContinuousExpression::BinaryOperation(
BinaryOperator::Add,
Box::new(ContinuousExpression::ResourceVariable(0)),
Box::new(ContinuousExpression::Constant(1.0)),
);
let continuous_resource_effect2 = ContinuousExpression::BinaryOperation(
BinaryOperator::Div,
Box::new(ContinuousExpression::ResourceVariable(1)),
Box::new(ContinuousExpression::Constant(2.0)),
);
let effect = effect::Effect {
set_effects: vec![(0, set_effect1), (1, set_effect2)],
vector_effects: vec![(0, vector_effect1), (1, vector_effect2)],
element_effects: vec![(0, element_effect1), (1, element_effect2)],
integer_effects: vec![(0, integer_effect1), (1, integer_effect2)],
continuous_effects: vec![(0, continuous_effect1), (1, continuous_effect2)],
element_resource_effects: vec![],
integer_resource_effects: vec![
(0, integer_resource_effect1),
(1, integer_resource_effect2),
],
continuous_resource_effects: vec![
(0, continuous_resource_effect1),
(1, continuous_resource_effect2),
],
};
let mut set1 = Set::with_capacity(3);
set1.insert(0);
set1.insert(1);
set1.insert(2);
let mut set2 = Set::with_capacity(3);
set2.insert(1);
let expected = State {
signature_variables: SignatureVariables {
set_variables: vec![set1, set2],
vector_variables: vec![vec![0, 2, 1], vec![1, 2, 0]],
element_variables: vec![2, 1],
integer_variables: vec![0, 4, 3],
continuous_variables: vec![0.0, 4.0, 3.0],
},
resource_variables: ResourceVariables {
element_variables: vec![],
integer_variables: vec![5, 2, 6],
continuous_variables: vec![5.0, 2.5, 6.0],
},
};
let successor: State =
state.apply_effect(&effect, &mut function_cache, &state_functions, ®istry);
assert_eq!(successor, expected);
}
#[test]
fn is_satisfied() {
let state = State {
signature_variables: SignatureVariables {
integer_variables: vec![1],
..Default::default()
},
..Default::default()
};
let mut name_to_integer_variable = FxHashMap::default();
name_to_integer_variable.insert(String::from("i0"), 0);
let metadata = StateMetadata {
integer_variable_names: vec![String::from("i0")],
name_to_integer_variable,
..Default::default()
};
let base_state = State {
signature_variables: SignatureVariables {
integer_variables: vec![1],
..Default::default()
},
..Default::default()
};
assert!(base_state.is_satisfied(&state, &metadata));
let base_state = State {
signature_variables: SignatureVariables {
integer_variables: vec![2],
..Default::default()
},
..Default::default()
};
assert!(!base_state.is_satisfied(&state, &metadata));
}
#[test]
fn number_of_objects() {
let metadata = generate_metadata();
assert_eq!(metadata.number_of_object_types(), 2);
}
#[test]
fn number_of_set_variables() {
let metadata = generate_metadata();
assert_eq!(metadata.number_of_set_variables(), 4);
}
#[test]
fn number_of_vector_variables() {
let metadata = generate_metadata();
assert_eq!(metadata.number_of_vector_variables(), 4);
}
#[test]
fn number_of_element_variables() {
let metadata = generate_metadata();
assert_eq!(metadata.number_of_element_variables(), 4);
}
#[test]
fn number_of_integer_variables() {
let metadata = generate_metadata();
assert_eq!(metadata.number_of_integer_variables(), 4);
}
#[test]
fn number_of_continuous_variables() {
let metadata = generate_metadata();
assert_eq!(metadata.number_of_continuous_variables(), 4);
}
#[test]
fn number_of_integer_resource_variables() {
let metadata = generate_metadata();
assert_eq!(metadata.number_of_integer_resource_variables(), 4);
}
#[test]
fn number_of_continuous_resource_variables() {
let metadata = generate_metadata();
assert_eq!(metadata.number_of_continuous_resource_variables(), 4);
}
#[test]
fn has_resource_variable() {
let metadata = StateMetadata {
element_variable_names: vec![String::from("v")],
element_variable_to_object: vec![0],
integer_variable_names: vec![String::from("v")],
continuous_variable_names: vec![String::from("v")],
set_variable_names: vec![String::from("v")],
set_variable_to_object: vec![0],
vector_variable_names: vec![String::from("v")],
vector_variable_to_object: vec![0],
..Default::default()
};
assert!(!metadata.has_resource_variables());
let metadata = StateMetadata {
element_resource_variable_names: vec![String::from("v")],
element_resource_variable_to_object: vec![0],
element_less_is_better: vec![true],
..Default::default()
};
assert!(metadata.has_resource_variables());
let metadata = StateMetadata {
integer_resource_variable_names: vec![String::from("v")],
integer_less_is_better: vec![true],
..Default::default()
};
assert!(metadata.has_resource_variables());
let metadata = StateMetadata {
continuous_resource_variable_names: vec![String::from("v")],
continuous_less_is_better: vec![true],
..Default::default()
};
assert!(metadata.has_resource_variables());
}
#[test]
fn get_name_set() {
let metadata = generate_metadata();
let mut expected = FxHashSet::default();
expected.insert(String::from("object"));
expected.insert(String::from("small"));
expected.insert(String::from("s0"));
expected.insert(String::from("s1"));
expected.insert(String::from("s2"));
expected.insert(String::from("s3"));
expected.insert(String::from("p0"));
expected.insert(String::from("p1"));
expected.insert(String::from("p2"));
expected.insert(String::from("p3"));
expected.insert(String::from("e0"));
expected.insert(String::from("e1"));
expected.insert(String::from("e2"));
expected.insert(String::from("e3"));
expected.insert(String::from("er0"));
expected.insert(String::from("er1"));
expected.insert(String::from("er2"));
expected.insert(String::from("er3"));
expected.insert(String::from("i0"));
expected.insert(String::from("i1"));
expected.insert(String::from("i2"));
expected.insert(String::from("i3"));
expected.insert(String::from("c0"));
expected.insert(String::from("c1"));
expected.insert(String::from("c2"));
expected.insert(String::from("c3"));
expected.insert(String::from("ir0"));
expected.insert(String::from("ir1"));
expected.insert(String::from("ir2"));
expected.insert(String::from("ir3"));
expected.insert(String::from("cr0"));
expected.insert(String::from("cr1"));
expected.insert(String::from("cr2"));
expected.insert(String::from("cr3"));
assert_eq!(metadata.get_name_set(), expected);
}
#[test]
fn dominance() {
let metadata = generate_metadata();
let a = State {
resource_variables: ResourceVariables {
element_variables: vec![0, 1, 2, 0],
integer_variables: vec![1, 2, 2, 0],
continuous_variables: vec![0.0, 0.0, 0.0, 0.0],
},
..Default::default()
};
let b = State {
resource_variables: ResourceVariables {
element_variables: vec![0, 1, 2, 0],
integer_variables: vec![1, 2, 2, 0],
continuous_variables: vec![0.0, 0.0, 0.0, 0.0],
},
..Default::default()
};
assert_eq!(metadata.dominance(&a, &b), Some(Ordering::Equal));
let b = State {
resource_variables: ResourceVariables {
element_variables: vec![0, 0, 3, 0],
integer_variables: vec![1, 2, 2, 0],
continuous_variables: vec![0.0, 0.0, 0.0, 0.0],
},
..Default::default()
};
assert_eq!(metadata.dominance(&a, &b), Some(Ordering::Greater));
assert_eq!(metadata.dominance(&b, &a), Some(Ordering::Less));
let b = State {
resource_variables: ResourceVariables {
element_variables: vec![0, 1, 2, 0],
integer_variables: vec![1, 1, 3, 0],
continuous_variables: vec![0.0, 0.0, 0.0, 0.0],
},
..Default::default()
};
assert_eq!(metadata.dominance(&a, &b), Some(Ordering::Greater));
assert_eq!(metadata.dominance(&b, &a), Some(Ordering::Less));
let b = State {
resource_variables: ResourceVariables {
element_variables: vec![0, 1, 2, 0],
integer_variables: vec![1, 3, 3, 0],
continuous_variables: vec![0.0, 0.0, 0.0, 0.0],
},
..Default::default()
};
assert!(metadata.dominance(&b, &a).is_none());
let a = State {
resource_variables: ResourceVariables {
element_variables: vec![0, 1, 2, 0],
integer_variables: vec![1, 2, 2, 0],
continuous_variables: vec![1.0, 2.0, 2.0, 0.0],
},
..Default::default()
};
let b = State {
resource_variables: ResourceVariables {
element_variables: vec![0, 1, 2, 0],
integer_variables: vec![1, 2, 2, 0],
continuous_variables: vec![1.0, 1.0, 3.0, 0.0],
},
..Default::default()
};
assert_eq!(metadata.dominance(&a, &b), Some(Ordering::Greater));
assert_eq!(metadata.dominance(&b, &a), Some(Ordering::Less));
let b = State {
resource_variables: ResourceVariables {
element_variables: vec![0, 1, 2, 0],
integer_variables: vec![1, 2, 2, 0],
continuous_variables: vec![1.0, 3.0, 4.0, 0.0],
},
..Default::default()
};
assert!(metadata.dominance(&a, &b).is_none());
}
#[test]
#[should_panic]
fn dominance_element_length_panic() {
let metadata = generate_metadata();
let a = State {
resource_variables: ResourceVariables {
element_variables: vec![1, 2, 3],
integer_variables: vec![1, 2, 2, 2],
continuous_variables: vec![],
},
..Default::default()
};
let b = State {
resource_variables: ResourceVariables {
element_variables: vec![1, 2, 3, 0],
integer_variables: vec![1, 2, 2, 2],
continuous_variables: vec![],
},
..Default::default()
};
metadata.dominance(&b, &a);
}
#[test]
#[should_panic]
fn dominance_integer_length_panic() {
let metadata = generate_metadata();
let a = State {
resource_variables: ResourceVariables {
element_variables: vec![],
integer_variables: vec![1, 2, 2],
continuous_variables: vec![],
},
..Default::default()
};
let b = State {
resource_variables: ResourceVariables {
element_variables: vec![],
integer_variables: vec![1, 2, 2, 0],
continuous_variables: vec![],
},
..Default::default()
};
metadata.dominance(&b, &a);
}
#[test]
#[should_panic]
fn dominance_continuous_length_panic() {
let metadata = generate_metadata();
let a = State {
resource_variables: ResourceVariables {
element_variables: vec![],
integer_variables: vec![1, 2, 2, 0],
continuous_variables: vec![1.0, 2.0, 2.0, 0.0],
},
..Default::default()
};
let b = State {
resource_variables: ResourceVariables {
element_variables: vec![],
integer_variables: vec![1, 2, 2, 0],
continuous_variables: vec![1.0, 1.0, 3.0],
},
..Default::default()
};
metadata.dominance(&b, &a);
}
#[test]
fn check_state_ok() {
let metadata = generate_metadata();
let state = State {
signature_variables: SignatureVariables {
element_variables: vec![4, 8, 9, 1],
vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
set_variables: vec![
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(2),
],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
resource_variables: ResourceVariables {
element_variables: vec![4, 8, 9, 1],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
};
assert!(metadata.check_state(&state).is_ok())
}
#[test]
fn chech_state_err() {
let metadata = generate_metadata();
let state = State {
signature_variables: SignatureVariables {
element_variables: vec![4, 8, 9],
vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
set_variables: vec![
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(2),
],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
resource_variables: ResourceVariables {
element_variables: vec![4, 8, 9, 1],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
};
assert!(metadata.check_state(&state).is_err());
let state = State {
signature_variables: SignatureVariables {
element_variables: vec![4, 8, 9, 1],
vector_variables: vec![vec![4], vec![8], vec![9]],
set_variables: vec![
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(2),
],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
resource_variables: ResourceVariables {
element_variables: vec![4, 8, 9, 1],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
};
assert!(metadata.check_state(&state).is_err());
let state = State {
signature_variables: SignatureVariables {
element_variables: vec![4, 8, 9, 1],
vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
set_variables: vec![
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(10),
],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
resource_variables: ResourceVariables {
element_variables: vec![4, 8, 9, 1],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
};
assert!(metadata.check_state(&state).is_err());
let state = State {
signature_variables: SignatureVariables {
element_variables: vec![4, 8, 9, 1],
vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
set_variables: vec![
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(2),
],
integer_variables: vec![-1, 2, 4],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
resource_variables: ResourceVariables {
element_variables: vec![4, 8, 9, 1],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
};
assert!(metadata.check_state(&state).is_err());
let state = State {
signature_variables: SignatureVariables {
element_variables: vec![4, 8, 9, 1],
vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
set_variables: vec![
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(2),
],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0],
},
resource_variables: ResourceVariables {
element_variables: vec![4, 8, 9, 1],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
};
assert!(metadata.check_state(&state).is_err());
let state = State {
signature_variables: SignatureVariables {
element_variables: vec![4, 8, 9, 1],
vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
set_variables: vec![
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(2),
],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
resource_variables: ResourceVariables {
element_variables: vec![4, 8, 9],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
};
assert!(metadata.check_state(&state).is_err());
let state = State {
signature_variables: SignatureVariables {
element_variables: vec![4, 8, 9, 1],
vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
set_variables: vec![
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(2),
],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
resource_variables: ResourceVariables {
element_variables: vec![4, 8, 9, 1],
integer_variables: vec![-1, 2, 4],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
};
assert!(metadata.check_state(&state).is_err());
let state = State {
signature_variables: SignatureVariables {
element_variables: vec![4, 8, 9, 1],
vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
set_variables: vec![
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(2),
],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
resource_variables: ResourceVariables {
element_variables: vec![4, 8, 9, 1],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0],
},
};
assert!(metadata.check_state(&state).is_err());
let state = State {
signature_variables: SignatureVariables {
element_variables: vec![4, 8, 10, 1],
vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
set_variables: vec![
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(2),
],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
resource_variables: ResourceVariables {
element_variables: vec![4, 8, 9, 1],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
};
assert!(metadata.check_state(&state).is_err());
let state = State {
signature_variables: SignatureVariables {
element_variables: vec![4, 8, 9, 1],
vector_variables: vec![vec![4], vec![8], vec![10], vec![1]],
set_variables: vec![
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(2),
],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
resource_variables: ResourceVariables {
element_variables: vec![4, 8, 9, 1],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
};
assert!(metadata.check_state(&state).is_err());
let state = State {
signature_variables: SignatureVariables {
element_variables: vec![4, 8, 9, 1],
vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
set_variables: vec![
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(11),
Set::with_capacity(2),
],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
resource_variables: ResourceVariables {
element_variables: vec![4, 8, 9, 1],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
};
assert!(metadata.check_state(&state).is_err());
let state = State {
signature_variables: SignatureVariables {
element_variables: vec![4, 8, 9, 1],
vector_variables: vec![vec![4], vec![8], vec![9], vec![1]],
set_variables: vec![
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(10),
Set::with_capacity(2),
],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
resource_variables: ResourceVariables {
element_variables: vec![4, 8, 10, 1],
integer_variables: vec![-1, 2, 4, 5],
continuous_variables: vec![-1.0, 2.0, 4.0, 5.0],
},
};
assert!(metadata.check_state(&state).is_err());
}
#[test]
fn add_object_ok() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
assert_eq!(ob, ObjectType(0));
assert_eq!(ob.id(), 0);
assert_eq!(metadata.object_type_names, vec![String::from("something")]);
assert_eq!(metadata.object_numbers, vec![10]);
let mut name_to_object = FxHashMap::default();
name_to_object.insert(String::from("something"), 0);
assert_eq!(metadata.name_to_object_type, name_to_object);
let ob = metadata.add_object_type(String::from("other"), 5);
assert!(ob.is_ok());
let ob = ob.unwrap();
assert_eq!(ob, ObjectType(1));
assert_eq!(ob.id(), 1);
assert_eq!(
metadata.object_type_names,
vec![String::from("something"), String::from("other")]
);
assert_eq!(metadata.object_numbers, vec![10, 5]);
name_to_object.insert(String::from("other"), 1);
assert_eq!(metadata.name_to_object_type, name_to_object);
}
#[test]
fn add_object_err() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_err());
assert_eq!(metadata.object_type_names, vec![String::from("something")]);
assert_eq!(metadata.object_numbers, vec![10]);
let mut name_to_object = FxHashMap::default();
name_to_object.insert(String::from("something"), 0);
assert_eq!(metadata.name_to_object_type, name_to_object);
}
#[test]
fn number_of_object_ok() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let result = metadata.get_number_of_objects(ob);
assert!(result.is_ok());
assert_eq!(result.unwrap(), 10);
}
#[test]
fn number_of_object_err() {
let mut metadata1 = StateMetadata::default();
let ob = metadata1.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let mut metadata2 = StateMetadata::default();
let ob = metadata2.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = metadata2.add_object_type(String::from("other"), 10);
assert!(ob.is_ok());
assert_eq!(metadata1.object_type_names, vec![String::from("something")]);
assert_eq!(metadata1.object_numbers, vec![10]);
let mut name_to_object = FxHashMap::default();
name_to_object.insert(String::from("something"), 0);
assert_eq!(metadata1.name_to_object_type, name_to_object);
}
#[test]
fn create_set_ok() {
let mut metadata1 = StateMetadata::default();
let ob = metadata1.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let result = metadata1.create_set(ob, &[0, 1, 9]);
assert!(result.is_ok());
let mut set = Set::with_capacity(10);
set.insert(0);
set.insert(1);
set.insert(9);
assert_eq!(result.unwrap(), set);
}
#[test]
fn create_set_err() {
let mut metadata1 = StateMetadata::default();
let ob = metadata1.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let result = metadata1.create_set(ob, &[0, 1, 10]);
assert!(result.is_err());
let mut metadata2 = StateMetadata::default();
let ob = metadata2.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = metadata2.add_object_type(String::from("other"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let result = metadata1.create_set(ob, &[0, 1, 9]);
assert!(result.is_err());
}
#[test]
fn add_element_variable_ok() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_element_variable(String::from("v"), ob);
assert!(v.is_ok());
let v = v.unwrap();
assert_eq!(v, ElementVariable(0));
assert_eq!(v.id(), 0);
assert_eq!(metadata.element_variable_names, vec![String::from("v")]);
assert_eq!(metadata.element_variable_to_object, vec![0]);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_element_variable, name_to_variable);
let v = metadata.add_element_variable(String::from("u"), ob);
assert!(v.is_ok());
let v = v.unwrap();
assert_eq!(v, ElementVariable(1));
assert_eq!(v.id(), 1);
assert_eq!(
metadata.element_variable_names,
vec![String::from("v"), String::from("u")]
);
assert_eq!(metadata.element_variable_to_object, vec![0, 0]);
name_to_variable.insert(String::from("u"), 1);
assert_eq!(metadata.name_to_element_variable, name_to_variable);
}
#[test]
fn add_element_variable_err() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_element_variable(String::from("v"), ob);
assert!(v.is_ok());
let v = metadata.add_element_variable(String::from("v"), ob);
assert!(v.is_err());
assert_eq!(metadata.element_variable_names, vec![String::from("v")]);
assert_eq!(metadata.element_variable_to_object, vec![0]);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_element_variable, name_to_variable);
let mut metadata2 = StateMetadata::default();
let ob = metadata2.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = metadata2.add_object_type(String::from("other"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_element_variable(String::from("u"), ob);
assert!(v.is_err());
assert_eq!(metadata.element_variable_names, vec![String::from("v")]);
assert_eq!(metadata.element_variable_to_object, vec![0]);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_element_variable, name_to_variable);
}
#[test]
fn get_object_type_of_element_variable_ok() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_element_variable(String::from("v"), ob);
assert!(v.is_ok());
let v = v.unwrap();
let ob1 = metadata.get_object_type_of(v);
assert!(ob1.is_ok());
assert_eq!(ob1.unwrap(), ob);
}
#[test]
fn get_object_type_of_element_variable_err() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_element_variable(String::from("v"), ob);
assert!(v.is_ok());
let mut metadata2 = StateMetadata::default();
let ob = metadata2.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata2.add_element_variable(String::from("v"), ob);
assert!(v.is_ok());
let v = metadata2.add_element_variable(String::from("u"), ob);
assert!(v.is_ok());
let v = v.unwrap();
let ob = metadata.get_object_type_of(v);
assert!(ob.is_err());
}
#[test]
fn add_element_resource_variable_ok() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_element_resource_variable(String::from("v"), ob, true);
assert!(v.is_ok());
let v = v.unwrap();
assert_eq!(v, ElementResourceVariable(0));
assert_eq!(v.id(), 0);
assert_eq!(
metadata.element_resource_variable_names,
vec![String::from("v")]
);
assert_eq!(metadata.element_resource_variable_to_object, vec![0]);
assert_eq!(metadata.element_less_is_better, vec![true]);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_element_resource_variable, name_to_variable);
let v = metadata.add_element_resource_variable(String::from("u"), ob, false);
assert!(v.is_ok());
let v = v.unwrap();
assert_eq!(v, ElementResourceVariable(1));
assert_eq!(v.id(), 1);
assert_eq!(
metadata.element_resource_variable_names,
vec![String::from("v"), String::from("u")]
);
assert_eq!(metadata.element_resource_variable_to_object, vec![0, 0]);
name_to_variable.insert(String::from("u"), 1);
assert_eq!(metadata.name_to_element_resource_variable, name_to_variable);
assert_eq!(metadata.element_less_is_better, vec![true, false]);
}
#[test]
fn add_element_resource_variable_err() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_element_resource_variable(String::from("v"), ob, true);
assert!(v.is_ok());
let v = metadata.add_element_resource_variable(String::from("v"), ob, false);
assert!(v.is_err());
assert_eq!(
metadata.element_resource_variable_names,
vec![String::from("v")]
);
assert_eq!(metadata.element_resource_variable_to_object, vec![0]);
assert_eq!(metadata.element_less_is_better, vec![true]);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_element_resource_variable, name_to_variable);
let mut metadata2 = StateMetadata::default();
let ob = metadata2.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = metadata2.add_object_type(String::from("other"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_element_resource_variable(String::from("u"), ob, true);
assert!(v.is_err());
assert_eq!(
metadata.element_resource_variable_names,
vec![String::from("v")]
);
assert_eq!(metadata.element_resource_variable_to_object, vec![0]);
assert_eq!(metadata.element_less_is_better, vec![true]);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_element_resource_variable, name_to_variable);
}
#[test]
fn get_object_type_of_element_resource_variable_ok() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_element_resource_variable(String::from("v"), ob, true);
assert!(v.is_ok());
let v = v.unwrap();
let ob1 = metadata.get_object_type_of(v);
assert!(ob1.is_ok());
assert_eq!(ob1.unwrap(), ob);
}
#[test]
fn get_object_type_of_element_resource_variable_err() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_element_resource_variable(String::from("v"), ob, true);
assert!(v.is_ok());
let mut metadata2 = StateMetadata::default();
let ob = metadata2.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata2.add_element_resource_variable(String::from("v"), ob, false);
assert!(v.is_ok());
let v = metadata2.add_element_resource_variable(String::from("u"), ob, true);
assert!(v.is_ok());
let v = v.unwrap();
let ob = metadata.get_object_type_of(v);
assert!(ob.is_err());
}
#[test]
fn element_resource_variable_preference_ok() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_element_resource_variable(String::from("v"), ob, true);
assert!(v.is_ok());
let v = v.unwrap();
let result = metadata.get_preference(v);
assert!(result.is_ok());
assert!(result.unwrap());
let result = metadata.set_preference(v, false);
assert!(result.is_ok());
assert_eq!(metadata.element_less_is_better, vec![false]);
let result = metadata.get_preference(v);
assert!(result.is_ok());
assert!(!result.unwrap());
}
#[test]
fn element_resource_variable_preference_err() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_element_resource_variable(String::from("v"), ob, true);
assert!(v.is_ok());
let mut metadata2 = StateMetadata::default();
let ob = metadata2.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata2.add_element_resource_variable(String::from("v"), ob, true);
assert!(v.is_ok());
let v = metadata2.add_element_resource_variable(String::from("u"), ob, true);
assert!(v.is_ok());
let v = v.unwrap();
let result = metadata.get_preference(v);
assert!(result.is_err());
let result = metadata.set_preference(v, false);
assert!(result.is_err());
assert_eq!(metadata.element_less_is_better, vec![true]);
}
#[test]
fn add_set_variable_ok() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_set_variable(String::from("v"), ob);
assert!(v.is_ok());
let v = v.unwrap();
assert_eq!(v, SetVariable(0));
assert_eq!(v.id(), 0);
assert_eq!(metadata.set_variable_names, vec![String::from("v")]);
assert_eq!(metadata.set_variable_to_object, vec![0]);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_set_variable, name_to_variable);
let v = metadata.add_set_variable(String::from("u"), ob);
assert!(v.is_ok());
let v = v.unwrap();
assert_eq!(v, SetVariable(1));
assert_eq!(v.id(), 1);
assert_eq!(
metadata.set_variable_names,
vec![String::from("v"), String::from("u")]
);
assert_eq!(metadata.set_variable_to_object, vec![0, 0]);
name_to_variable.insert(String::from("u"), 1);
assert_eq!(metadata.name_to_set_variable, name_to_variable);
}
#[test]
fn add_set_variable_err() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_set_variable(String::from("v"), ob);
assert!(v.is_ok());
let v = metadata.add_set_variable(String::from("v"), ob);
assert!(v.is_err());
assert_eq!(metadata.set_variable_names, vec![String::from("v")]);
assert_eq!(metadata.set_variable_to_object, vec![0]);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_set_variable, name_to_variable);
let mut metadata2 = StateMetadata::default();
let ob = metadata2.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = metadata2.add_object_type(String::from("other"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_set_variable(String::from("u"), ob);
assert!(v.is_err());
assert_eq!(metadata.set_variable_names, vec![String::from("v")]);
assert_eq!(metadata.set_variable_to_object, vec![0]);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_set_variable, name_to_variable);
}
#[test]
fn get_object_type_of_set_variable_ok() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_set_variable(String::from("v"), ob);
assert!(v.is_ok());
let v = v.unwrap();
let ob1 = metadata.get_object_type_of(v);
assert!(ob1.is_ok());
assert_eq!(ob1.unwrap(), ob);
}
#[test]
fn get_object_type_of_set_variable_err() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_set_variable(String::from("v"), ob);
assert!(v.is_ok());
let mut metadata2 = StateMetadata::default();
let ob = metadata2.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata2.add_set_variable(String::from("v"), ob);
assert!(v.is_ok());
let v = metadata2.add_set_variable(String::from("u"), ob);
assert!(v.is_ok());
let v = v.unwrap();
let ob = metadata.get_object_type_of(v);
assert!(ob.is_err());
}
#[test]
fn add_vector_variable_ok() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_vector_variable(String::from("v"), ob);
assert!(v.is_ok());
let v = v.unwrap();
assert_eq!(v, VectorVariable(0));
assert_eq!(v.id(), 0);
assert_eq!(metadata.vector_variable_names, vec![String::from("v")]);
assert_eq!(metadata.vector_variable_to_object, vec![0]);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_vector_variable, name_to_variable);
let v = metadata.add_vector_variable(String::from("u"), ob);
assert!(v.is_ok());
let v = v.unwrap();
assert_eq!(v, VectorVariable(1));
assert_eq!(v.id(), 1);
assert_eq!(
metadata.vector_variable_names,
vec![String::from("v"), String::from("u")]
);
assert_eq!(metadata.vector_variable_to_object, vec![0, 0]);
name_to_variable.insert(String::from("u"), 1);
assert_eq!(metadata.name_to_vector_variable, name_to_variable);
}
#[test]
fn add_vector_variable_err() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_vector_variable(String::from("v"), ob);
assert!(v.is_ok());
let v = metadata.add_vector_variable(String::from("v"), ob);
assert!(v.is_err());
assert_eq!(metadata.vector_variable_names, vec![String::from("v")]);
assert_eq!(metadata.vector_variable_to_object, vec![0]);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_vector_variable, name_to_variable);
let mut metadata2 = StateMetadata::default();
let ob = metadata2.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = metadata2.add_object_type(String::from("other"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_vector_variable(String::from("u"), ob);
assert!(v.is_err());
assert_eq!(metadata.vector_variable_names, vec![String::from("v")]);
assert_eq!(metadata.vector_variable_to_object, vec![0]);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_vector_variable, name_to_variable);
}
#[test]
fn get_object_type_of_vector_variable_ok() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_vector_variable(String::from("v"), ob);
assert!(v.is_ok());
let v = v.unwrap();
let ob1 = metadata.get_object_type_of(v);
assert!(ob1.is_ok());
assert_eq!(ob1.unwrap(), ob);
}
#[test]
fn get_object_type_of_vector_variable_err() {
let mut metadata = StateMetadata::default();
let ob = metadata.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata.add_vector_variable(String::from("v"), ob);
assert!(v.is_ok());
let mut metadata2 = StateMetadata::default();
let ob = metadata2.add_object_type(String::from("something"), 10);
assert!(ob.is_ok());
let ob = ob.unwrap();
let v = metadata2.add_vector_variable(String::from("v"), ob);
assert!(v.is_ok());
let v = metadata2.add_vector_variable(String::from("u"), ob);
assert!(v.is_ok());
let v = v.unwrap();
let ob = metadata.get_object_type_of(v);
assert!(ob.is_err());
}
#[test]
fn add_integer_variable_ok() {
let mut metadata = StateMetadata::default();
let v = metadata.add_integer_variable(String::from("v"));
assert!(v.is_ok());
let v = v.unwrap();
assert_eq!(v, IntegerVariable(0));
assert_eq!(v.id(), 0);
assert_eq!(metadata.integer_variable_names, vec![String::from("v")]);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_integer_variable, name_to_variable);
let v = metadata.add_integer_variable(String::from("u"));
assert!(v.is_ok());
let v = v.unwrap();
assert_eq!(v, IntegerVariable(1));
assert_eq!(v.id(), 1);
assert_eq!(
metadata.integer_variable_names,
vec![String::from("v"), String::from("u")]
);
name_to_variable.insert(String::from("u"), 1);
assert_eq!(metadata.name_to_integer_variable, name_to_variable);
}
#[test]
fn add_integer_variable_err() {
let mut metadata = StateMetadata::default();
let v = metadata.add_integer_variable(String::from("v"));
assert!(v.is_ok());
let v = metadata.add_integer_variable(String::from("v"));
assert!(v.is_err());
assert_eq!(metadata.integer_variable_names, vec![String::from("v")]);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_integer_variable, name_to_variable);
}
#[test]
fn add_integer_resource_variable_ok() {
let mut metadata = StateMetadata::default();
let v = metadata.add_integer_resource_variable(String::from("v"), true);
assert!(v.is_ok());
let v = v.unwrap();
assert_eq!(v, IntegerResourceVariable(0));
assert_eq!(v.id(), 0);
assert_eq!(
metadata.integer_resource_variable_names,
vec![String::from("v")]
);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_integer_resource_variable, name_to_variable);
assert_eq!(metadata.integer_less_is_better, vec![true]);
let v = metadata.add_integer_resource_variable(String::from("u"), false);
assert!(v.is_ok());
let v = v.unwrap();
assert_eq!(v, IntegerResourceVariable(1));
assert_eq!(v.id(), 1);
assert_eq!(
metadata.integer_resource_variable_names,
vec![String::from("v"), String::from("u")]
);
name_to_variable.insert(String::from("u"), 1);
assert_eq!(metadata.name_to_integer_resource_variable, name_to_variable);
assert_eq!(metadata.integer_less_is_better, vec![true, false]);
}
#[test]
fn add_integer_resource_variable_err() {
let mut metadata = StateMetadata::default();
let v = metadata.add_integer_resource_variable(String::from("v"), true);
assert!(v.is_ok());
let v = metadata.add_integer_resource_variable(String::from("v"), false);
assert!(v.is_err());
assert_eq!(
metadata.integer_resource_variable_names,
vec![String::from("v")]
);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_integer_resource_variable, name_to_variable);
assert_eq!(metadata.integer_less_is_better, vec![true]);
}
#[test]
fn integer_resource_variable_preference_ok() {
let mut metadata = StateMetadata::default();
let v = metadata.add_integer_resource_variable(String::from("v"), true);
assert!(v.is_ok());
let v = v.unwrap();
let result = metadata.get_preference(v);
assert!(result.is_ok());
assert!(result.unwrap());
let result = metadata.set_preference(v, false);
assert!(result.is_ok());
assert_eq!(metadata.integer_less_is_better, vec![false]);
let result = metadata.get_preference(v);
assert!(result.is_ok());
assert!(!result.unwrap());
}
#[test]
fn integer_resource_variable_preference_err() {
let mut metadata = StateMetadata::default();
let v = metadata.add_integer_resource_variable(String::from("v"), true);
assert!(v.is_ok());
let mut metadata2 = StateMetadata::default();
let v = metadata2.add_integer_resource_variable(String::from("v"), true);
assert!(v.is_ok());
let v = metadata2.add_integer_resource_variable(String::from("u"), true);
assert!(v.is_ok());
let v = v.unwrap();
let result = metadata.get_preference(v);
assert!(result.is_err());
let result = metadata.set_preference(v, false);
assert!(result.is_err());
assert_eq!(metadata.integer_less_is_better, vec![true]);
}
#[test]
fn add_continuous_variable_ok() {
let mut metadata = StateMetadata::default();
let v = metadata.add_continuous_variable(String::from("v"));
assert!(v.is_ok());
let v = v.unwrap();
assert_eq!(v, ContinuousVariable(0));
assert_eq!(v.id(), 0);
assert_eq!(metadata.continuous_variable_names, vec![String::from("v")]);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_continuous_variable, name_to_variable);
let v = metadata.add_continuous_variable(String::from("u"));
assert!(v.is_ok());
let v = v.unwrap();
assert_eq!(v, ContinuousVariable(1));
assert_eq!(v.id(), 1);
assert_eq!(
metadata.continuous_variable_names,
vec![String::from("v"), String::from("u")]
);
name_to_variable.insert(String::from("u"), 1);
assert_eq!(metadata.name_to_continuous_variable, name_to_variable);
}
#[test]
fn add_continuous_variable_err() {
let mut metadata = StateMetadata::default();
let v = metadata.add_continuous_variable(String::from("v"));
assert!(v.is_ok());
let v = metadata.add_continuous_variable(String::from("v"));
assert!(v.is_err());
assert_eq!(metadata.continuous_variable_names, vec![String::from("v")]);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(metadata.name_to_continuous_variable, name_to_variable);
}
#[test]
fn add_continuous_resource_variable_ok() {
let mut metadata = StateMetadata::default();
let v = metadata.add_continuous_resource_variable(String::from("v"), true);
assert!(v.is_ok());
let v = v.unwrap();
assert_eq!(v, ContinuousResourceVariable(0));
assert_eq!(v.id(), 0);
assert_eq!(
metadata.continuous_resource_variable_names,
vec![String::from("v")]
);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(
metadata.name_to_continuous_resource_variable,
name_to_variable
);
assert_eq!(metadata.continuous_less_is_better, vec![true]);
let v = metadata.add_continuous_resource_variable(String::from("u"), false);
assert!(v.is_ok());
let v = v.unwrap();
assert_eq!(v, ContinuousResourceVariable(1));
assert_eq!(v.id(), 1);
assert_eq!(
metadata.continuous_resource_variable_names,
vec![String::from("v"), String::from("u")]
);
name_to_variable.insert(String::from("u"), 1);
assert_eq!(
metadata.name_to_continuous_resource_variable,
name_to_variable
);
assert_eq!(metadata.continuous_less_is_better, vec![true, false]);
}
#[test]
fn add_continuous_resource_variable_err() {
let mut metadata = StateMetadata::default();
let v = metadata.add_continuous_resource_variable(String::from("v"), true);
assert!(v.is_ok());
let v = metadata.add_continuous_resource_variable(String::from("v"), false);
assert!(v.is_err());
assert_eq!(
metadata.continuous_resource_variable_names,
vec![String::from("v")]
);
let mut name_to_variable = FxHashMap::default();
name_to_variable.insert(String::from("v"), 0);
assert_eq!(
metadata.name_to_continuous_resource_variable,
name_to_variable
);
assert_eq!(metadata.continuous_less_is_better, vec![true]);
}
#[test]
fn continuous_resource_variable_preference_ok() {
let mut metadata = StateMetadata::default();
let v = metadata.add_continuous_resource_variable(String::from("v"), true);
assert!(v.is_ok());
let v = v.unwrap();
let result = metadata.get_preference(v);
assert!(result.is_ok());
assert!(result.unwrap());
let result = metadata.set_preference(v, false);
assert!(result.is_ok());
assert_eq!(metadata.continuous_less_is_better, vec![false]);
let result = metadata.get_preference(v);
assert!(result.is_ok());
assert!(!result.unwrap());
}
#[test]
fn continuous_resource_variable_preference_err() {
let mut metadata = StateMetadata::default();
let v = metadata.add_continuous_resource_variable(String::from("v"), true);
assert!(v.is_ok());
let mut metadata2 = StateMetadata::default();
let v = metadata2.add_continuous_resource_variable(String::from("v"), true);
assert!(v.is_ok());
let v = metadata2.add_continuous_resource_variable(String::from("u"), true);
assert!(v.is_ok());
let v = v.unwrap();
let result = metadata.get_preference(v);
assert!(result.is_err());
let result = metadata.set_preference(v, false);
assert!(result.is_err());
assert_eq!(metadata.continuous_less_is_better, vec![true]);
}
}