Fixed hide intermediate steps, such that header and body is of same length

This commit is contained in:
Martin Berg Alstad 2024-06-17 23:04:47 +02:00
parent bcf8b87f5f
commit 6df5152061
3 changed files with 64 additions and 8 deletions

View File

@ -141,3 +141,23 @@ GET {{url}}/table/A
client.assert(response.body.truthTable, "Response body does not contain the truth table")
});
%}
### GET table and hide intermediate values
< {%
import {expression} from "./common";
expression("A & B | C")
%}
GET {{url}}/table/{{expression}}?hideIntermediateSteps=true
> {%
client.test("Response body does not contain intermediate steps", () => {
const header = response.body.truthTable.header;
const matrix = response.body.truthTable.truthMatrix;
client.assert(header.length === 4, "Response body contains intermediate steps")
for (let i = 0; i < matrix.length; i++) {
client.assert(matrix[i].length === 4, "Response body contains intermediate steps")
}
});
%}

View File

@ -37,11 +37,14 @@ pub enum Sort {
impl TruthTable {
pub fn new(expression: &Expression, options: TruthTableOptions) -> Self {
let header = Self::extract_header(expression);
let mut header = Self::extract_header(expression);
let mut truth_matrix = Self::generate_truth_matrix(expression, &header, options.hide, options.hide_intermediate_steps);
if !matches!(options.sort, Sort::Default) {
Self::sort_matrix(&mut truth_matrix, options.sort);
}
if options.hide_intermediate_steps {
header = Self::remove_non_atomic_from_header(&header);
}
Self { header, truth_matrix }
}
@ -53,6 +56,23 @@ impl TruthTable {
})
}
fn remove_non_atomic_from_header(header: &[String]) -> Vec<String> {
header.iter()
.enumerate()
.filter_map(|(index, s)| {
if !Self::contains_operator(s) || index == header.len() - 1 {
Some(s.clone())
} else {
None
}
})
.collect()
}
fn contains_operator(slice: &str) -> bool {
slice.contains('⋀') || slice.contains('') || slice.contains('➔')
}
/// Extracts the header for the truth table from the expression
/// Duplicate values are removed.
/// - Arguments
@ -116,9 +136,13 @@ impl TruthTable {
}
fn resolve_expression(expression: &Expression, booleans: &HashMap<String, bool>, header: &[String], hide_intermediate: bool) -> Vec<bool> {
let Some(last_expression) = header.last() else {
return vec![];
};
let mut expression_map = Self::_resolve_expression(expression, booleans);
if hide_intermediate {
expression_map = Self::remove_intermediate_steps(expression_map);
expression_map = Self::remove_intermediate_steps(expression_map, last_expression);
}
let string_map = expression_map.iter()
.map(|(key, value)| (key.to_string(), *value))
@ -129,11 +153,10 @@ impl TruthTable {
.collect()
}
fn remove_intermediate_steps(expression_map: HashMap<&Expression, bool>) -> HashMap<&Expression, bool> {
fn remove_intermediate_steps<'a>(expression_map: HashMap<&'a Expression, bool>, top_level_expression: &'a str) -> HashMap<&'a Expression, bool> {
expression_map.iter()
.enumerate()
.filter_map(|(index, (key, value))| {
if key.is_atomic() || index == expression_map.len() - 1 {
.filter_map(|(key, value)| {
if key.is_atomic() || key.to_string() == top_level_expression {
Some((*key, *value))
} else {
None
@ -217,6 +240,19 @@ mod tests {
assert_eq!(truth_table.truth_matrix[7], vec![false, false, false, false, false, false]);
}
#[test]
fn test_new_truth_table_and_hide_intermediate_steps() {
let expression = and(atomic("A"), or(atomic("B"), atomic("C")));
let truth_table = TruthTable::new(&expression, TruthTableOptions {
hide_intermediate_steps: true,
..Default::default()
});
assert_eq!(truth_table.header, vec!["A", "B", "C", "A ⋀ (B C)"]);
for (index, row) in truth_table.truth_matrix.iter().enumerate() {
assert_eq!(row.len(), 4, "Row at {index}: {:?}", row);
}
}
#[test]
fn test_sort_matrix_true_first() {
let mut matrix = matrix![

View File

@ -20,8 +20,8 @@ pub struct TruthTableOptions {
pub sort: Sort,
#[serde(default)]
pub hide: Hide,
#[serde(default)]
pub hide_intermediate_steps: bool, // TODO: Implement hide intermediate steps
#[serde(default, deserialize_with = "deserialize_bool")]
pub hide_intermediate_steps: bool,
}
#[derive(Deserialize)]