use crate::internal_representation::{InteractionInternalRepresentation,InteractionOperatorRepresentation,CommonIoInteractionInterface};
pub trait FromInternalRepresentationToInteractionTerm<CioII : CommonIoInteractionInterface> : Sized + Clone {
fn get_empty_interaction() -> Self;
fn instantiate_interaction_under_operator(operator : &CioII::InteractionOperatorType, sub_ints : &mut Vec<Self>) -> Option<Self>;
fn transform_pattern_to_term(pattern : &CioII::InteractionLeafPatternType) -> Self;
fn fold_associative_operands_recursively(operator : &CioII::InteractionOperatorType, operands : &mut Vec<Self>) -> Self {
let ops_num = operands.len();
if ops_num == 2 {
let i2 = operands.pop().unwrap();
let i1 = operands.pop().unwrap();
Self::instantiate_interaction_under_operator(operator,&mut vec![i1,i2]).unwrap()
} else if ops_num == 1 {
operands.pop().unwrap().clone()
} else if ops_num == 0 {
Self::get_empty_interaction()
} else {
let i1 = operands.remove(0);
let i2 = Self::fold_associative_operands_recursively(operator,operands);
Self::instantiate_interaction_under_operator(operator,&mut vec![i1,i2]).unwrap()
}
}
fn from_io_repr(io_int_repr : &InteractionInternalRepresentation<CioII>) -> Self {
match io_int_repr {
InteractionInternalRepresentation::LeafPattern(leaf_pattern) => {
Self::transform_pattern_to_term(leaf_pattern)
},
InteractionInternalRepresentation::Operator(operator, sub_ints_reprs) => {
let mut sub_ints : Vec<Self> = sub_ints_reprs.iter().map(Self::from_io_repr).collect();
if operator.is_associative() {
Self::fold_associative_operands_recursively(operator, &mut sub_ints)
} else {
Self::instantiate_interaction_under_operator(operator,&mut sub_ints).unwrap()
}
}
}
}
}