#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)]
pub struct VarId(pub u32);
impl VarId {
#[inline(always)]
pub fn idx(self) -> usize {
self.0 as usize
}
#[inline(always)]
pub fn to_dimacs(self) -> i32 {
self.0 as i32 + 1
}
#[inline(always)]
pub fn from_dimacs(n: i32) -> Self {
VarId::try_from_dimacs(n).unwrap_or_else(|| panic!("{n} names no DIMACS variable"))
}
#[inline(always)]
pub fn try_from_dimacs(n: i32) -> Option<Self> {
let named = n.checked_abs()?;
(named != 0).then(|| VarId(named as u32 - 1))
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct Literal {
pub var: VarId,
pub positive: bool,
}
impl Literal {
pub fn new(var: VarId, positive: bool) -> Self {
Literal { var, positive }
}
pub fn pos(var: VarId) -> Self {
Literal::new(var, true)
}
pub fn neg(var: VarId) -> Self {
Literal::new(var, false)
}
#[must_use]
pub fn negated(self) -> Self {
Literal {
var: self.var,
positive: !self.positive,
}
}
pub fn to_dimacs(self) -> i32 {
let var = self.var.to_dimacs();
if self.positive { var } else { -var }
}
}
impl From<i32> for Literal {
fn from(n: i32) -> Self {
let var = VarId::from_dimacs(n);
if n > 0 {
Literal::pos(var)
} else {
Literal::neg(var)
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) struct EquivFold {
pub eliminated: VarId,
pub survivor: Literal,
}