Compare commits
No commits in common. "b8c12047a5edb6cfc7292c0dae6095dd7a254915" and "8031391a61073e98d50e870511fef1175babe2f9" have entirely different histories.
b8c12047a5
...
8031391a61
42
src/ast.rs
42
src/ast.rs
|
@ -1,42 +0,0 @@
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum Token {
|
|
||||||
Negation,
|
|
||||||
Conjunction,
|
|
||||||
Disjunction,
|
|
||||||
ExclusiveDisjunction,
|
|
||||||
MaterialCondition,
|
|
||||||
LogicalEquivalence
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum Node<T> {
|
|
||||||
Leaf(T),
|
|
||||||
Unary {
|
|
||||||
operator: Token,
|
|
||||||
operand: Box<Node<T>>
|
|
||||||
},
|
|
||||||
Binary {
|
|
||||||
operator: Token,
|
|
||||||
lhs: Box<Node<T>>,
|
|
||||||
rhs: Box<Node<T>>,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_unary_node<T>(stack: &mut Vec<Node<T>>, token: Token) {
|
|
||||||
let operand = Box::new(stack.pop().unwrap());
|
|
||||||
stack.push(Node::Unary {
|
|
||||||
operator: token,
|
|
||||||
operand,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_binary_node<T>(stack: &mut Vec<Node<T>>, token: Token) {
|
|
||||||
let lhs = Box::new(stack.pop().unwrap());
|
|
||||||
let rhs = Box::new(stack.pop().unwrap());
|
|
||||||
stack.push(Node::Binary {
|
|
||||||
operator: token,
|
|
||||||
lhs,
|
|
||||||
rhs
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
#[test]
|
|
||||||
fn add_nodes() {
|
|
||||||
let stack = vec![Node::Leaf(true), Node::Leaf(false)];
|
|
||||||
let rhs = vec![Node::Binary {
|
|
||||||
operator: Token::Conjunction,
|
|
||||||
lhs: Box::new(Node::Leaf(true)),
|
|
||||||
rhs: Box::new(Node::Leaf(false))
|
|
||||||
}];
|
|
||||||
assert_eq!(add_binary_node(&mut stack, Token::Conjunction), rhs);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
mod tests;
|
|
||||||
|
|
||||||
use crate::ast::{ Token, Node, add_unary_node, add_binary_node };
|
|
||||||
|
|
||||||
fn parse_formula(formula: &str) -> Node<bool> {
|
|
||||||
let mut stack = vec![];
|
|
||||||
for c in formula.chars() {
|
|
||||||
match c {
|
|
||||||
'0' => stack.push(Node::Leaf(false)),
|
|
||||||
'1' => stack.push(Node::Leaf(true)),
|
|
||||||
'!' => add_unary_node(&mut stack, Token::Negation),
|
|
||||||
'&' => add_binary_node(&mut stack, Token::Conjunction),
|
|
||||||
'|' => add_binary_node(&mut stack, Token::Disjunction),
|
|
||||||
'^' => add_binary_node(&mut stack, Token::ExclusiveDisjunction),
|
|
||||||
'>' => add_binary_node(&mut stack, Token::MaterialCondition),
|
|
||||||
'=' => add_binary_node(&mut stack, Token::LogicalEquivalence),
|
|
||||||
_ => panic!("Error: {} is not a valid character", c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stack.pop().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compute(operator: Token, lhs: bool, rhs: bool) -> bool {
|
|
||||||
match operator {
|
|
||||||
Token::Negation => !lhs,
|
|
||||||
Token::Conjunction => lhs & rhs,
|
|
||||||
Token::Disjunction => lhs | rhs,
|
|
||||||
Token::ExclusiveDisjunction => lhs ^ rhs,
|
|
||||||
Token::MaterialCondition => !(lhs && !rhs),
|
|
||||||
Token::LogicalEquivalence => lhs == rhs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn evaluate(tree: Node<bool>) -> bool {
|
|
||||||
match tree {
|
|
||||||
Node::Unary { operator, operand } => compute(operator, evaluate(*operand), false),
|
|
||||||
Node::Binary { operator, lhs, rhs } => compute(operator, evaluate(*lhs), evaluate(*rhs)),
|
|
||||||
Node::Leaf(b) => b,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn eval_formula(formula: &str) -> bool {
|
|
||||||
let tree = parse_formula(formula);
|
|
||||||
evaluate(tree)
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use crate::boolean_evaluation::eval_formula;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn only_binary() {
|
|
||||||
assert_eq!(eval_formula("10&"), false);
|
|
||||||
assert_eq!(eval_formula("10|"), true);
|
|
||||||
assert_eq!(eval_formula("11>"), true);
|
|
||||||
assert_eq!(eval_formula("10="), false);
|
|
||||||
assert_eq!(eval_formula("1011||="), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn only_unary() {
|
|
||||||
assert_eq!(eval_formula("1!"), false);
|
|
||||||
assert_eq!(eval_formula("0!"), true);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn chained_unary() {
|
|
||||||
assert_eq!(eval_formula("1!!"), true);
|
|
||||||
assert_eq!(eval_formula("0!!"), false);
|
|
||||||
assert_eq!(eval_formula("0!!!"), true);
|
|
||||||
assert_eq!(eval_formula("1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"), true);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn binary_and_uneray() {
|
|
||||||
assert_eq!(eval_formula("10&!"), true);
|
|
||||||
assert_eq!(eval_formula("11&!"), false);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +1,6 @@
|
||||||
mod adder;
|
mod adder;
|
||||||
mod multiplier;
|
mod multiplier;
|
||||||
mod gray_code;
|
mod gray_code;
|
||||||
mod boolean_evaluation;
|
|
||||||
mod truth_table;
|
|
||||||
mod ast;
|
|
||||||
|
|
||||||
use gray_code::gray_code;
|
use gray_code::gray_code;
|
||||||
|
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
mod tests;
|
|
||||||
|
|
||||||
use std::collections::HashSet;
|
|
||||||
use crate::ast::{ Token, Node, add_unary_node, add_binary_node };
|
|
||||||
|
|
||||||
fn parse_formula(formula: &str) -> Node<bool> {
|
|
||||||
let mut stack = vec![];
|
|
||||||
for c in formula.chars() {
|
|
||||||
match c {
|
|
||||||
'0' => stack.push(Node::Leaf(false)),
|
|
||||||
'1' => stack.push(Node::Leaf(true)),
|
|
||||||
'!' => add_unary_node(&mut stack, Token::Negation),
|
|
||||||
'&' => add_binary_node(&mut stack, Token::Conjunction),
|
|
||||||
'|' => add_binary_node(&mut stack, Token::Disjunction),
|
|
||||||
'^' => add_binary_node(&mut stack, Token::ExclusiveDisjunction),
|
|
||||||
'>' => add_binary_node(&mut stack, Token::MaterialCondition),
|
|
||||||
'=' => add_binary_node(&mut stack, Token::LogicalEquivalence),
|
|
||||||
_ => panic!("Error: {} is not a valid character", c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stack.pop().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compute(operator: Token, lhs: bool, rhs: bool) -> bool {
|
|
||||||
match operator {
|
|
||||||
Token::Negation => !lhs,
|
|
||||||
Token::Conjunction => lhs & rhs,
|
|
||||||
Token::Disjunction => lhs | rhs,
|
|
||||||
Token::ExclusiveDisjunction => lhs ^ rhs,
|
|
||||||
Token::MaterialCondition => !(lhs && !rhs),
|
|
||||||
Token::LogicalEquivalence => lhs == rhs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn evaluate(tree: Node<bool>) -> bool {
|
|
||||||
match tree {
|
|
||||||
Node::Unary { operator, operand } => compute(operator, evaluate(*operand), false),
|
|
||||||
Node::Binary { operator, lhs, rhs } => compute(operator, evaluate(*lhs), evaluate(*rhs)),
|
|
||||||
Node::Leaf(b) => b,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_hashset(formula: &str) -> HashSet<char> {
|
|
||||||
let mut hashset = HashSet::new();
|
|
||||||
|
|
||||||
for c in formula.chars() {
|
|
||||||
match c {
|
|
||||||
'A'..='Z' => { hashset.insert(c); },
|
|
||||||
'!' | '&' | '|' | '^' | '>' | '=' => (),
|
|
||||||
_ => panic!("Error: {} is not a valid character", c),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hashset
|
|
||||||
}
|
|
||||||
|
|
||||||
fn eval_formula(formula: &str) -> bool {
|
|
||||||
let tree = parse_formula(formula);
|
|
||||||
evaluate(tree)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn recursive_fn(formula: &str, mut vec: Vec<char>, format: String) {
|
|
||||||
let char = vec.pop();
|
|
||||||
if let Some(c) = char {
|
|
||||||
recursive_fn(formula.replace(c, "0").as_str(), vec.clone(), format!("{format} 0 |"));
|
|
||||||
recursive_fn(formula.replace(c, "1").as_str(), vec.clone(), format!("{format} 1 |"));
|
|
||||||
} else {
|
|
||||||
match eval_formula(formula) {
|
|
||||||
false => println!("{format} 0 |"),
|
|
||||||
true => println!("{format} 1 |"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_truth_table(formula: &str) {
|
|
||||||
let set: HashSet<char> = get_hashset(formula);
|
|
||||||
let mut vec: Vec<char> = set.iter().cloned().collect();
|
|
||||||
vec.sort();
|
|
||||||
let mut format = String::from("|");
|
|
||||||
let mut separator = String::from("|");
|
|
||||||
for i in vec.clone() {
|
|
||||||
format = format!("{format} {i} |");
|
|
||||||
separator = format!("{separator}---|");
|
|
||||||
}
|
|
||||||
|
|
||||||
format = format!("{format} = |");
|
|
||||||
|
|
||||||
separator = format!("{separator}---|");
|
|
||||||
println!("{format}");
|
|
||||||
println!("{separator}");
|
|
||||||
recursive_fn(formula, vec, String::from("|"));
|
|
||||||
// call eval formula a lot
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use crate::truth_table::print_truth_table;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn only_binary() {
|
|
||||||
print_truth_table("AB&");
|
|
||||||
print_truth_table("AB|");
|
|
||||||
print_truth_table("AB>");
|
|
||||||
print_truth_table("AB=");
|
|
||||||
print_truth_table("ABCD||=");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn only_unary() {
|
|
||||||
print_truth_table("A!");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn binary_and_uneray() {
|
|
||||||
print_truth_table("AB&!");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn big() {
|
|
||||||
print_truth_table("AB&CD&&EF&GH&&&IJ&KL&&MN&OP&&&QR&ST&&UV&WX&&&YZ&&&")
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue