1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
use HashMap;
use Opcode;
use ;
use crateExpr;
extern crate lalrpop_util;
lalrpop_mod!;
/// The function evaluates the Boolean expression expr for each of the states in the states vector. The evaluation is performed by calling the `evaluate` function with the `state` and `expression` as arguments. The result of the evaluation is stored in a new vector. The `solve_truth_table` function returns this solution vector.
///
/// # Parameters
/// * `expr` - A boxed expression of the `Expr` type, which represents a logical expression to be evaluated.
/// * `states` - A vector of hash maps, where each hash map represents a different state of the Boolean variables used in the expression.
///
/// # Return Value
/// A vector of Boolean values that represent the evaluation result of the expression expr for each state in the states vector.
/// Generates all possible combinations of boolean values for a set of variables.
///
/// The function takes a vector of variable names `vars` and returns a vector of HashMaps.
/// Each key-value pair in the hash represents a variable and its corresponding boolean value.
///
/// # Arguments
///
/// * `vars` - A vector of variable names as strings.
///
/// # Examples
///
/// ```
/// use std::collections::HashMap;
/// use logical_solver::permutate;
///
/// let vars = vec!["A".to_string(), "B".to_string(), "C".to_string()];
/// let combs = permutate(vars);
///
/// for comb in combs {
/// println!("{:?}", comb);
/// }
/// ```
///
/// ## Output:
///
/// ```compile_fail
/// {"A": false, "B": false, "C": false}
/// {"A": false, "B": false, "C": true}
/// {"A": false, "B": true, "C": false}
/// {"A": false, "B": true, "C": true}
/// {"A": true, "B": false, "C": false}
/// {"A": true, "B": false, "C": true}
/// {"A": true, "B": true, "C": false}
/// {"A": true, "B": true, "C": true}
/// ```
/// Evaluates a boolean expression using a given state of variables.
///
/// # Arguments
///
/// * `expr` - A boxed expression of type `Expr` to be evaluated.
/// * `state` - A hashmap of type `HashMap<String, bool>` that maps variable names to their boolean values.
///
/// # Examples
///
/// ```
/// use std::collections::HashMap;
/// use logical_solver::{evaluate, ast::{Expr, Opcode}};
///
/// let mut state = HashMap::new();
/// state.insert(String::from("P"), true);
/// state.insert(String::from("Q"), false);
///
/// let expr = Box::new(Expr::Op(Box::new(Expr::Variable(String::from("P"))), Opcode::And, Box::new(Expr::Variable(String::from("Q")))));
///
/// assert_eq!(evaluate(expr, state), false);
/// ```
///
/// # Panics
///
/// * If an `Expr::Not` node is encountered while evaluating the expression. The `Expr::Not` node should never be part of an `Expr::Op` node in a boolean expression.
/// * If variable mentioned in the expression is not found in the state `HashMap`.
///
/// Parses a logical expression represented as a string and returns a boxed expression.
///
/// The `expression` parameter is a string slice representing a logical expression to be parsed.
///
/// # Example
///
/// ```
/// use logical_solver::{ast::Expr, parse_expression};
/// use lalrpop_util::{ParseError, lexer};
///
/// let result = parse_expression("A and B");
///
/// match result {
/// Ok(expr) => {
/// assert_eq!(format!("{}", expr), "(A ∧ B)");
/// },
/// Err(error) => {
/// panic!("Failed to parse expression: {:?}", error);
/// }
/// }
/// ```
///
/// # Supported operations
///
/// | Predicate | Usage |
/// | --------------------------------- | ------ |
/// | Conjunction(AND) ∧ | and |
/// | Disjunction(OR) ∨ | or |
/// | Negation(NOT) ¬ | not |
/// | Conditional(IF...THEN) ⇒/→ | => |
/// | Biconditional(IF AND ONLY IF) ⇔/↔ | <=> |
/// | Variables (for truth tables)\* | [A-Z]+ |
///
/// \*Variables can be one or more capital letters.
///
/// # Returns
///
/// Returns a `Result` object containing a boxed expression if parsing was successful, or a `ParseError` object
/// if there was an error during parsing.
///
/// The `Expr` type is defined in the `logic_parser` crate, and represents a logical expression that can be
/// evaluated.
///
/// The `ParseError` type is also defined in the `lalrpo_util` crate, and represents an error that occurred
/// during parsing. The error contains information about the location of the error in the input string, the token
/// that caused the error, and a message describing the error.