Skip to content

Commit d56ac6d

Browse files
committed
Implement solutions
1 parent a701d56 commit d56ac6d

File tree

3 files changed

+132
-2
lines changed

3 files changed

+132
-2
lines changed

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod error;
77
mod interpreter;
88
mod latex_writer;
99
mod parser;
10+
mod solve;
1011
mod span;
1112
mod tableau;
1213
mod token;
@@ -18,6 +19,7 @@ pub use error::*;
1819
pub use interpreter::*;
1920
pub use latex_writer::*;
2021
pub use parser::*;
22+
pub use solve::*;
2123
pub use span::*;
2224
pub use tableau::*;
2325
pub use token::*;

src/solve.rs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
use crate::{ExpressionKind, Tableau};
2+
3+
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
4+
pub struct Solution {
5+
variables: Vec<(String, bool)>,
6+
}
7+
8+
impl Solution {
9+
pub const fn new() -> Self {
10+
Self {
11+
variables: Vec::new(),
12+
}
13+
}
14+
15+
pub fn get(&self, name: impl AsRef<str>) -> Option<bool> {
16+
self.variables
17+
.iter()
18+
.find(|(n, _)| n == name.as_ref())
19+
.map(|(_, v)| *v)
20+
}
21+
22+
pub fn contains(&self, name: impl AsRef<str>, value: bool) -> bool {
23+
self.variables
24+
.iter()
25+
.any(|(n, v)| n == name.as_ref() && *v == value)
26+
}
27+
28+
pub fn push(&mut self, name: impl Into<String>, value: bool) {
29+
self.variables.push((name.into(), value));
30+
}
31+
32+
pub fn len(&self) -> usize {
33+
self.variables.len()
34+
}
35+
36+
pub fn iter(&self) -> impl Iterator<Item = (&str, bool)> {
37+
self.variables.iter().map(|(n, v)| (n.as_str(), *v))
38+
}
39+
}
40+
41+
#[derive(Clone, Debug, Default)]
42+
pub struct Solutions {
43+
solutions: Vec<Solution>,
44+
}
45+
46+
impl Solutions {
47+
pub const fn new() -> Self {
48+
Self {
49+
solutions: Vec::new(),
50+
}
51+
}
52+
53+
/// Pushes a variable on to all solutions.
54+
pub fn push(&mut self, name: impl Into<String>, value: bool) {
55+
let name = name.into();
56+
57+
self.solutions.retain_mut(|solution| {
58+
if let Some(v) = solution.get(&name) {
59+
v == value
60+
} else {
61+
solution.push(name.clone(), value);
62+
63+
true
64+
}
65+
});
66+
}
67+
68+
/// Removes all redundant solutions.
69+
pub fn clean(&mut self) {
70+
let mut redunant = Vec::new();
71+
72+
for (i, s_a) in self.solutions.iter().enumerate() {
73+
for (j, s_b) in self.solutions.iter().enumerate() {
74+
if s_a == s_b && !redunant.contains(&i) && i != j {
75+
redunant.push(j);
76+
}
77+
78+
if s_a.len() < s_b.len() {
79+
if s_a.iter().all(|(n, v)| s_b.contains(n, v)) {
80+
redunant.push(j);
81+
}
82+
}
83+
}
84+
}
85+
86+
let mut i = 0;
87+
self.solutions.retain(|_| {
88+
let retain = !redunant.contains(&i);
89+
i += 1;
90+
retain
91+
});
92+
}
93+
94+
/// Returns an [`Iterator`] over all solutions.
95+
pub fn iter(&self) -> impl Iterator<Item = &Solution> {
96+
self.solutions.iter()
97+
}
98+
}
99+
100+
impl From<&Tableau> for Solutions {
101+
fn from(tableau: &Tableau) -> Self {
102+
let mut this = Solutions::new();
103+
104+
if tableau.branches.is_empty() {
105+
this.solutions.push(Solution::new());
106+
}
107+
108+
for branch in tableau.branches.iter() {
109+
let mut solutions = Self::from(branch);
110+
111+
this.solutions.append(&mut solutions.solutions);
112+
}
113+
114+
for expectation in tableau.expectations.iter() {
115+
if let ExpressionKind::Atomic(atomic) = expectation.expr.kind.as_ref() {
116+
this.push(&atomic.ident, expectation.truth_value);
117+
}
118+
}
119+
120+
this
121+
}
122+
}

src/tableau.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
2-
AtomicExpression, BinaryExpression, BinaryOperator, Expression, ExpressionKind,
3-
ParenExpression, TruthValueExpression, UnaryExpression, UnaryOperator,
2+
AtomicExpression, BinaryExpression, BinaryOperator, Error, Expression, ExpressionKind,
3+
ParenExpression, Parser, TruthValueExpression, UnaryExpression, UnaryOperator,
44
};
55

66
#[derive(Clone, Debug)]
@@ -22,6 +22,12 @@ pub struct Tableau {
2222
}
2323

2424
impl Tableau {
25+
pub fn parse(source: &str, expect: bool) -> Result<Self, Error> {
26+
let builder = TableauBuilder::default();
27+
let parser = Parser::default();
28+
Ok(builder.build_expression(&parser.parse(source)?, expect))
29+
}
30+
2531
pub fn merge(&mut self, mut other: Self) {
2632
self.expectations.append(&mut other.expectations);
2733
self.branches.append(&mut other.branches);

0 commit comments

Comments
 (0)