logic_form/
lib.rs

1#![feature(step_trait)]
2
3mod assign;
4mod cnf;
5mod dagcnf;
6pub mod dimacs;
7mod lbool;
8mod litordvec;
9mod litvec;
10mod litvvec;
11mod utils;
12
13pub use assign::*;
14pub use cnf::*;
15pub use dagcnf::*;
16pub use lbool::*;
17pub use litordvec::*;
18pub use litvec::*;
19pub use litvvec::*;
20pub use utils::*;
21
22use std::{
23    fmt::{self, Debug, Display},
24    hash::Hash,
25    iter::Step,
26    ops::{Add, AddAssign, Deref, Not},
27};
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
30pub struct Var(pub u32);
31
32impl Var {
33    pub const CONST: Var = Var(0);
34
35    #[inline]
36    pub fn new(x: usize) -> Self {
37        Self(x as _)
38    }
39
40    #[inline]
41    pub fn lit(&self) -> Lit {
42        Lit(self.0 << 1)
43    }
44
45    #[inline]
46    pub fn is_constant(&self) -> bool {
47        *self == Self::CONST
48    }
49}
50
51impl Add<Var> for Var {
52    type Output = Var;
53
54    #[inline]
55    fn add(self, rhs: Var) -> Self::Output {
56        Self(self.0 + rhs.0)
57    }
58}
59
60impl AddAssign<Var> for Var {
61    #[inline]
62    fn add_assign(&mut self, rhs: Var) {
63        self.0 += rhs.0;
64    }
65}
66
67impl From<Lit> for Var {
68    #[inline]
69    fn from(value: Lit) -> Self {
70        value.var()
71    }
72}
73
74impl Deref for Var {
75    type Target = u32;
76
77    #[inline]
78    fn deref(&self) -> &Self::Target {
79        &self.0
80    }
81}
82
83impl Display for Var {
84    #[inline]
85    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86        write!(f, "{}", self.0)
87    }
88}
89
90impl Step for Var {
91    #[inline]
92    fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
93        u32::steps_between(&start.0, &end.0)
94    }
95
96    #[inline]
97    fn forward_checked(start: Self, count: usize) -> Option<Self> {
98        u32::forward_checked(start.0, count).map(Self)
99    }
100
101    #[inline]
102    fn backward_checked(start: Self, count: usize) -> Option<Self> {
103        u32::backward_checked(start.0, count).map(Self)
104    }
105}
106
107macro_rules! impl_var_traits {
108    ($T:ty) => {
109        impl PartialEq<$T> for Var {
110            #[inline]
111            fn eq(&self, other: &$T) -> bool {
112                self.0.eq(&(*other as u32))
113            }
114        }
115
116        impl PartialOrd<$T> for Var {
117            #[inline]
118            fn partial_cmp(&self, other: &$T) -> Option<std::cmp::Ordering> {
119                self.0.partial_cmp(&(*other as u32))
120            }
121        }
122
123        impl From<Var> for $T {
124            #[inline]
125            fn from(value: Var) -> Self {
126                value.0 as $T
127            }
128        }
129
130        impl From<$T> for Var {
131            #[inline]
132            fn from(value: $T) -> Self {
133                Self(value as u32)
134            }
135        }
136
137        impl Add<$T> for Var {
138            type Output = Var;
139
140            #[inline]
141            fn add(self, rhs: $T) -> Self::Output {
142                Self(self.0 + rhs as u32)
143            }
144        }
145
146        impl AddAssign<$T> for Var {
147            #[inline]
148            fn add_assign(&mut self, rhs: $T) {
149                self.0 += rhs as u32;
150            }
151        }
152    };
153}
154
155impl_var_traits!(u32);
156impl_var_traits!(i32);
157impl_var_traits!(usize);
158impl_var_traits!(isize);
159
160#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
161pub struct Lit(u32);
162
163impl From<Var> for Lit {
164    #[inline]
165    fn from(value: Var) -> Self {
166        Self(value.0 << 1)
167    }
168}
169
170impl From<Lit> for u32 {
171    #[inline]
172    fn from(val: Lit) -> Self {
173        val.0
174    }
175}
176
177impl From<Lit> for i32 {
178    #[inline]
179    fn from(val: Lit) -> Self {
180        let mut v: i32 = val.var().into();
181        if !val.polarity() {
182            v = -v;
183        }
184        v
185    }
186}
187
188impl From<i32> for Lit {
189    #[inline]
190    fn from(value: i32) -> Self {
191        Self::new(Var(value.unsigned_abs()), value > 0)
192    }
193}
194
195impl Lit {
196    #[inline]
197    pub fn new(var: Var, polarity: bool) -> Self {
198        Lit(var.0 + var.0 + !polarity as u32)
199    }
200
201    #[inline]
202    pub fn var(&self) -> Var {
203        Var(self.0 >> 1)
204    }
205
206    #[inline]
207    pub fn polarity(&self) -> bool {
208        self.0 & 1 == 0
209    }
210
211    #[inline]
212    pub fn constant(polarity: bool) -> Self {
213        Self::new(Var::CONST, !polarity)
214    }
215
216    #[inline]
217    pub fn is_constant(&self, polarity: bool) -> bool {
218        *self == Self::constant(polarity)
219    }
220
221    #[inline]
222    pub fn not_if(&self, c: bool) -> Self {
223        if c { !*self } else { *self }
224    }
225
226    #[inline]
227    pub fn cube(&self) -> LitVec {
228        LitVec::from([*self])
229    }
230
231    #[inline]
232    pub fn map_var(&self, map: impl Fn(Var) -> Var) -> Self {
233        Self::new(map(self.var()), self.polarity())
234    }
235}
236
237impl Not for Lit {
238    type Output = Self;
239
240    #[inline]
241    fn not(mut self) -> Self::Output {
242        self.0 ^= 1;
243        self
244    }
245}
246
247impl Debug for Lit {
248    #[inline]
249    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
250        if self.polarity() {
251            write!(f, "{}", self.var())
252        } else {
253            write!(f, "-{}", self.var())
254        }
255    }
256}
257
258impl Display for Lit {
259    #[inline]
260    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
261        Debug::fmt(&self, f)
262    }
263}