1pub mod reader;
8pub mod writer;
9
10use std::fmt::Display;
11use std::num::NonZero;
12use std::ops::Add;
13use std::ops::Mul;
14use std::ops::Not;
15
16#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
17pub enum IntComparison {
18 GreaterEqual,
19 LessEqual,
20 Equal,
21 NotEqual,
22}
23
24impl Display for IntComparison {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 let s = match self {
27 IntComparison::GreaterEqual => ">=",
28 IntComparison::LessEqual => "<=",
29 IntComparison::Equal => "==",
30 IntComparison::NotEqual => "!=",
31 };
32
33 write!(f, "{s}")
34 }
35}
36
37pub trait IntValue: Clone + Display + Ord + Mul<Output = Self> + Add<Output = Self> {
41 fn increment(&self) -> Self;
42 fn decrement(&self) -> Self;
43
44 fn shift_left(&self) -> Self;
46
47 fn from_digit(byte: u8) -> Self;
49}
50
51pub trait SignedIntValue: IntValue {
52 fn negate(&self) -> Self;
54}
55
56macro_rules! impl_int_value {
57 ($type:ty) => {
58 impl IntValue for $type {
59 #[inline]
60 fn increment(&self) -> Self {
61 (*self) + 1
62 }
63
64 #[inline]
65 fn decrement(&self) -> Self {
66 (*self) - 1
67 }
68
69 #[inline]
70 fn shift_left(&self) -> Self {
71 (*self) * 10
72 }
73
74 #[allow(trivial_numeric_casts, reason = "inside macro")]
75 #[inline]
76 fn from_digit(byte: u8) -> Self {
77 assert!(byte.is_ascii_digit());
78 (byte - b'0') as Self
79 }
80 }
81 };
82}
83
84macro_rules! impl_signed_int_value {
85 ($type:ty) => {
86 impl SignedIntValue for $type {
87 #[inline]
88 fn negate(&self) -> Self {
89 (*self) * -1
90 }
91 }
92 };
93}
94
95impl_int_value!(u8);
96impl_int_value!(u16);
97impl_int_value!(u32);
98impl_int_value!(u64);
99impl_int_value!(i8);
100impl_int_value!(i16);
101impl_int_value!(i32);
102impl_int_value!(i64);
103impl_signed_int_value!(i8);
104impl_signed_int_value!(i16);
105impl_signed_int_value!(i32);
106impl_signed_int_value!(i64);
107
108#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
110pub struct IntAtomic<Identifier, Int> {
111 pub name: Identifier,
112 pub comparison: IntComparison,
113 pub value: Int,
114}
115
116impl<Identifier, Int> IntAtomic<Identifier, Int> {
117 pub fn new(name: Identifier, comparison: IntComparison, value: Int) -> Self {
119 IntAtomic {
120 name,
121 comparison,
122 value,
123 }
124 }
125}
126
127impl<Identifier: Display, Int: Display> Display for IntAtomic<Identifier, Int> {
128 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
129 let IntAtomic {
130 name,
131 comparison,
132 value,
133 } = self;
134
135 write!(f, "[{name} {comparison} {value}]")
136 }
137}
138
139impl<Identifier, Int> Not for IntAtomic<Identifier, Int>
140where
141 Int: IntValue,
142{
143 type Output = Self;
144
145 fn not(self) -> Self::Output {
146 IntAtomic {
147 name: self.name,
148 comparison: match self.comparison {
149 IntComparison::GreaterEqual => IntComparison::LessEqual,
150 IntComparison::LessEqual => IntComparison::GreaterEqual,
151 IntComparison::Equal => IntComparison::NotEqual,
152 IntComparison::NotEqual => IntComparison::Equal,
153 },
154 value: match self.comparison {
155 IntComparison::GreaterEqual => self.value.decrement(),
156 IntComparison::LessEqual => self.value.increment(),
157 IntComparison::Equal | IntComparison::NotEqual => self.value,
158 },
159 }
160 }
161}
162
163pub type ConstraintId = NonZero<u32>;
165
166#[derive(Clone, Debug, PartialEq, Eq, Hash)]
168pub struct Inference<Identifier, Int, Label> {
169 pub constraint_id: ConstraintId,
171 pub premises: Vec<IntAtomic<Identifier, Int>>,
173 pub consequent: Option<IntAtomic<Identifier, Int>>,
176 pub generated_by: Option<ConstraintId>,
178 pub label: Option<Label>,
180}
181
182#[derive(Clone, Debug, PartialEq, Eq, Hash)]
184pub struct Deduction<Identifier, Int> {
185 pub constraint_id: ConstraintId,
187 pub premises: Vec<IntAtomic<Identifier, Int>>,
189 pub sequence: Vec<ConstraintId>,
192}
193
194#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
197pub enum Conclusion<Identifier, Int> {
198 Unsat,
200 DualBound(IntAtomic<Identifier, Int>),
202}
203
204#[derive(Clone, Debug, PartialEq, Eq, Hash)]
206pub enum Step<Identifier, Int, Label> {
207 Inference(Inference<Identifier, Int, Label>),
208 Deduction(Deduction<Identifier, Int>),
209 Conclusion(Conclusion<Identifier, Int>),
210}