1pub mod reader;
8pub mod writer;
9
10use std::fmt::Display;
11use std::num::NonZero;
12use std::ops::Not;
13use std::str::FromStr;
14
15#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
16pub enum IntComparison {
17 GreaterEqual,
18 LessEqual,
19 Equal,
20 NotEqual,
21}
22
23impl Display for IntComparison {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 let s = match self {
26 IntComparison::GreaterEqual => ">=",
27 IntComparison::LessEqual => "<=",
28 IntComparison::Equal => "==",
29 IntComparison::NotEqual => "!=",
30 };
31
32 write!(f, "{s}")
33 }
34}
35
36pub trait IntValue: Clone + Display + FromStr + Ord {
40 fn increment(&self) -> Self;
41 fn decrement(&self) -> Self;
42}
43
44macro_rules! impl_int_value {
45 ($type:ty) => {
46 impl IntValue for $type {
47 fn increment(&self) -> Self {
48 (*self) + 1
49 }
50
51 fn decrement(&self) -> Self {
52 (*self) - 1
53 }
54 }
55 };
56}
57
58impl_int_value!(i8);
59impl_int_value!(i16);
60impl_int_value!(i32);
61impl_int_value!(i64);
62
63#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
65pub struct IntAtomic<Identifier, Int> {
66 pub name: Identifier,
67 pub comparison: IntComparison,
68 pub value: Int,
69}
70
71impl<Identifier, Int> IntAtomic<Identifier, Int> {
72 pub fn new(name: Identifier, comparison: IntComparison, value: Int) -> Self {
74 IntAtomic {
75 name,
76 comparison,
77 value,
78 }
79 }
80}
81
82impl<Identifier: Display, Int: Display> Display for IntAtomic<Identifier, Int> {
83 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
84 let IntAtomic {
85 name,
86 comparison,
87 value,
88 } = self;
89
90 write!(f, "[{name} {comparison} {value}]")
91 }
92}
93
94impl<Identifier, Int> Not for IntAtomic<Identifier, Int>
95where
96 Int: IntValue,
97{
98 type Output = Self;
99
100 fn not(self) -> Self::Output {
101 IntAtomic {
102 name: self.name,
103 comparison: match self.comparison {
104 IntComparison::GreaterEqual => IntComparison::LessEqual,
105 IntComparison::LessEqual => IntComparison::GreaterEqual,
106 IntComparison::Equal => IntComparison::NotEqual,
107 IntComparison::NotEqual => IntComparison::Equal,
108 },
109 value: match self.comparison {
110 IntComparison::GreaterEqual => self.value.decrement(),
111 IntComparison::LessEqual => self.value.increment(),
112 IntComparison::Equal | IntComparison::NotEqual => self.value,
113 },
114 }
115 }
116}
117
118pub type ConstraintId = NonZero<u32>;
120
121#[derive(Clone, Debug, PartialEq, Eq, Hash)]
123pub struct Inference<Identifier, Int, Label> {
124 pub constraint_id: ConstraintId,
126 pub premises: Vec<IntAtomic<Identifier, Int>>,
128 pub consequent: Option<IntAtomic<Identifier, Int>>,
131 pub generated_by: Option<ConstraintId>,
133 pub label: Option<Label>,
135}
136
137#[derive(Clone, Debug, PartialEq, Eq, Hash)]
139pub struct Deduction<Identifier, Int> {
140 pub constraint_id: ConstraintId,
142 pub premises: Vec<IntAtomic<Identifier, Int>>,
144 pub sequence: Vec<ConstraintId>,
147}
148
149#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
152pub enum Conclusion<Identifier, Int> {
153 Unsat,
155 DualBound(IntAtomic<Identifier, Int>),
157}
158
159#[derive(Clone, Debug, PartialEq, Eq, Hash)]
161pub enum Step<Identifier, Int, Label> {
162 Inference(Inference<Identifier, Int, Label>),
163 Deduction(Deduction<Identifier, Int>),
164 Conclusion(Conclusion<Identifier, Int>),
165}