-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(bool fn trait): implemented iterator structs for Expression
This satisfies BooleanFunctions's types DomainIterator, RangeIterator, RelationIterator, SupportIterator.
- Loading branch information
1 parent
5053114
commit 68c68f7
Showing
6 changed files
with
431 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
use crate::expressions::Expression; | ||
use crate::traits::{BooleanPoint, GatherLiterals}; | ||
use crate::utils::{boolean_point_to_valuation, row_index_to_bool_point}; | ||
use std::collections::BTreeMap; | ||
use std::fmt::Debug; | ||
|
||
pub struct ExpressionDomainIterator { | ||
variable_count: usize, | ||
index: usize, | ||
} | ||
|
||
impl<T: Debug + Clone + Ord> From<&Expression<T>> for ExpressionDomainIterator { | ||
fn from(value: &Expression<T>) -> Self { | ||
Self { | ||
variable_count: value.gather_literals().len(), | ||
index: 0, | ||
} | ||
} | ||
} | ||
|
||
impl Iterator for ExpressionDomainIterator { | ||
type Item = Vec<bool>; | ||
|
||
fn next(&mut self) -> Option<Self::Item> { | ||
if self.index >= 2_usize.pow(self.variable_count as u32) { | ||
return None; | ||
} | ||
|
||
let result = row_index_to_bool_point(self.index, self.variable_count); | ||
self.index += 1; | ||
|
||
Some(result) | ||
} | ||
} | ||
|
||
impl<T: Debug + Clone + Eq + Ord> Expression<T> { | ||
pub fn boolean_point_to_valuation(&self, point: BooleanPoint) -> Option<BTreeMap<T, bool>> { | ||
boolean_point_to_valuation(self.gather_literals(), point) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::expressions::var; | ||
use crate::traits::BooleanFunction; | ||
use std::collections::BTreeMap; | ||
|
||
#[test] | ||
fn test_domain_ends() { | ||
let input = var("a") | var("b"); | ||
let mut iterator = input.domain(); | ||
|
||
assert!(iterator.next().is_some()); | ||
assert!(iterator.next().is_some()); | ||
assert!(iterator.next().is_some()); | ||
assert!(iterator.next().is_some()); | ||
assert!(iterator.next().is_none()); | ||
assert!(iterator.next().is_none()); | ||
} | ||
|
||
#[test] | ||
fn test_domain_ok() { | ||
let input = var("d") & var("b") | var("a"); | ||
|
||
let actual = input.domain().collect::<Vec<_>>(); | ||
|
||
let expected = vec![ | ||
vec![false, false, false], | ||
vec![false, false, true], | ||
vec![false, true, false], | ||
vec![false, true, true], | ||
vec![true, false, false], | ||
vec![true, false, true], | ||
vec![true, true, false], | ||
vec![true, true, true], | ||
]; | ||
|
||
assert_eq!(actual, expected); | ||
} | ||
|
||
#[test] | ||
fn test_point_to_valuation_ok() -> Result<(), String> { | ||
let input = var("d") & var("b") | var("a"); | ||
|
||
let actual = input | ||
.domain() | ||
.map(|point| input.boolean_point_to_valuation(point)) | ||
.collect::<Option<Vec<_>>>() | ||
.ok_or("Failed to translate".to_string())?; | ||
|
||
let expected = vec![ | ||
vec![false, false, false], | ||
vec![false, false, true], | ||
vec![false, true, false], | ||
vec![false, true, true], | ||
vec![true, false, false], | ||
vec![true, false, true], | ||
vec![true, true, false], | ||
vec![true, true, true], | ||
] | ||
.into_iter() | ||
.map(|point| { | ||
BTreeMap::from_iter(vec![ | ||
("a".to_string(), point[0]), | ||
("b".to_string(), point[1]), | ||
("d".to_string(), point[2]), | ||
]) | ||
}) | ||
.collect::<Vec<_>>(); | ||
|
||
assert_eq!(actual, expected); | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
use crate::expressions::Expression; | ||
use crate::traits::{Evaluate, GatherLiterals}; | ||
use crate::utils::{boolean_point_to_valuation, row_index_to_bool_point}; | ||
use std::collections::BTreeSet; | ||
use std::fmt::Debug; | ||
|
||
pub struct ExpressionImageIterator<T: Debug + Clone + Ord> { | ||
variables: BTreeSet<T>, | ||
expression: Expression<T>, | ||
index: usize, | ||
} | ||
|
||
impl<T: Debug + Clone + Ord> From<&Expression<T>> for ExpressionImageIterator<T> { | ||
fn from(value: &Expression<T>) -> Self { | ||
Self { | ||
variables: value.gather_literals(), | ||
expression: value.clone(), | ||
index: 0, | ||
} | ||
} | ||
} | ||
|
||
impl<T: Debug + Clone + Ord> Iterator for ExpressionImageIterator<T> { | ||
type Item = bool; | ||
|
||
fn next(&mut self) -> Option<Self::Item> { | ||
if self.index >= 2_usize.pow(self.variables.len() as u32) { | ||
return None; | ||
} | ||
|
||
let boolean_point = row_index_to_bool_point(self.index, self.variables.len()); | ||
let valuation = boolean_point_to_valuation(self.variables.clone(), boolean_point)?; | ||
let result = self.expression.evaluate(&valuation); | ||
|
||
self.index += 1; | ||
|
||
Some(result) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
use crate::expressions::var; | ||
use crate::traits::BooleanFunction; | ||
use std::collections::BTreeMap; | ||
|
||
#[test] | ||
fn test_image_ok() { | ||
let input = var("d") & var("b") | var("a"); | ||
|
||
let mut actual = input.image(); | ||
let expected = [ | ||
Some(input.evaluate(&BTreeMap::from([ | ||
("a".to_string(), false), | ||
("b".to_string(), false), | ||
("d".to_string(), false), | ||
]))), | ||
Some(input.evaluate(&BTreeMap::from([ | ||
("a".to_string(), false), | ||
("b".to_string(), false), | ||
("d".to_string(), true), | ||
]))), | ||
Some(input.evaluate(&BTreeMap::from([ | ||
("a".to_string(), false), | ||
("b".to_string(), true), | ||
("d".to_string(), false), | ||
]))), | ||
Some(input.evaluate(&BTreeMap::from([ | ||
("a".to_string(), false), | ||
("b".to_string(), true), | ||
("d".to_string(), true), | ||
]))), | ||
Some(input.evaluate(&BTreeMap::from([ | ||
("a".to_string(), true), | ||
("b".to_string(), false), | ||
("d".to_string(), false), | ||
]))), | ||
Some(input.evaluate(&BTreeMap::from([ | ||
("a".to_string(), true), | ||
("b".to_string(), false), | ||
("d".to_string(), true), | ||
]))), | ||
Some(input.evaluate(&BTreeMap::from([ | ||
("a".to_string(), true), | ||
("b".to_string(), true), | ||
("d".to_string(), false), | ||
]))), | ||
Some(input.evaluate(&BTreeMap::from([ | ||
("a".to_string(), true), | ||
("b".to_string(), true), | ||
("d".to_string(), true), | ||
]))), | ||
]; | ||
|
||
assert_eq!(actual.next(), expected[0]); | ||
assert_eq!(actual.next(), expected[1]); | ||
assert_eq!(actual.next(), expected[2]); | ||
assert_eq!(actual.next(), expected[3]); | ||
assert_eq!(actual.next(), expected[4]); | ||
assert_eq!(actual.next(), expected[5]); | ||
assert_eq!(actual.next(), expected[6]); | ||
assert_eq!(actual.next(), expected[7]); | ||
|
||
assert_eq!(actual.next(), None); | ||
assert_eq!(actual.next(), None); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
pub use domain::ExpressionDomainIterator; | ||
pub use image::ExpressionImageIterator; | ||
pub use relation::ExpressionRelationIterator; | ||
pub use support::ExpressionSupportIterator; | ||
|
||
mod domain; | ||
mod image; | ||
mod relation; | ||
mod support; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
use crate::expressions::Expression; | ||
use crate::traits::{BooleanPoint, Evaluate, GatherLiterals}; | ||
use crate::utils::{boolean_point_to_valuation, row_index_to_bool_point}; | ||
use std::collections::BTreeSet; | ||
use std::fmt::Debug; | ||
|
||
pub struct ExpressionRelationIterator<T: Debug + Clone + Ord> { | ||
variables: BTreeSet<T>, | ||
expression: Expression<T>, | ||
index: usize, | ||
} | ||
|
||
impl<T: Debug + Clone + Ord> From<&Expression<T>> for ExpressionRelationIterator<T> { | ||
fn from(value: &Expression<T>) -> Self { | ||
Self { | ||
variables: value.gather_literals(), | ||
expression: value.clone(), | ||
index: 0, | ||
} | ||
} | ||
} | ||
|
||
impl<T: Debug + Clone + Ord> Iterator for ExpressionRelationIterator<T> { | ||
type Item = (BooleanPoint, bool); | ||
|
||
fn next(&mut self) -> Option<Self::Item> { | ||
if self.index >= 2_usize.pow(self.variables.len() as u32) { | ||
return None; | ||
} | ||
|
||
let boolean_point = row_index_to_bool_point(self.index, self.variables.len()); | ||
let valuation = boolean_point_to_valuation(self.variables.clone(), boolean_point.clone())?; | ||
let result = self.expression.evaluate(&valuation); | ||
|
||
self.index += 1; | ||
|
||
Some((boolean_point, result)) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
use crate::expressions::var; | ||
use crate::traits::BooleanFunction; | ||
use std::collections::BTreeMap; | ||
|
||
#[test] | ||
fn test_relation_ok() { | ||
let input = var("d") & var("b") | var("a"); | ||
|
||
let mut actual = input.relation(); | ||
let expected = vec![ | ||
vec![false, false, false], | ||
vec![false, false, true], | ||
vec![false, true, false], | ||
vec![false, true, true], | ||
vec![true, false, false], | ||
vec![true, false, true], | ||
vec![true, true, false], | ||
vec![true, true, true], | ||
] | ||
.into_iter() | ||
.map(|point| { | ||
Some(( | ||
point.clone(), | ||
input.evaluate(&BTreeMap::from_iter(vec![ | ||
("a".to_string(), point[0]), | ||
("b".to_string(), point[1]), | ||
("d".to_string(), point[2]), | ||
])), | ||
)) | ||
}) | ||
.collect::<Vec<_>>(); | ||
|
||
assert_eq!(actual.next(), expected[0]); | ||
assert_eq!(actual.next(), expected[1]); | ||
assert_eq!(actual.next(), expected[2]); | ||
assert_eq!(actual.next(), expected[3]); | ||
assert_eq!(actual.next(), expected[4]); | ||
assert_eq!(actual.next(), expected[5]); | ||
assert_eq!(actual.next(), expected[6]); | ||
assert_eq!(actual.next(), expected[7]); | ||
|
||
assert_eq!(actual.next(), None); | ||
assert_eq!(actual.next(), None); | ||
} | ||
} |
Oops, something went wrong.