boolean_circuit/
evaluator.rs

1use std::collections::HashMap;
2
3use crate::{Node, Operation};
4
5/// Returns the value computed in `node` given assignments to all required variables.
6pub fn evaluate(node: &Node, assignments: &HashMap<String, bool>) -> bool {
7    Evaluator {
8        cache: HashMap::new(),
9        assignments,
10    }
11    .evaluate(node)
12}
13
14struct Evaluator<'a> {
15    cache: HashMap<usize, bool>,
16    assignments: &'a HashMap<String, bool>,
17}
18
19impl Evaluator<'_> {
20    fn evaluate(&mut self, node: &Node) -> bool {
21        if let Some(&result) = self.cache.get(&node.id()) {
22            return result;
23        }
24        let result = match node.operation() {
25            Operation::Variable(name) => {
26                *self.assignments.get(name.as_str()).unwrap_or_else(|| {
27                    panic!("No assignment for variable '{name}'");
28                })
29            }
30            Operation::Constant(value) => *value,
31            Operation::Negation(inner) => !self.evaluate(inner),
32            Operation::Conjunction(left, right) => self.evaluate(left) && self.evaluate(right),
33            Operation::Disjunction(left, right) => self.evaluate(left) || self.evaluate(right),
34            Operation::Xor(left, right) => self.evaluate(left) ^ self.evaluate(right),
35        };
36        self.cache.insert(node.id(), result);
37        result
38    }
39}