From 89c3456e76ae2d2f0172e1b2e466c6b256cf25f1 Mon Sep 17 00:00:00 2001 From: Samuel Pastva Date: Sun, 24 Dec 2023 13:28:29 +0100 Subject: [PATCH] Ignore trailing `None` values when comparing `BddPartialValuation` objects. --- src/_impl_bdd_partial_valuation.rs | 49 ++++++++++++++++++++++++++++++ src/lib.rs | 2 +- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/_impl_bdd_partial_valuation.rs b/src/_impl_bdd_partial_valuation.rs index eba3d14..ca2bef6 100644 --- a/src/_impl_bdd_partial_valuation.rs +++ b/src/_impl_bdd_partial_valuation.rs @@ -1,5 +1,7 @@ use crate::{BddPartialValuation, BddValuation, BddVariable}; +use std::cmp::min; use std::convert::TryFrom; +use std::hash::{Hash, Hasher}; use std::ops::{Index, IndexMut}; impl BddPartialValuation { @@ -136,9 +138,46 @@ impl IndexMut for BddPartialValuation { } } +impl PartialEq for BddPartialValuation { + fn eq(&self, other: &Self) -> bool { + let min_len = min(self.0.len(), other.0.len()); + for i in 0..min_len { + if self.0[i] != other.0[i] { + return false; + } + } + for j in min_len..self.0.len() { + if self.0[j].is_some() { + return false; + } + } + for j in min_len..other.0.len() { + if other.0[j].is_some() { + return false; + } + } + true + } +} + +impl Eq for BddPartialValuation {} + +impl Hash for BddPartialValuation { + fn hash(&self, state: &mut H) { + for (var, value) in self.0.iter().enumerate() { + if let Some(value) = value { + state.write_usize(var); + state.write_u8(u8::from(*value)) + } + } + } +} + #[cfg(test)] mod tests { use crate::{BddPartialValuation, BddValuation, BddVariable}; + use std::collections::hash_map::DefaultHasher; + use std::hash::{Hash, Hasher}; #[test] fn basic_partial_valuation_properties() { @@ -166,6 +205,16 @@ mod tests { assert_eq!(a, b); assert_eq!(a, BddPartialValuation::from_values(&a.to_values())); + + a.unset_value(v5); + let b = BddPartialValuation::from_values(&[(v1, false), (v2, false)]); + assert_eq!(a, b); + + let mut hasher_a = DefaultHasher::new(); + let mut hasher_b = DefaultHasher::new(); + a.hash(&mut hasher_a); + b.hash(&mut hasher_b); + assert_eq!(hasher_a.finish(), hasher_b.finish()); } #[test] diff --git a/src/lib.rs b/src/lib.rs index 3c4a714..99eb2ea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -127,7 +127,7 @@ pub struct BddValuation(Vec); /// A partial valuation can be used to quickly construct simple conjunctive/disjunctive clauses. /// It also exactly describes one path in a `Bdd` and hence can be used as an intermediate /// value when traversing the valuations of a `Bdd`. -#[derive(Clone, Debug, Eq, Hash, PartialEq)] +#[derive(Clone, Debug)] pub struct BddPartialValuation(Vec>); /// Exhaustively iterates over all valuations with a certain number of variables.