1use crate::effect::Effect;
2use crate::expression::{
3 Condition, ContinuousExpression, ElementExpression, IntegerExpression, ReferenceExpression,
4 SetCondition, SetExpression, VectorExpression,
5};
6use crate::grounded_condition;
7use crate::state::{
8 ContinuousResourceVariable, ContinuousVariable, ElementResourceVariable, ElementVariable,
9 IntegerResourceVariable, IntegerVariable, SetVariable, State, StateInterface, VectorVariable,
10};
11use crate::state_functions::{StateFunctionCache, StateFunctions};
12use crate::table_registry;
13use crate::util::ModelErr;
14use crate::variable_type::{Continuous, Element, FromNumeric, Numeric};
15use std::fmt::Debug;
16
17#[derive(Debug, PartialEq, Clone)]
19pub enum CostExpression {
20 Integer(IntegerExpression),
22 Continuous(ContinuousExpression),
24}
25
26impl Default for CostExpression {
27 fn default() -> Self {
29 Self::Integer(IntegerExpression::Cost)
30 }
31}
32
33impl<T> From<T> for CostExpression
34where
35 IntegerExpression: From<T>,
36{
37 fn from(cost: T) -> Self {
38 Self::Integer(IntegerExpression::from(cost))
39 }
40}
41
42impl From<ContinuousExpression> for CostExpression {
43 fn from(cost: ContinuousExpression) -> Self {
44 Self::Continuous(cost)
45 }
46}
47
48impl From<Continuous> for CostExpression {
49 fn from(cost: Continuous) -> Self {
50 Self::from(ContinuousExpression::from(cost))
51 }
52}
53
54impl From<ContinuousVariable> for CostExpression {
55 fn from(cost: ContinuousVariable) -> Self {
56 Self::from(ContinuousExpression::from(cost))
57 }
58}
59
60impl From<ContinuousResourceVariable> for CostExpression {
61 fn from(cost: ContinuousResourceVariable) -> Self {
62 Self::from(ContinuousExpression::from(cost))
63 }
64}
65
66impl CostExpression {
67 #[inline]
92 pub fn eval<T: Numeric, U: StateInterface>(
93 &self,
94 state: &U,
95 function_cache: &mut StateFunctionCache,
96 state_functions: &StateFunctions,
97 registry: &table_registry::TableRegistry,
98 ) -> T {
99 match self {
100 Self::Integer(expression) => {
101 T::from(expression.eval(state, function_cache, state_functions, registry))
102 }
103 Self::Continuous(expression) => {
104 T::from(expression.eval(state, function_cache, state_functions, registry))
105 }
106 }
107 }
108
109 pub fn eval_cost<T: Numeric, U: StateInterface>(
133 &self,
134 cost: T,
135 state: &U,
136 function_cache: &mut StateFunctionCache,
137 state_functions: &StateFunctions,
138 registry: &table_registry::TableRegistry,
139 ) -> T {
140 match self {
141 Self::Integer(expression) => T::from(expression.eval_cost(
142 FromNumeric::from(cost),
143 state,
144 function_cache,
145 state_functions,
146 registry,
147 )),
148 Self::Continuous(expression) => T::from(expression.eval_cost(
149 FromNumeric::from(cost),
150 state,
151 function_cache,
152 state_functions,
153 registry,
154 )),
155 }
156 }
157
158 pub fn simplify(&self, registry: &table_registry::TableRegistry) -> CostExpression {
164 match self {
165 Self::Integer(expression) => Self::Integer(expression.simplify(registry)),
166 Self::Continuous(expression) => Self::Continuous(expression.simplify(registry)),
167 }
168 }
169}
170
171pub trait TransitionInterface {
173 fn is_applicable<T: StateInterface>(
175 &self,
176 state: &T,
177 function_cache: &mut StateFunctionCache,
178 state_functions: &StateFunctions,
179 registry: &table_registry::TableRegistry,
180 ) -> bool;
181
182 fn apply<S: StateInterface, T: From<State>>(
184 &self,
185 state: &S,
186 function_cache: &mut StateFunctionCache,
187 state_functions: &StateFunctions,
188 registry: &table_registry::TableRegistry,
189 ) -> T;
190
191 fn eval_cost<U: Numeric, T: StateInterface>(
193 &self,
194 cost: U,
195 state: &T,
196 function_cache: &mut StateFunctionCache,
197 state_functions: &StateFunctions,
198 registry: &table_registry::TableRegistry,
199 ) -> U;
200}
201
202#[derive(Debug, PartialEq, Clone, Default)]
204pub struct Transition {
205 pub name: String,
207 pub parameter_names: Vec<String>,
209 pub parameter_values: Vec<Element>,
211 pub elements_in_set_variable: Vec<(usize, Element)>,
214 pub elements_in_vector_variable: Vec<(usize, Element, usize)>,
217 pub preconditions: Vec<grounded_condition::GroundedCondition>,
219 pub effect: Effect,
221 pub cost: CostExpression,
223}
224
225impl TransitionInterface for Transition {
226 fn is_applicable<S: StateInterface>(
266 &self,
267 state: &S,
268 function_cache: &mut StateFunctionCache,
269 state_functions: &StateFunctions,
270 registry: &table_registry::TableRegistry,
271 ) -> bool {
272 for (i, v) in &self.elements_in_set_variable {
273 if !state.get_set_variable(*i).contains(*v) {
274 return false;
275 }
276 }
277 for (i, v, _) in &self.elements_in_vector_variable {
278 if !state.get_vector_variable(*i).contains(v) {
279 return false;
280 }
281 }
282 self.preconditions
283 .iter()
284 .all(|c| c.is_satisfied(state, function_cache, state_functions, registry))
285 }
286
287 #[inline]
311 fn apply<S: StateInterface, T: From<State>>(
312 &self,
313 state: &S,
314 function_cache: &mut StateFunctionCache,
315 state_functions: &StateFunctions,
316 registry: &table_registry::TableRegistry,
317 ) -> T {
318 state.apply_effect(&self.effect, function_cache, state_functions, registry)
319 }
320
321 #[inline]
347 fn eval_cost<T: Numeric, S: StateInterface>(
348 &self,
349 cost: T,
350 state: &S,
351 function_cache: &mut StateFunctionCache,
352 state_functions: &StateFunctions,
353 registry: &table_registry::TableRegistry,
354 ) -> T {
355 self.cost
356 .eval_cost(cost, state, function_cache, state_functions, registry)
357 }
358}
359
360impl Transition {
361 pub fn get_full_name(&self) -> String {
372 let mut full_name = self.name.clone();
373 for (name, value) in self
374 .parameter_names
375 .iter()
376 .zip(self.parameter_values.iter())
377 {
378 full_name += format!(" {name}:{value}").as_str();
379 }
380 full_name
381 }
382
383 pub fn new<T>(name: T) -> Transition
385 where
386 String: From<T>,
387 {
388 Transition {
389 name: String::from(name),
390 ..Default::default()
391 }
392 }
393
394 pub fn set_cost<T>(&mut self, cost: T)
404 where
405 CostExpression: From<T>,
406 {
407 self.cost = CostExpression::from(cost)
408 }
409
410 pub fn get_preconditions(&self) -> Vec<Condition> {
437 let mut result = Vec::with_capacity(
438 self.elements_in_set_variable.len()
439 + self.elements_in_vector_variable.len()
440 + self.preconditions.len(),
441 );
442
443 for (i, e) in &self.elements_in_set_variable {
444 result.push(Condition::Set(Box::new(SetCondition::IsIn(
445 ElementExpression::Constant(*e),
446 SetExpression::Reference(ReferenceExpression::Variable(*i)),
447 ))));
448 }
449
450 for (i, e, capacity) in &self.elements_in_vector_variable {
451 result.push(Condition::Set(Box::new(SetCondition::IsIn(
452 ElementExpression::Constant(*e),
453 SetExpression::FromVector(
454 *capacity,
455 Box::new(VectorExpression::Reference(ReferenceExpression::Variable(
456 *i,
457 ))),
458 ),
459 ))));
460 }
461
462 for condition in &self.preconditions {
463 result.push(Condition::from(condition.clone()));
464 }
465
466 result
467 }
468
469 pub fn add_precondition(&mut self, condition: Condition) {
485 match &condition {
486 Condition::Set(condition) => match condition.as_ref() {
487 SetCondition::IsIn(
488 ElementExpression::Constant(e),
489 SetExpression::Reference(ReferenceExpression::Variable(i)),
490 ) => {
491 self.elements_in_set_variable.push((*i, *e));
492 return;
493 }
494 SetCondition::IsIn(
495 ElementExpression::Constant(e),
496 SetExpression::FromVector(capacity, v),
497 ) => {
498 if let VectorExpression::Reference(ReferenceExpression::Variable(i)) =
499 v.as_ref()
500 {
501 self.elements_in_vector_variable.push((*i, *e, *capacity));
502 return;
503 }
504 }
505 _ => {}
506 },
507 Condition::Constant(true) => {
508 eprintln!("a precondition is always satisfied");
509 }
510 Condition::Constant(false) => {
511 eprintln!("a precondition is never satisfied");
512 }
513 _ => {}
514 }
515 self.preconditions
516 .push(grounded_condition::GroundedCondition::from(condition))
517 }
518}
519
520pub trait AddEffect<T, U> {
534 fn add_effect<V>(&mut self, v: T, expression: V) -> Result<(), ModelErr>
540 where
541 U: From<V>;
542}
543
544macro_rules! impl_add_effect {
545 ($T:ty,$U:ty,$x:ident) => {
546 impl AddEffect<$T, $U> for Transition {
547 fn add_effect<V>(&mut self, v: $T, expression: V) -> Result<(), ModelErr>
548 where
549 $U: From<V>,
550 {
551 let expression = <$U>::from(expression);
552 let mut index = None;
553 for (j, (i, _)) in self.effect.$x.iter().enumerate() {
554 if *i == v.id() {
555 return Err(ModelErr::new(format!(
556 "the transition already has an effect on variable id {i}",
557 )));
558 }
559
560 if *i > v.id() {
561 index = Some(j);
562 break;
563 }
564 }
565
566 if let Some(index) = index {
567 self.effect.$x.insert(index, (v.id(), expression));
568 } else {
569 self.effect.$x.push((v.id(), expression));
570 }
571
572 Ok(())
573 }
574 }
575 };
576}
577
578impl_add_effect!(SetVariable, SetExpression, set_effects);
579impl_add_effect!(VectorVariable, VectorExpression, vector_effects);
580impl_add_effect!(ElementVariable, ElementExpression, element_effects);
581impl_add_effect!(
582 ElementResourceVariable,
583 ElementExpression,
584 element_resource_effects
585);
586impl_add_effect!(IntegerVariable, IntegerExpression, integer_effects);
587impl_add_effect!(
588 IntegerResourceVariable,
589 IntegerExpression,
590 integer_resource_effects
591);
592impl_add_effect!(ContinuousVariable, ContinuousExpression, continuous_effects);
593impl_add_effect!(
594 ContinuousResourceVariable,
595 ContinuousExpression,
596 continuous_resource_effects
597);
598
599#[cfg(test)]
600mod tests {
601 use super::*;
602 use crate::expression::*;
603 use crate::state;
604 use crate::table;
605 use crate::table_data;
606 use crate::variable_type::*;
607 use crate::StateMetadata;
608 use rustc_hash::FxHashMap;
609
610 fn generate_registry() -> table_registry::TableRegistry {
611 let tables_1d = vec![table::Table1D::new(vec![10, 20, 30])];
612 let mut name_to_table_1d = FxHashMap::default();
613 name_to_table_1d.insert(String::from("f1"), 0);
614
615 let tables_2d = vec![table::Table2D::new(vec![
616 vec![10, 20, 30],
617 vec![40, 50, 60],
618 ])];
619 let mut name_to_table_2d = FxHashMap::default();
620 name_to_table_2d.insert(String::from("f2"), 0);
621
622 table_registry::TableRegistry {
623 integer_tables: table_data::TableData {
624 tables_1d,
625 name_to_table_1d,
626 tables_2d,
627 name_to_table_2d,
628 ..Default::default()
629 },
630 ..Default::default()
631 }
632 }
633
634 fn generate_state() -> state::State {
635 let mut set1 = Set::with_capacity(3);
636 set1.insert(0);
637 set1.insert(2);
638 let mut set2 = Set::with_capacity(3);
639 set2.insert(0);
640 set2.insert(1);
641 state::State {
642 signature_variables: state::SignatureVariables {
643 set_variables: vec![set1, set2],
644 vector_variables: vec![vec![0, 2], vec![1, 2]],
645 element_variables: vec![1, 2],
646 integer_variables: vec![1, 2, 3],
647 continuous_variables: vec![1.0, 2.0, 3.0],
648 },
649 resource_variables: state::ResourceVariables {
650 element_variables: vec![0, 1],
651 integer_variables: vec![4, 5, 6],
652 continuous_variables: vec![4.0, 5.0, 6.0],
653 },
654 }
655 }
656
657 #[test]
658 fn cost_expression_default() {
659 let expression = CostExpression::default();
660 assert_eq!(expression, CostExpression::Integer(IntegerExpression::Cost));
661 }
662
663 #[test]
664 fn cost_expression_from_integer() {
665 let expression = CostExpression::from(IntegerExpression::Cost);
666 assert_eq!(expression, CostExpression::Integer(IntegerExpression::Cost));
667 }
668
669 #[test]
670 fn cost_expression_from_continuous_expression() {
671 let expression = CostExpression::from(ContinuousExpression::Cost);
672 assert_eq!(
673 expression,
674 CostExpression::Continuous(ContinuousExpression::Cost)
675 );
676 }
677
678 #[test]
679 fn cost_expression_from_continuous() {
680 let expression = CostExpression::from(1.0);
681 assert_eq!(
682 expression,
683 CostExpression::Continuous(ContinuousExpression::Constant(1.0))
684 );
685 }
686
687 #[test]
688 fn cost_expression_from_continuous_variable() {
689 let mut metadata = StateMetadata::default();
690 let var = metadata.add_continuous_variable("var");
691 assert!(var.is_ok());
692 let var = var.unwrap();
693 let expression = CostExpression::from(var);
694 assert_eq!(
695 expression,
696 CostExpression::Continuous(ContinuousExpression::Variable(0))
697 );
698 }
699
700 #[test]
701 fn cost_expression_from_continuous_resource_variable() {
702 let mut metadata = StateMetadata::default();
703 let var = metadata.add_continuous_resource_variable("var", false);
704 assert!(var.is_ok());
705 let var = var.unwrap();
706 let expression = CostExpression::from(var);
707 assert_eq!(
708 expression,
709 CostExpression::Continuous(ContinuousExpression::ResourceVariable(0))
710 );
711 }
712
713 #[test]
714 fn cost_expression_eval() {
715 let state = generate_state();
716 let state_functions = StateFunctions::default();
717 let mut function_cache = StateFunctionCache::new(&state_functions);
718 let registry = generate_registry();
719
720 let expression = CostExpression::Integer(IntegerExpression::BinaryOperation(
721 BinaryOperator::Add,
722 Box::new(IntegerExpression::Constant(1)),
723 Box::new(IntegerExpression::Constant(1)),
724 ));
725 assert_eq!(
726 expression.eval_cost(0, &state, &mut function_cache, &state_functions, ®istry),
727 2
728 );
729
730 let expression = CostExpression::Continuous(ContinuousExpression::BinaryOperation(
731 BinaryOperator::Add,
732 Box::new(ContinuousExpression::Constant(1.0)),
733 Box::new(ContinuousExpression::Constant(1.0)),
734 ));
735 assert_eq!(
736 expression.eval_cost(
737 0.0,
738 &state,
739 &mut function_cache,
740 &state_functions,
741 ®istry
742 ),
743 2.0
744 );
745 }
746
747 #[test]
748 fn cost_expression_eval_cost() {
749 let state = generate_state();
750 let state_functions = StateFunctions::default();
751 let mut function_cache = StateFunctionCache::new(&state_functions);
752 let registry = generate_registry();
753
754 let expression = CostExpression::Integer(IntegerExpression::BinaryOperation(
755 BinaryOperator::Add,
756 Box::new(IntegerExpression::Cost),
757 Box::new(IntegerExpression::Constant(1)),
758 ));
759 assert_eq!(
760 expression.eval_cost(0, &state, &mut function_cache, &state_functions, ®istry),
761 1
762 );
763
764 let expression = CostExpression::Continuous(ContinuousExpression::BinaryOperation(
765 BinaryOperator::Add,
766 Box::new(ContinuousExpression::Cost),
767 Box::new(ContinuousExpression::Constant(1.0)),
768 ));
769 assert_eq!(
770 expression.eval_cost(
771 0.0,
772 &state,
773 &mut function_cache,
774 &state_functions,
775 ®istry
776 ),
777 1.0
778 );
779 }
780
781 #[test]
782 fn cost_expression_simplify_integer() {
783 let registry = generate_registry();
784 let expression = CostExpression::Integer(IntegerExpression::BinaryOperation(
785 BinaryOperator::Add,
786 Box::new(IntegerExpression::Constant(1)),
787 Box::new(IntegerExpression::Constant(1)),
788 ));
789 assert_eq!(
790 expression.simplify(®istry),
791 CostExpression::Integer(IntegerExpression::Constant(2))
792 )
793 }
794
795 #[test]
796 fn cost_expression_simplify_continuous() {
797 let registry = generate_registry();
798 let expression = CostExpression::Continuous(ContinuousExpression::BinaryOperation(
799 BinaryOperator::Add,
800 Box::new(ContinuousExpression::Constant(1.0)),
801 Box::new(ContinuousExpression::Constant(1.0)),
802 ));
803 assert_eq!(
804 expression.simplify(®istry),
805 CostExpression::Continuous(ContinuousExpression::Constant(2.0))
806 )
807 }
808
809 #[test]
810 fn applicable() {
811 let state = generate_state();
812 let state_functions = StateFunctions::default();
813 let mut function_cache = StateFunctionCache::new(&state_functions);
814 let registry = generate_registry();
815 let set_condition = grounded_condition::GroundedCondition {
816 condition: Condition::Set(Box::new(SetCondition::IsIn(
817 ElementExpression::Constant(0),
818 SetExpression::Reference(ReferenceExpression::Variable(0)),
819 ))),
820 ..Default::default()
821 };
822 let numeric_condition = grounded_condition::GroundedCondition {
823 condition: Condition::ComparisonI(
824 ComparisonOperator::Ge,
825 Box::new(IntegerExpression::Variable(0)),
826 Box::new(IntegerExpression::Constant(1)),
827 ),
828 ..Default::default()
829 };
830
831 let transition = Transition {
832 name: String::from(""),
833 preconditions: vec![set_condition, numeric_condition],
834 cost: CostExpression::Integer(IntegerExpression::Constant(0)),
835 ..Default::default()
836 };
837 assert!(transition.is_applicable(&state, &mut function_cache, &state_functions, ®istry));
838
839 let transition = Transition {
840 name: String::from(""),
841 elements_in_set_variable: vec![(0, 0), (1, 1)],
842 elements_in_vector_variable: vec![(0, 0, 3), (1, 2, 3)],
843 cost: CostExpression::Integer(IntegerExpression::Constant(0)),
844 ..Default::default()
845 };
846 assert!(transition.is_applicable(&state, &mut function_cache, &state_functions, ®istry));
847 }
848
849 #[test]
850 fn not_applicable() {
851 let state = generate_state();
852 let registry = generate_registry();
853 let state_functions = StateFunctions::default();
854 let mut function_cache = StateFunctionCache::new(&state_functions);
855 let set_condition = grounded_condition::GroundedCondition {
856 condition: Condition::Set(Box::new(SetCondition::IsIn(
857 ElementExpression::Constant(0),
858 SetExpression::Reference(ReferenceExpression::Variable(0)),
859 ))),
860 ..Default::default()
861 };
862 let numeric_condition = grounded_condition::GroundedCondition {
863 condition: Condition::ComparisonI(
864 ComparisonOperator::Le,
865 Box::new(IntegerExpression::Variable(0)),
866 Box::new(IntegerExpression::Constant(1)),
867 ),
868 ..Default::default()
869 };
870
871 let transition = Transition {
872 name: String::from(""),
873 preconditions: vec![set_condition, numeric_condition],
874 cost: CostExpression::Integer(IntegerExpression::Constant(0)),
875 ..Default::default()
876 };
877 assert!(transition.is_applicable(&state, &mut function_cache, &state_functions, ®istry));
878
879 let transition = Transition {
880 name: String::from(""),
881 elements_in_set_variable: vec![(0, 1), (1, 1)],
882 elements_in_vector_variable: vec![(0, 0, 3), (1, 2, 3)],
883 cost: CostExpression::Integer(IntegerExpression::Constant(0)),
884 ..Default::default()
885 };
886 assert!(!transition.is_applicable(
887 &state,
888 &mut function_cache,
889 &state_functions,
890 ®istry
891 ));
892
893 let transition = Transition {
894 name: String::from(""),
895 elements_in_set_variable: vec![(0, 1), (1, 1)],
896 elements_in_vector_variable: vec![(0, 1, 3), (1, 2, 3)],
897 cost: CostExpression::Integer(IntegerExpression::Constant(0)),
898 ..Default::default()
899 };
900 assert!(!transition.is_applicable(
901 &state,
902 &mut function_cache,
903 &state_functions,
904 ®istry
905 ));
906 }
907
908 #[test]
909 fn apply_effects() {
910 let state = generate_state();
911 let state_functions = StateFunctions::default();
912 let mut function_cache = StateFunctionCache::new(&state_functions);
913 let registry = generate_registry();
914 let set_effect1 = SetExpression::SetElementOperation(
915 SetElementOperator::Add,
916 ElementExpression::Constant(1),
917 Box::new(SetExpression::Reference(ReferenceExpression::Variable(0))),
918 );
919 let set_effect2 = SetExpression::SetElementOperation(
920 SetElementOperator::Remove,
921 ElementExpression::Constant(0),
922 Box::new(SetExpression::Reference(ReferenceExpression::Variable(1))),
923 );
924 let vector_effect1 = VectorExpression::Push(
925 ElementExpression::Constant(1),
926 Box::new(VectorExpression::Reference(ReferenceExpression::Variable(
927 0,
928 ))),
929 );
930 let vector_effect2 = VectorExpression::Push(
931 ElementExpression::Constant(0),
932 Box::new(VectorExpression::Reference(ReferenceExpression::Variable(
933 1,
934 ))),
935 );
936 let element_effect1 = ElementExpression::Constant(2);
937 let element_effect2 = ElementExpression::Constant(1);
938 let integer_effect1 = IntegerExpression::BinaryOperation(
939 BinaryOperator::Sub,
940 Box::new(IntegerExpression::Variable(0)),
941 Box::new(IntegerExpression::Constant(1)),
942 );
943 let integer_effect2 = IntegerExpression::BinaryOperation(
944 BinaryOperator::Mul,
945 Box::new(IntegerExpression::Variable(1)),
946 Box::new(IntegerExpression::Constant(2)),
947 );
948 let continuous_effect1 = ContinuousExpression::BinaryOperation(
949 BinaryOperator::Sub,
950 Box::new(ContinuousExpression::Variable(0)),
951 Box::new(ContinuousExpression::Constant(1.0)),
952 );
953 let continuous_effect2 = ContinuousExpression::BinaryOperation(
954 BinaryOperator::Mul,
955 Box::new(ContinuousExpression::Variable(1)),
956 Box::new(ContinuousExpression::Constant(2.0)),
957 );
958 let element_resource_effect1 = ElementExpression::Constant(1);
959 let element_resource_effect2 = ElementExpression::Constant(0);
960 let integer_resource_effect1 = IntegerExpression::BinaryOperation(
961 BinaryOperator::Add,
962 Box::new(IntegerExpression::ResourceVariable(0)),
963 Box::new(IntegerExpression::Constant(1)),
964 );
965 let integer_resource_effect2 = IntegerExpression::BinaryOperation(
966 BinaryOperator::Div,
967 Box::new(IntegerExpression::ResourceVariable(1)),
968 Box::new(IntegerExpression::Constant(2)),
969 );
970 let continuous_resource_effect1 = ContinuousExpression::BinaryOperation(
971 BinaryOperator::Add,
972 Box::new(ContinuousExpression::ResourceVariable(0)),
973 Box::new(ContinuousExpression::Constant(1.0)),
974 );
975 let continuous_resource_effect2 = ContinuousExpression::BinaryOperation(
976 BinaryOperator::Div,
977 Box::new(ContinuousExpression::ResourceVariable(1)),
978 Box::new(ContinuousExpression::Constant(2.0)),
979 );
980 let transition = Transition {
981 name: String::from(""),
982 effect: Effect {
983 set_effects: vec![(0, set_effect1), (1, set_effect2)],
984 vector_effects: vec![(0, vector_effect1), (1, vector_effect2)],
985 element_effects: vec![(0, element_effect1), (1, element_effect2)],
986 integer_effects: vec![(0, integer_effect1), (1, integer_effect2)],
987 continuous_effects: vec![(0, continuous_effect1), (1, continuous_effect2)],
988 element_resource_effects: vec![
989 (0, element_resource_effect1),
990 (1, element_resource_effect2),
991 ],
992 integer_resource_effects: vec![
993 (0, integer_resource_effect1),
994 (1, integer_resource_effect2),
995 ],
996 continuous_resource_effects: vec![
997 (0, continuous_resource_effect1),
998 (1, continuous_resource_effect2),
999 ],
1000 },
1001 cost: CostExpression::Integer(IntegerExpression::BinaryOperation(
1002 BinaryOperator::Add,
1003 Box::new(IntegerExpression::Cost),
1004 Box::new(IntegerExpression::Constant(1)),
1005 )),
1006 ..Default::default()
1007 };
1008
1009 let mut set1 = Set::with_capacity(3);
1010 set1.insert(0);
1011 set1.insert(1);
1012 set1.insert(2);
1013 let mut set2 = Set::with_capacity(3);
1014 set2.insert(1);
1015 let expected = state::State {
1016 signature_variables: state::SignatureVariables {
1017 set_variables: vec![set1, set2],
1018 vector_variables: vec![vec![0, 2, 1], vec![1, 2, 0]],
1019 element_variables: vec![2, 1],
1020 integer_variables: vec![0, 4, 3],
1021 continuous_variables: vec![0.0, 4.0, 3.0],
1022 },
1023 resource_variables: state::ResourceVariables {
1024 element_variables: vec![1, 0],
1025 integer_variables: vec![5, 2, 6],
1026 continuous_variables: vec![5.0, 2.5, 6.0],
1027 },
1028 };
1029 let successor: State =
1030 transition.apply(&state, &mut function_cache, &state_functions, ®istry);
1031 assert_eq!(successor, expected);
1032 }
1033
1034 #[test]
1035 fn eval_cost() {
1036 let state = generate_state();
1037 let state_functions = StateFunctions::default();
1038 let mut function_cache = StateFunctionCache::new(&state_functions);
1039 let registry = generate_registry();
1040
1041 let transition = Transition {
1042 cost: CostExpression::Integer(IntegerExpression::BinaryOperation(
1043 BinaryOperator::Add,
1044 Box::new(IntegerExpression::Cost),
1045 Box::new(IntegerExpression::Constant(1)),
1046 )),
1047 ..Default::default()
1048 };
1049 assert_eq!(
1050 transition.eval_cost(0, &state, &mut function_cache, &state_functions, ®istry),
1051 1
1052 );
1053
1054 let transition = Transition {
1055 cost: CostExpression::Continuous(ContinuousExpression::BinaryOperation(
1056 BinaryOperator::Add,
1057 Box::new(ContinuousExpression::Cost),
1058 Box::new(ContinuousExpression::Constant(1.0)),
1059 )),
1060 ..Default::default()
1061 };
1062 assert_eq!(
1063 transition.eval_cost(
1064 0.0,
1065 &state,
1066 &mut function_cache,
1067 &state_functions,
1068 ®istry
1069 ),
1070 1.0
1071 );
1072 }
1073
1074 #[test]
1075 fn get_full_name() {
1076 let transition = Transition {
1077 name: String::from("transition"),
1078 parameter_names: vec![String::from("param1"), String::from("param2")],
1079 parameter_values: vec![0, 1],
1080 ..Default::default()
1081 };
1082 assert_eq!(
1083 transition.get_full_name(),
1084 String::from("transition param1:0 param2:1")
1085 );
1086 }
1087
1088 #[test]
1089 fn new() {
1090 let transition = Transition::new("t");
1091 assert_eq!(
1092 transition,
1093 Transition {
1094 name: String::from("t"),
1095 ..Default::default()
1096 }
1097 );
1098 }
1099
1100 #[test]
1101 fn set_cost() {
1102 let mut transition = Transition::default();
1103 transition.set_cost(ContinuousExpression::Cost);
1104 assert_eq!(
1105 transition,
1106 Transition {
1107 cost: CostExpression::Continuous(ContinuousExpression::Cost),
1108 ..Default::default()
1109 }
1110 );
1111 }
1112
1113 #[test]
1114 fn get_preconditions() {
1115 let transition = Transition {
1116 elements_in_set_variable: vec![(0, 1), (1, 2)],
1117 elements_in_vector_variable: vec![(2, 3, 4), (3, 4, 5)],
1118 preconditions: vec![
1119 grounded_condition::GroundedCondition {
1120 condition: Condition::Set(Box::new(SetCondition::IsIn(
1121 ElementExpression::Variable(0),
1122 SetExpression::Reference(ReferenceExpression::Variable(0)),
1123 ))),
1124 ..Default::default()
1125 },
1126 grounded_condition::GroundedCondition {
1127 condition: Condition::Set(Box::new(SetCondition::IsIn(
1128 ElementExpression::Variable(1),
1129 SetExpression::Reference(ReferenceExpression::Variable(1)),
1130 ))),
1131 ..Default::default()
1132 },
1133 ],
1134 ..Default::default()
1135 };
1136 assert_eq!(
1137 transition.get_preconditions(),
1138 vec![
1139 Condition::Set(Box::new(SetCondition::IsIn(
1140 ElementExpression::Constant(1),
1141 SetExpression::Reference(ReferenceExpression::Variable(0)),
1142 ))),
1143 Condition::Set(Box::new(SetCondition::IsIn(
1144 ElementExpression::Constant(2),
1145 SetExpression::Reference(ReferenceExpression::Variable(1)),
1146 ))),
1147 Condition::Set(Box::new(SetCondition::IsIn(
1148 ElementExpression::Constant(3),
1149 SetExpression::FromVector(
1150 4,
1151 Box::new(VectorExpression::Reference(ReferenceExpression::Variable(
1152 2
1153 )))
1154 ),
1155 ))),
1156 Condition::Set(Box::new(SetCondition::IsIn(
1157 ElementExpression::Constant(4),
1158 SetExpression::FromVector(
1159 5,
1160 Box::new(VectorExpression::Reference(ReferenceExpression::Variable(
1161 3
1162 )))
1163 ),
1164 ))),
1165 Condition::Set(Box::new(SetCondition::IsIn(
1166 ElementExpression::Variable(0),
1167 SetExpression::Reference(ReferenceExpression::Variable(0)),
1168 ))),
1169 Condition::Set(Box::new(SetCondition::IsIn(
1170 ElementExpression::Variable(1),
1171 SetExpression::Reference(ReferenceExpression::Variable(1)),
1172 ))),
1173 ]
1174 );
1175 }
1176
1177 #[test]
1178 fn add_precondition() {
1179 let mut transition = Transition::default();
1180 transition.add_precondition(Condition::Set(Box::new(SetCondition::IsIn(
1181 ElementExpression::Constant(0),
1182 SetExpression::Reference(ReferenceExpression::Variable(0)),
1183 ))));
1184 assert_eq!(
1185 transition,
1186 Transition {
1187 elements_in_set_variable: vec![(0, 0)],
1188 ..Default::default()
1189 }
1190 );
1191 transition.add_precondition(Condition::Set(Box::new(SetCondition::IsIn(
1192 ElementExpression::Constant(1),
1193 SetExpression::Reference(ReferenceExpression::Variable(1)),
1194 ))));
1195 assert_eq!(
1196 transition,
1197 Transition {
1198 elements_in_set_variable: vec![(0, 0), (1, 1)],
1199 ..Default::default()
1200 }
1201 );
1202 transition.add_precondition(Condition::Set(Box::new(SetCondition::IsIn(
1203 ElementExpression::Constant(0),
1204 SetExpression::FromVector(
1205 10,
1206 Box::new(VectorExpression::Reference(ReferenceExpression::Variable(
1207 0,
1208 ))),
1209 ),
1210 ))));
1211 assert_eq!(
1212 transition,
1213 Transition {
1214 elements_in_set_variable: vec![(0, 0), (1, 1)],
1215 elements_in_vector_variable: vec![(0, 0, 10)],
1216 ..Default::default()
1217 }
1218 );
1219 transition.add_precondition(Condition::Set(Box::new(SetCondition::IsIn(
1220 ElementExpression::Constant(1),
1221 SetExpression::FromVector(
1222 10,
1223 Box::new(VectorExpression::Reference(ReferenceExpression::Variable(
1224 1,
1225 ))),
1226 ),
1227 ))));
1228 assert_eq!(
1229 transition,
1230 Transition {
1231 elements_in_set_variable: vec![(0, 0), (1, 1)],
1232 elements_in_vector_variable: vec![(0, 0, 10), (1, 1, 10)],
1233 ..Default::default()
1234 }
1235 );
1236 transition.add_precondition(Condition::ComparisonE(
1237 ComparisonOperator::Eq,
1238 Box::new(ElementExpression::Variable(0)),
1239 Box::new(ElementExpression::Constant(0)),
1240 ));
1241 assert_eq!(
1242 transition,
1243 Transition {
1244 elements_in_set_variable: vec![(0, 0), (1, 1)],
1245 elements_in_vector_variable: vec![(0, 0, 10), (1, 1, 10)],
1246 preconditions: vec![grounded_condition::GroundedCondition {
1247 condition: Condition::ComparisonE(
1248 ComparisonOperator::Eq,
1249 Box::new(ElementExpression::Variable(0)),
1250 Box::new(ElementExpression::Constant(0))
1251 ),
1252 ..Default::default()
1253 }],
1254 ..Default::default()
1255 }
1256 );
1257 transition.add_precondition(Condition::ComparisonE(
1258 ComparisonOperator::Eq,
1259 Box::new(ElementExpression::Variable(1)),
1260 Box::new(ElementExpression::Constant(1)),
1261 ));
1262 assert_eq!(
1263 transition,
1264 Transition {
1265 elements_in_set_variable: vec![(0, 0), (1, 1)],
1266 elements_in_vector_variable: vec![(0, 0, 10), (1, 1, 10)],
1267 preconditions: vec![
1268 grounded_condition::GroundedCondition {
1269 condition: Condition::ComparisonE(
1270 ComparisonOperator::Eq,
1271 Box::new(ElementExpression::Variable(0)),
1272 Box::new(ElementExpression::Constant(0))
1273 ),
1274 ..Default::default()
1275 },
1276 grounded_condition::GroundedCondition {
1277 condition: Condition::ComparisonE(
1278 ComparisonOperator::Eq,
1279 Box::new(ElementExpression::Variable(1)),
1280 Box::new(ElementExpression::Constant(1))
1281 ),
1282 ..Default::default()
1283 },
1284 ],
1285 ..Default::default()
1286 }
1287 );
1288 }
1289
1290 #[test]
1291 fn add_set_effect_ok() {
1292 let mut metadata = state::StateMetadata::default();
1293 let ob = metadata.add_object_type(String::from("something"), 10);
1294 assert!(ob.is_ok());
1295 let ob = ob.unwrap();
1296 let v1 = metadata.add_set_variable(String::from("v1"), ob);
1297 assert!(v1.is_ok());
1298 let v1 = v1.unwrap();
1299 let v2 = metadata.add_set_variable(String::from("v2"), ob);
1300 assert!(v2.is_ok());
1301 let v2 = v2.unwrap();
1302 let v3 = metadata.add_set_variable(String::from("v3"), ob);
1303 assert!(v3.is_ok());
1304 let v3 = v3.unwrap();
1305 let v4 = metadata.add_set_variable(String::from("v4"), ob);
1306 assert!(v4.is_ok());
1307 let v4 = v4.unwrap();
1308
1309 let mut transition = Transition::default();
1310 let mut effect = Set::with_capacity(10);
1311 effect.insert(1);
1312 let result = transition.add_effect(v3, effect);
1313 assert!(result.is_ok());
1314 assert_eq!(
1315 transition,
1316 Transition {
1317 effect: Effect {
1318 set_effects: vec![(
1319 v3.id(),
1320 SetExpression::Reference(ReferenceExpression::Constant({
1321 let mut set = Set::with_capacity(10);
1322 set.insert(1);
1323 set
1324 }))
1325 )],
1326 ..Default::default()
1327 },
1328 ..Default::default()
1329 },
1330 );
1331 let result = transition.add_effect(v1, Set::with_capacity(10));
1332 assert!(result.is_ok());
1333 assert_eq!(
1334 transition,
1335 Transition {
1336 effect: Effect {
1337 set_effects: vec![
1338 (
1339 v1.id(),
1340 SetExpression::Reference(ReferenceExpression::Constant(
1341 Set::with_capacity(10)
1342 ))
1343 ),
1344 (
1345 v3.id(),
1346 SetExpression::Reference(ReferenceExpression::Constant({
1347 let mut set = Set::with_capacity(10);
1348 set.insert(1);
1349 set
1350 }))
1351 )
1352 ],
1353 ..Default::default()
1354 },
1355 ..Default::default()
1356 },
1357 );
1358 let result = transition.add_effect(v2, v1);
1359 assert!(result.is_ok());
1360 assert_eq!(
1361 transition,
1362 Transition {
1363 effect: Effect {
1364 set_effects: vec![
1365 (
1366 v1.id(),
1367 SetExpression::Reference(ReferenceExpression::Constant(
1368 Set::with_capacity(10)
1369 ))
1370 ),
1371 (
1372 v2.id(),
1373 SetExpression::Reference(ReferenceExpression::Variable(v1.id()))
1374 ),
1375 (
1376 v3.id(),
1377 SetExpression::Reference(ReferenceExpression::Constant({
1378 let mut set = Set::with_capacity(10);
1379 set.insert(1);
1380 set
1381 }))
1382 )
1383 ],
1384 ..Default::default()
1385 },
1386 ..Default::default()
1387 },
1388 );
1389 let result = transition.add_effect(v4, v2);
1390 assert!(result.is_ok());
1391 assert_eq!(
1392 transition,
1393 Transition {
1394 effect: Effect {
1395 set_effects: vec![
1396 (
1397 v1.id(),
1398 SetExpression::Reference(ReferenceExpression::Constant(
1399 Set::with_capacity(10)
1400 ))
1401 ),
1402 (
1403 v2.id(),
1404 SetExpression::Reference(ReferenceExpression::Variable(v1.id()))
1405 ),
1406 (
1407 v3.id(),
1408 SetExpression::Reference(ReferenceExpression::Constant({
1409 let mut set = Set::with_capacity(10);
1410 set.insert(1);
1411 set
1412 }))
1413 ),
1414 (
1415 v4.id(),
1416 SetExpression::Reference(ReferenceExpression::Variable(v2.id()))
1417 ),
1418 ],
1419 ..Default::default()
1420 },
1421 ..Default::default()
1422 },
1423 );
1424 }
1425
1426 #[test]
1427 fn add_set_effect_err() {
1428 let mut metadata = state::StateMetadata::default();
1429 let ob = metadata.add_object_type(String::from("something"), 10);
1430 assert!(ob.is_ok());
1431 let ob = ob.unwrap();
1432 let v = metadata.add_set_variable(String::from("v"), ob);
1433 assert!(v.is_ok());
1434 let v = v.unwrap();
1435
1436 let mut transition = Transition::default();
1437 let result = transition.add_effect(v, Set::with_capacity(10));
1438 assert!(result.is_ok());
1439 let result = transition.add_effect(v, Set::with_capacity(10));
1440 assert!(result.is_err());
1441 }
1442
1443 #[test]
1444 fn add_vector_effect_ok() {
1445 let mut metadata = state::StateMetadata::default();
1446 let ob = metadata.add_object_type(String::from("something"), 10);
1447 assert!(ob.is_ok());
1448 let ob = ob.unwrap();
1449 let v1 = metadata.add_vector_variable(String::from("v1"), ob);
1450 assert!(v1.is_ok());
1451 let v1 = v1.unwrap();
1452 let v2 = metadata.add_vector_variable(String::from("v2"), ob);
1453 assert!(v2.is_ok());
1454 let v2 = v2.unwrap();
1455 let v3 = metadata.add_vector_variable(String::from("v3"), ob);
1456 assert!(v3.is_ok());
1457 let v3 = v3.unwrap();
1458 let v4 = metadata.add_vector_variable(String::from("v4"), ob);
1459 assert!(v4.is_ok());
1460 let v4 = v4.unwrap();
1461
1462 let mut transition = Transition::default();
1463 let result = transition.add_effect(
1464 v3,
1465 VectorExpression::Reference(ReferenceExpression::Constant(vec![])),
1466 );
1467 assert!(result.is_ok());
1468 assert_eq!(
1469 transition,
1470 Transition {
1471 effect: Effect {
1472 vector_effects: vec![(
1473 v3.id(),
1474 VectorExpression::Reference(ReferenceExpression::Constant(vec![]))
1475 )],
1476 ..Default::default()
1477 },
1478 ..Default::default()
1479 },
1480 );
1481 let result = transition.add_effect(
1482 v1,
1483 VectorExpression::Reference(ReferenceExpression::Constant(vec![1, 2])),
1484 );
1485 assert!(result.is_ok());
1486 assert_eq!(
1487 transition,
1488 Transition {
1489 effect: Effect {
1490 vector_effects: vec![
1491 (
1492 v1.id(),
1493 VectorExpression::Reference(ReferenceExpression::Constant(vec![1, 2]))
1494 ),
1495 (
1496 v3.id(),
1497 VectorExpression::Reference(ReferenceExpression::Constant(vec![]))
1498 )
1499 ],
1500 ..Default::default()
1501 },
1502 ..Default::default()
1503 },
1504 );
1505 let result = transition.add_effect(
1506 v2,
1507 VectorExpression::Reference(ReferenceExpression::Variable(v1.id())),
1508 );
1509 assert!(result.is_ok());
1510 assert_eq!(
1511 transition,
1512 Transition {
1513 effect: Effect {
1514 vector_effects: vec![
1515 (
1516 v1.id(),
1517 VectorExpression::Reference(ReferenceExpression::Constant(vec![1, 2]))
1518 ),
1519 (
1520 v2.id(),
1521 VectorExpression::Reference(ReferenceExpression::Variable(v1.id()))
1522 ),
1523 (
1524 v3.id(),
1525 VectorExpression::Reference(ReferenceExpression::Constant(vec![]))
1526 )
1527 ],
1528 ..Default::default()
1529 },
1530 ..Default::default()
1531 },
1532 );
1533 let result = transition.add_effect(
1534 v4,
1535 VectorExpression::Reference(ReferenceExpression::Variable(v2.id())),
1536 );
1537 assert!(result.is_ok());
1538 assert_eq!(
1539 transition,
1540 Transition {
1541 effect: Effect {
1542 vector_effects: vec![
1543 (
1544 v1.id(),
1545 VectorExpression::Reference(ReferenceExpression::Constant(vec![1, 2]))
1546 ),
1547 (
1548 v2.id(),
1549 VectorExpression::Reference(ReferenceExpression::Variable(v1.id()))
1550 ),
1551 (
1552 v3.id(),
1553 VectorExpression::Reference(ReferenceExpression::Constant(vec![]))
1554 ),
1555 (
1556 v4.id(),
1557 VectorExpression::Reference(ReferenceExpression::Variable(v2.id()))
1558 ),
1559 ],
1560 ..Default::default()
1561 },
1562 ..Default::default()
1563 },
1564 );
1565 }
1566
1567 #[test]
1568 fn add_vector_effect_err() {
1569 let mut metadata = state::StateMetadata::default();
1570 let ob = metadata.add_object_type(String::from("something"), 10);
1571 assert!(ob.is_ok());
1572 let ob = ob.unwrap();
1573 let v = metadata.add_vector_variable(String::from("v"), ob);
1574 assert!(v.is_ok());
1575 let v = v.unwrap();
1576
1577 let mut transition = Transition::default();
1578 let result = transition.add_effect(
1579 v,
1580 VectorExpression::Reference(ReferenceExpression::Constant(vec![1, 2])),
1581 );
1582 assert!(result.is_ok());
1583 let result = transition.add_effect(
1584 v,
1585 VectorExpression::Reference(ReferenceExpression::Constant(vec![1, 2])),
1586 );
1587 assert!(result.is_err());
1588 }
1589
1590 #[test]
1591 fn add_element_effect_ok() {
1592 let mut metadata = state::StateMetadata::default();
1593 let ob = metadata.add_object_type(String::from("something"), 10);
1594 assert!(ob.is_ok());
1595 let ob = ob.unwrap();
1596 let v1 = metadata.add_element_variable(String::from("v1"), ob);
1597 assert!(v1.is_ok());
1598 let v1 = v1.unwrap();
1599 let v2 = metadata.add_element_variable(String::from("v2"), ob);
1600 assert!(v2.is_ok());
1601 let v2 = v2.unwrap();
1602
1603 let mut transition = Transition::default();
1604 let result = transition.add_effect(v1, 0);
1605 assert!(result.is_ok());
1606 assert_eq!(
1607 transition,
1608 Transition {
1609 effect: Effect {
1610 element_effects: vec![(v1.id(), ElementExpression::Constant(0))],
1611 ..Default::default()
1612 },
1613 ..Default::default()
1614 },
1615 );
1616 let result = transition.add_effect(v2, v1);
1617 assert!(result.is_ok());
1618 assert_eq!(
1619 transition,
1620 Transition {
1621 effect: Effect {
1622 element_effects: vec![
1623 (v1.id(), ElementExpression::Constant(0)),
1624 (v2.id(), ElementExpression::Variable(v1.id()))
1625 ],
1626 ..Default::default()
1627 },
1628 ..Default::default()
1629 },
1630 );
1631 }
1632
1633 #[test]
1634 fn add_element_effect_err() {
1635 let mut metadata = state::StateMetadata::default();
1636 let ob = metadata.add_object_type(String::from("something"), 10);
1637 assert!(ob.is_ok());
1638 let ob = ob.unwrap();
1639 let v = metadata.add_element_variable(String::from("v"), ob);
1640 assert!(v.is_ok());
1641 let v = v.unwrap();
1642
1643 let mut transition = Transition::default();
1644 let result = transition.add_effect(v, 0);
1645 assert!(result.is_ok());
1646 let result = transition.add_effect(v, 0);
1647 assert!(result.is_err());
1648 }
1649
1650 #[test]
1651 fn add_element_resource_effect_ok() {
1652 let mut metadata = state::StateMetadata::default();
1653 let ob = metadata.add_object_type(String::from("something"), 10);
1654 assert!(ob.is_ok());
1655 let ob = ob.unwrap();
1656 let v1 = metadata.add_element_resource_variable(String::from("v1"), ob, false);
1657 assert!(v1.is_ok());
1658 let v1 = v1.unwrap();
1659 let v2 = metadata.add_element_resource_variable(String::from("v2"), ob, true);
1660 assert!(v2.is_ok());
1661 let v2 = v2.unwrap();
1662
1663 let mut transition = Transition::default();
1664 let result = transition.add_effect(v1, 0);
1665 assert!(result.is_ok());
1666 assert_eq!(
1667 transition,
1668 Transition {
1669 effect: Effect {
1670 element_resource_effects: vec![(v1.id(), ElementExpression::Constant(0))],
1671 ..Default::default()
1672 },
1673 ..Default::default()
1674 },
1675 );
1676 let result = transition.add_effect(v2, v1);
1677 assert!(result.is_ok());
1678 assert_eq!(
1679 transition,
1680 Transition {
1681 effect: Effect {
1682 element_resource_effects: vec![
1683 (v1.id(), ElementExpression::Constant(0)),
1684 (v2.id(), ElementExpression::ResourceVariable(v1.id()))
1685 ],
1686 ..Default::default()
1687 },
1688 ..Default::default()
1689 },
1690 );
1691 }
1692
1693 #[test]
1694 fn add_element_resource_effect_err() {
1695 let mut metadata = state::StateMetadata::default();
1696 let ob = metadata.add_object_type(String::from("something"), 10);
1697 assert!(ob.is_ok());
1698 let ob = ob.unwrap();
1699 let v = metadata.add_element_resource_variable(String::from("v"), ob, false);
1700 assert!(v.is_ok());
1701 let v = v.unwrap();
1702
1703 let mut transition = Transition::default();
1704 let result = transition.add_effect(v, 0);
1705 assert!(result.is_ok());
1706 let result = transition.add_effect(v, 0);
1707 assert!(result.is_err());
1708 }
1709
1710 #[test]
1711 fn add_integer_effect_ok() {
1712 let mut metadata = state::StateMetadata::default();
1713 let v1 = metadata.add_integer_variable(String::from("v1"));
1714 assert!(v1.is_ok());
1715 let v1 = v1.unwrap();
1716 let v2 = metadata.add_integer_variable(String::from("v2"));
1717 assert!(v2.is_ok());
1718 let v2 = v2.unwrap();
1719
1720 let mut transition = Transition::default();
1721 let result = transition.add_effect(v1, 0);
1722 assert!(result.is_ok());
1723 assert_eq!(
1724 transition,
1725 Transition {
1726 effect: Effect {
1727 integer_effects: vec![(v1.id(), IntegerExpression::Constant(0))],
1728 ..Default::default()
1729 },
1730 ..Default::default()
1731 },
1732 );
1733 let result = transition.add_effect(v2, v1);
1734 assert!(result.is_ok());
1735 assert_eq!(
1736 transition,
1737 Transition {
1738 effect: Effect {
1739 integer_effects: vec![
1740 (v1.id(), IntegerExpression::Constant(0)),
1741 (v2.id(), IntegerExpression::Variable(v1.id()))
1742 ],
1743 ..Default::default()
1744 },
1745 ..Default::default()
1746 },
1747 );
1748 }
1749
1750 #[test]
1751 fn add_integer_effect_err() {
1752 let mut metadata = state::StateMetadata::default();
1753 let v = metadata.add_integer_variable(String::from("v"));
1754 assert!(v.is_ok());
1755 let v = v.unwrap();
1756
1757 let mut transition = Transition::default();
1758 let result = transition.add_effect(v, 0);
1759 assert!(result.is_ok());
1760 let result = transition.add_effect(v, 0);
1761 assert!(result.is_err());
1762 }
1763
1764 #[test]
1765 fn add_integer_resource_effect_ok() {
1766 let mut metadata = state::StateMetadata::default();
1767 let v1 = metadata.add_integer_resource_variable(String::from("v1"), false);
1768 assert!(v1.is_ok());
1769 let v1 = v1.unwrap();
1770 let v2 = metadata.add_integer_resource_variable(String::from("v2"), true);
1771 assert!(v2.is_ok());
1772 let v2 = v2.unwrap();
1773
1774 let mut transition = Transition::default();
1775 let result = transition.add_effect(v1, 0);
1776 assert!(result.is_ok());
1777 assert_eq!(
1778 transition,
1779 Transition {
1780 effect: Effect {
1781 integer_resource_effects: vec![(v1.id(), IntegerExpression::Constant(0))],
1782 ..Default::default()
1783 },
1784 ..Default::default()
1785 },
1786 );
1787 let result = transition.add_effect(v2, v1);
1788 assert!(result.is_ok());
1789 assert_eq!(
1790 transition,
1791 Transition {
1792 effect: Effect {
1793 integer_resource_effects: vec![
1794 (v1.id(), IntegerExpression::Constant(0)),
1795 (v2.id(), IntegerExpression::ResourceVariable(v1.id()))
1796 ],
1797 ..Default::default()
1798 },
1799 ..Default::default()
1800 },
1801 );
1802 }
1803
1804 #[test]
1805 fn add_integer_resource_effect_err() {
1806 let mut metadata = state::StateMetadata::default();
1807 let v = metadata.add_integer_resource_variable(String::from("v"), false);
1808 assert!(v.is_ok());
1809 let v = v.unwrap();
1810
1811 let mut transition = Transition::default();
1812 let result = transition.add_effect(v, 0);
1813 assert!(result.is_ok());
1814 let result = transition.add_effect(v, 0);
1815 assert!(result.is_err());
1816 }
1817
1818 #[test]
1819 fn add_continuous_effect_ok() {
1820 let mut metadata = state::StateMetadata::default();
1821 let v1 = metadata.add_continuous_variable(String::from("v1"));
1822 assert!(v1.is_ok());
1823 let v1 = v1.unwrap();
1824 let v2 = metadata.add_continuous_variable(String::from("v2"));
1825 assert!(v2.is_ok());
1826 let v2 = v2.unwrap();
1827
1828 let mut transition = Transition::default();
1829 let result = transition.add_effect(v1, 0.0);
1830 assert!(result.is_ok());
1831 assert_eq!(
1832 transition,
1833 Transition {
1834 effect: Effect {
1835 continuous_effects: vec![(v1.id(), ContinuousExpression::Constant(0.0))],
1836 ..Default::default()
1837 },
1838 ..Default::default()
1839 },
1840 );
1841 let result = transition.add_effect(v2, v1);
1842 assert!(result.is_ok());
1843 assert_eq!(
1844 transition,
1845 Transition {
1846 effect: Effect {
1847 continuous_effects: vec![
1848 (v1.id(), ContinuousExpression::Constant(0.0)),
1849 (v2.id(), ContinuousExpression::Variable(v1.id()))
1850 ],
1851 ..Default::default()
1852 },
1853 ..Default::default()
1854 },
1855 );
1856 }
1857
1858 #[test]
1859 fn add_continuous_effect_err() {
1860 let mut metadata = state::StateMetadata::default();
1861 let v = metadata.add_continuous_variable(String::from("v"));
1862 assert!(v.is_ok());
1863 let v = v.unwrap();
1864
1865 let mut transition = Transition::default();
1866 let result = transition.add_effect(v, 0.0);
1867 assert!(result.is_ok());
1868 let result = transition.add_effect(v, 0.0);
1869 assert!(result.is_err());
1870 }
1871
1872 #[test]
1873 fn add_continuous_resource_effect() {
1874 let mut metadata = state::StateMetadata::default();
1875 let v1 = metadata.add_continuous_resource_variable(String::from("v1"), false);
1876 assert!(v1.is_ok());
1877 let v1 = v1.unwrap();
1878 let v2 = metadata.add_continuous_resource_variable(String::from("v2"), true);
1879 assert!(v2.is_ok());
1880 let v2 = v2.unwrap();
1881
1882 let mut transition = Transition::default();
1883 let result = transition.add_effect(v1, 0.0);
1884 assert!(result.is_ok());
1885 assert_eq!(
1886 transition,
1887 Transition {
1888 effect: Effect {
1889 continuous_resource_effects: vec![(
1890 v1.id(),
1891 ContinuousExpression::Constant(0.0)
1892 )],
1893 ..Default::default()
1894 },
1895 ..Default::default()
1896 },
1897 );
1898 let result = transition.add_effect(v2, v1);
1899 assert!(result.is_ok());
1900 assert_eq!(
1901 transition,
1902 Transition {
1903 effect: Effect {
1904 continuous_resource_effects: vec![
1905 (v1.id(), ContinuousExpression::Constant(0.0)),
1906 (v2.id(), ContinuousExpression::ResourceVariable(v1.id()))
1907 ],
1908 ..Default::default()
1909 },
1910 ..Default::default()
1911 },
1912 );
1913 }
1914
1915 #[test]
1916 fn add_continuous_resource_effect_err() {
1917 let mut metadata = state::StateMetadata::default();
1918 let v = metadata.add_continuous_resource_variable(String::from("v"), false);
1919 assert!(v.is_ok());
1920 let v = v.unwrap();
1921
1922 let mut transition = Transition::default();
1923 let result = transition.add_effect(v, 0.0);
1924 assert!(result.is_ok());
1925 let result = transition.add_effect(v, 0.0);
1926 assert!(result.is_err());
1927 }
1928}