Helper matrix and array function to generate alternating bool arrays

This commit is contained in:
Martin Berg Alstad 2024-06-09 19:13:56 +02:00
parent f3fa0334c2
commit 4599b952fe
2 changed files with 96 additions and 7 deletions

View File

@ -1,7 +1,8 @@
use serde::{Deserialize, Serialize};
use crate::expressions::expression::Expression;
use crate::utils::array::Distinct;
use crate::matrix;
use crate::utils::array::{alternating_array, Distinct};
type TruthMatrix = Vec<Vec<bool>>;
@ -76,26 +77,60 @@ impl TruthTable {
}
fn generate_truth_matrix(expression: &Expression) -> TruthMatrix {
let count = expression.count_distinct();
if count == 0 {
return vec![];
}
let helper = Self::helper_matrix(count);
let truths = Self::generate_truth_table(&helper, expression);
todo!()
}
fn helper_matrix(number_of_atomics: usize) -> TruthMatrix {
todo!("Create a matrix with 2^number_of_atomics rows and number_of_atomics columns")
let len = 2usize.pow(number_of_atomics as u32);
let mut change_index = len / 2;
let mut rows: Vec<Vec<bool>> = matrix![false; 0 => number_of_atomics];
for row in &mut rows {
*row = alternating_array(len, change_index);
change_index /= 2;
}
rows
}
fn resolve_expression(expression: &Expression, row: &[bool]) -> bool {
// TODO store the expressions along with their values in a list tree structure
// For each node. Their left child is index * 2 + 1 and right child is index * 2 + 2
// Ex: 0 -> (1, 2), 1 -> (3, 4), 2 -> (5, 6)
fn generate_truth_table<'a>(helper: &TruthMatrix, expression: &'a Expression) -> Vec<Option<(&'a Expression, bool)>> {
todo!("Generate the truth table for the given expression")
}
fn resolve_expression(expression: &Expression, truths: &[Option<(&Expression, bool)>]) -> bool {
todo!("Resolve the expression with the given row of booleans")
}
fn find_expression(expression: Expression, expressions: &[Expression]) -> Option<usize> {
todo!("Find the expression in the truth table and return index")
}
}
#[cfg(test)]
mod tests {
use crate::matrix;
use super::*;
#[test]
fn test_helper_matrix_3() {
let helper = TruthTable::helper_matrix(3);
assert_eq!(helper, matrix![
true, true, true, true, false, false, false, false;
true, true, false, false, true, true, false, false;
true, false, true, false, true, false, true, false
]);
}
#[test]
fn test_helper_matrix_1() {
let helper = TruthTable::helper_matrix(1);
assert_eq!(helper, matrix![true, false]);
}
#[test]
fn test_atomic_expression() {
let expression = atomic!("A");

View File

@ -1,4 +1,6 @@
use std::cmp::max;
use std::ops::{Deref, DerefMut};
#[macro_export]
macro_rules! set {
() => { std::collections::HashSet::new() };
@ -13,6 +15,24 @@ macro_rules! set {
};
}
#[macro_export]
macro_rules! matrix {
($($($x:expr),*);*) => {
{
let mut temp_vec = vec![];
{} // Needed to avoid clippy warning
$(
temp_vec.push(vec![$($x),*]);
)*
temp_vec
}
};
($x:expr; $m:expr => $n:expr) => {
vec![vec![$x; $m]; $n]
};
}
pub trait Distinct {
fn distinct(&mut self);
}
@ -29,10 +49,44 @@ impl<T: PartialEq + Clone> Distinct for Vec<T> {
}
}
pub fn alternating_array(n: usize, mut skip: usize) -> Vec<bool> {
skip = max(skip, 1);
let mut array = vec![false; n];
let mut cell_value = false;
for (index, value) in array.iter_mut().enumerate() {
if index % skip == 0 {
cell_value = !cell_value;
}
*value = cell_value;
}
array
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_alternating_array() {
assert_eq!(alternating_array(4, 2), vec![true, true, false, false]);
assert_eq!(alternating_array(5, 1), vec![true, false, true, false, true]);
}
#[test]
fn test_alternating_array_0_skip() {
assert_eq!(alternating_array(4, 0), vec![true, false, true, false]);
}
#[test]
fn test_alternating_array_0_length() {
assert_eq!(alternating_array(0, 2), vec![] as Vec<bool>);
}
#[test]
fn test_alternating_array_skip_greater_than_length() {
assert_eq!(alternating_array(4, 5), vec![true, true, true, true]);
}
#[test]
fn test_distinct() {
let mut vec = vec![1, 2, 3, 1, 2, 3];