use std::cmp::Ordering; use node_defs::{Container, NodeData, Sum, Product, Power, Primitive}; #[derive(Eq, Ord, PartialEq, PartialOrd)] enum PrimitiveType { Input, SystemVariable, Parameter, Sigmoid, } impl Primitive { fn simplify(&self) -> PrimitiveType { match self { &Primitive::Input(_) => PrimitiveType::Input, &Primitive::SystemVariable(_) => PrimitiveType::SystemVariable, &Primitive::Parameter(_) => PrimitiveType::Parameter, &Primitive::Sigmoid(_, _) => PrimitiveType::Sigmoid, } } } impl Ord for Sum { fn cmp(&self, other: &Sum) -> Ordering { let cmp_result = self.constant.cmp(&other.constant); match cmp_result { Ordering::Equal => { for (self_term, other_term) in self.terms .clone() .into_iter() .zip(other.terms.clone()) { let cmp_result = self_term.cmp(&other_term); match cmp_result { Ordering::Equal => (), _ => return cmp_result, } } let cmp_result = self.terms.len().cmp(&other.terms.len()); match cmp_result { Ordering::Equal => self.minus.cmp(&other.minus), _ => cmp_result, } } _ => cmp_result, } } } impl Ord for Product { fn cmp(&self, other: &Product) -> Ordering { let cmp_result = self.fuzzy_cmp(other); match cmp_result { Ordering::Equal => self.coefficient.cmp(&other.coefficient), _ => cmp_result, } } } impl Product { pub fn fuzzy_cmp(&self, other: &Product) -> Ordering { for (self_power, other_power) in self.powers .clone() .into_iter() .zip(other.powers.clone()) { let cmp_result = self_power.cmp(&other_power); match cmp_result { Ordering::Equal => (), _ => return cmp_result, } } self.powers.len().cmp(&other.powers.len()) } } impl Ord for Power { fn cmp(&self, other: &Power) -> Ordering { match self.fuzzy_cmp(&other) { Ordering::Equal => self.exponent.cmp(&other.exponent), cmp_result => cmp_result, } } } impl Power { pub fn fuzzy_cmp(&self, other: &Power) -> Ordering { self.primitive.cmp(&other.primitive) } } impl Ord for Primitive { fn cmp(&self, other: &Primitive) -> Ordering { match (self, other) { (&Primitive::Input(ref a), &Primitive::Input(ref b)) => a.cmp(b), (&Primitive::SystemVariable(ref a), &Primitive::SystemVariable(ref b)) => a.cmp(b), (&Primitive::Parameter(ref a), &Primitive::Parameter(ref b)) => a.cmp(b), (&Primitive::Sigmoid(minus_a, ref a), &Primitive::Sigmoid(minus_b, ref b)) => { let cmp_result = a.cmp(b); match cmp_result { Ordering::Equal => minus_a.cmp(&minus_b), _ => cmp_result, } } _ => self.simplify().cmp(&other.simplify()), } } }