Option to sort truthTable
This commit is contained in:
parent
32d5089b44
commit
b9998ce7bf
@ -62,3 +62,23 @@ GET {{url}}/simplify/{{expression}}?simplify=false
|
||||
expression("A & B | C")
|
||||
%}
|
||||
GET {{url}}/simplify/table/{{expression}}
|
||||
|
||||
### GET with table sorted by true first
|
||||
< {%
|
||||
import {expression} from "./common";
|
||||
|
||||
expression("A & B | C")
|
||||
%}
|
||||
GET {{url}}/simplify/table/{{expression}}?sort=TRUE_FIRST
|
||||
|
||||
> {%
|
||||
client.test("Response body is sorted by true first", () => {
|
||||
const table = response.body.truthTable;
|
||||
const results = table.truthMatrix.map(arr => arr[arr.length - 1])
|
||||
const expected = results.slice() // Creates a copy of the array
|
||||
expected.sort((a, b) => b - a)
|
||||
for (let i = 0; i < results.length; i++) {
|
||||
client.assert(results[i] === expected[i], "Response body is not sorted by true first")
|
||||
}
|
||||
});
|
||||
%}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -40,13 +41,24 @@ pub struct TruthTableOptions {
|
||||
}
|
||||
|
||||
impl TruthTable {
|
||||
// TODO options
|
||||
// TODO hide option
|
||||
pub fn new(expression: &Expression, options: TruthTableOptions) -> Self {
|
||||
let header = Self::extract_header(expression);
|
||||
let truth_matrix = Self::generate_truth_matrix(expression, &header);
|
||||
let mut truth_matrix = Self::generate_truth_matrix(expression, &header);
|
||||
if !matches!(options.sort, Sort::Default) {
|
||||
Self::sort_matrix(&mut truth_matrix, options.sort);
|
||||
}
|
||||
Self { header, truth_matrix }
|
||||
}
|
||||
|
||||
fn sort_matrix(truth_matrix: &mut TruthMatrix, sort: Sort) {
|
||||
truth_matrix.sort_by(|row_a, row_b| match sort {
|
||||
Sort::TrueFirst => row_b.last().cmp(&row_a.last()),
|
||||
Sort::FalseFirst => row_a.last().cmp(&row_b.last()),
|
||||
Sort::Default => Ordering::Equal,
|
||||
})
|
||||
}
|
||||
|
||||
/// Extracts the header for the truth table from the expression
|
||||
/// Duplicate values are removed.
|
||||
/// - Arguments
|
||||
@ -62,16 +74,16 @@ impl TruthTable {
|
||||
/// ```
|
||||
fn extract_header(expression: &Expression) -> Vec<String> {
|
||||
match expression {
|
||||
not @ Expression::Not(expr) => {
|
||||
Expression::Not(expr) => {
|
||||
let mut header = Self::extract_header(expr);
|
||||
header.push(not.to_string());
|
||||
header.push(expression.to_string());
|
||||
header.distinct();
|
||||
header
|
||||
}
|
||||
binary @ Expression::Binary { left, right, .. } => {
|
||||
Expression::Binary { left, right, .. } => {
|
||||
let mut header = Self::extract_header(left);
|
||||
header.extend(Self::extract_header(right));
|
||||
header.push(binary.to_string());
|
||||
header.push(expression.to_string());
|
||||
header.distinct();
|
||||
header
|
||||
}
|
||||
@ -116,26 +128,26 @@ impl TruthTable {
|
||||
|
||||
fn _resolve_expression<'a>(expression: &'a Expression, booleans: &HashMap<String, bool>) -> HashMap<&'a Expression, bool> {
|
||||
match expression {
|
||||
not @ Expression::Not(expr) => {
|
||||
Expression::Not(expr) => {
|
||||
let mut map = Self::_resolve_expression(expr, booleans);
|
||||
if let Some(value) = map.get(expr.as_ref()) {
|
||||
map.insert(not, !value);
|
||||
map.insert(expression, !value);
|
||||
}
|
||||
map
|
||||
}
|
||||
binary @ Expression::Binary { left, right, operator } => {
|
||||
Expression::Binary { left, right, operator } => {
|
||||
let left_map = Self::_resolve_expression(left, booleans);
|
||||
let right_map = Self::_resolve_expression(right, booleans);
|
||||
let mut map = left_map;
|
||||
map.extend(right_map);
|
||||
if let (Some(left_value), Some(right_value)) = (map.get(left.as_ref()), map.get(right.as_ref())) {
|
||||
map.insert(binary, operator.eval(*left_value, *right_value));
|
||||
map.insert(expression, operator.eval(*left_value, *right_value));
|
||||
}
|
||||
map
|
||||
}
|
||||
atomic @ Expression::Atomic(value) => {
|
||||
Expression::Atomic(value) => {
|
||||
if let Some(value) = booleans.get(value) {
|
||||
map!(atomic => *value)
|
||||
map!(expression => *value)
|
||||
} else {
|
||||
unreachable!("Atomic value not found in booleans")
|
||||
}
|
||||
@ -189,6 +201,74 @@ mod tests {
|
||||
assert_eq!(truth_table.truth_matrix[7], vec![false, false, false, false, false, false]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sort_matrix_true_first() {
|
||||
let mut matrix = matrix![
|
||||
true, true, true;
|
||||
true, false, false;
|
||||
false, true, true;
|
||||
false, false, false
|
||||
];
|
||||
TruthTable::sort_matrix(&mut matrix, Sort::TrueFirst);
|
||||
assert_eq!(matrix, matrix![
|
||||
true, true, true;
|
||||
false, true, true;
|
||||
true, false, false;
|
||||
false, false, false
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sort_matrix_true_first_all_false_should_not_change() {
|
||||
let mut matrix = matrix![
|
||||
false, true, false;
|
||||
false, true, false;
|
||||
true, false, false;
|
||||
true, false, false
|
||||
];
|
||||
TruthTable::sort_matrix(&mut matrix, Sort::TrueFirst);
|
||||
assert_eq!(matrix, matrix![
|
||||
false, true, false;
|
||||
false, true, false;
|
||||
true, false, false;
|
||||
true, false, false
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sort_matrix_default_should_not_change() {
|
||||
let mut matrix = matrix![
|
||||
true, true, true;
|
||||
true, false, false;
|
||||
false, true, true;
|
||||
false, false, false
|
||||
];
|
||||
TruthTable::sort_matrix(&mut matrix, Sort::Default);
|
||||
assert_eq!(matrix, matrix![
|
||||
true, true, true;
|
||||
true, false, false;
|
||||
false, true, true;
|
||||
false, false, false
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sort_matrix_false_first() {
|
||||
let mut matrix = matrix![
|
||||
true, true, true;
|
||||
true, false, false;
|
||||
false, true, true;
|
||||
false, false, false
|
||||
];
|
||||
TruthTable::sort_matrix(&mut matrix, Sort::FalseFirst);
|
||||
assert_eq!(matrix, matrix![
|
||||
true, false, false;
|
||||
false, false, false;
|
||||
true, true, true;
|
||||
false, true, true
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truth_combinations_2() {
|
||||
let combinations = TruthTable::truth_combinations(2);
|
||||
|
Loading…
x
Reference in New Issue
Block a user